From db74a61a34abe345846d0ac59f290cce4f8e4175 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 16 Feb 2023 14:20:09 +0800 Subject: [PATCH 001/144] Prepare 3.1.7 release --- dubbo-dependencies-bom/pom.xml | 2 +- .../dubbo-dependencies-zookeeper-curator5/pom.xml | 2 +- dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 3fea871453..43859302af 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -182,7 +182,7 @@ 2.0 1.1.0 1.21 - 3.1.7-SNAPSHOT + 3.1.7 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml index 5931b27cec..3ad5c481ed 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.7-SNAPSHOT + 3.1.7 1.1.0 5.1.0 3.7.0 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml index a82cf055a4..a57db72ed3 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.7-SNAPSHOT + 3.1.7 1.1.0 4.2.0 3.4.14 diff --git a/pom.xml b/pom.xml index 38de091be0..2316f1a6f2 100644 --- a/pom.xml +++ b/pom.xml @@ -130,7 +130,7 @@ true true true - 3.1.7-SNAPSHOT + 3.1.7 From 3995bfc98a8b3d19e7adf98e3529b8b4fa98f3d0 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 16 Feb 2023 14:40:14 +0800 Subject: [PATCH 002/144] Add hessian allow --- dubbo-common/src/main/resources/security/serialize.allowlist | 1 + 1 file changed, 1 insertion(+) diff --git a/dubbo-common/src/main/resources/security/serialize.allowlist b/dubbo-common/src/main/resources/security/serialize.allowlist index bca85c1ca0..f05fb8c5ce 100644 --- a/dubbo-common/src/main/resources/security/serialize.allowlist +++ b/dubbo-common/src/main/resources/security/serialize.allowlist @@ -123,3 +123,4 @@ java.util.TreeSet java.util.UUID java.util.WeakHashMap org.apache.dubbo +com.alibaba.com.caucho.hessian.io.java8 From 5c0002c3174ea9e04c710f8386180a720ed2b72e Mon Sep 17 00:00:00 2001 From: Andy Cheung Date: Mon, 20 Feb 2023 15:43:51 +0800 Subject: [PATCH 003/144] Backport of remove apache-rat-plugin. (#11523) (#11592) --- .github/workflows/build-and-test-pr.yml | 11 +-- .../build-and-test-scheduled-3.0.yml | 11 +-- .../build-and-test-scheduled-3.1.yml | 11 +-- .../build-and-test-scheduled-3.2.yml | 11 +-- .github/workflows/release-test.yml | 11 +-- dubbo-build-tools/pom.xml | 51 ------------ pom.xml | 82 ------------------- 7 files changed, 5 insertions(+), 183 deletions(-) diff --git a/.github/workflows/build-and-test-pr.yml b/.github/workflows/build-and-test-pr.yml index cf3f0ab106..34da3805a8 100644 --- a/.github/workflows/build-and-test-pr.yml +++ b/.github/workflows/build-and-test-pr.yml @@ -70,16 +70,7 @@ jobs: - name: "Build Dubbo with Maven" run: | cd ./dubbo - ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,rat,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - - name: "Pack rat file if failure" - if: failure() - run: 7z a ${{ github.workspace }}/rat.zip *rat.txt -r - - name: "Upload rat file if failure" - if: failure() - uses: actions/upload-artifact@v3 - with: - name: "rat-file" - path: ${{ github.workspace }}/rat.zip + ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - name: "Pack checkstyle file if failure" if: failure() run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r diff --git a/.github/workflows/build-and-test-scheduled-3.0.yml b/.github/workflows/build-and-test-scheduled-3.0.yml index b8dedaeb59..2659f79801 100644 --- a/.github/workflows/build-and-test-scheduled-3.0.yml +++ b/.github/workflows/build-and-test-scheduled-3.0.yml @@ -50,16 +50,7 @@ jobs: - name: "Build Dubbo with Maven" run: | cd ./dubbo - ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,rat,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - - name: "Pack rat file if failure" - if: failure() - run: 7z a ${{ github.workspace }}/rat.zip *rat.txt -r - - name: "Upload rat file if failure" - if: failure() - uses: actions/upload-artifact@v3 - with: - name: "rat-file" - path: ${{ github.workspace }}/rat.zip + ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - name: "Pack checkstyle file if failure" if: failure() run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r diff --git a/.github/workflows/build-and-test-scheduled-3.1.yml b/.github/workflows/build-and-test-scheduled-3.1.yml index bf8dd1ace6..be33c7faf6 100644 --- a/.github/workflows/build-and-test-scheduled-3.1.yml +++ b/.github/workflows/build-and-test-scheduled-3.1.yml @@ -60,16 +60,7 @@ jobs: - name: "Build Dubbo with Maven" run: | cd ./dubbo - ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,rat,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - - name: "Pack rat file if failure" - if: failure() - run: 7z a ${{ github.workspace }}/rat.zip *rat.txt -r - - name: "Upload rat file if failure" - if: failure() - uses: actions/upload-artifact@v3 - with: - name: "rat-file" - path: ${{ github.workspace }}/rat.zip + ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - name: "Pack checkstyle file if failure" if: failure() run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r diff --git a/.github/workflows/build-and-test-scheduled-3.2.yml b/.github/workflows/build-and-test-scheduled-3.2.yml index a65db836d2..b133e06502 100644 --- a/.github/workflows/build-and-test-scheduled-3.2.yml +++ b/.github/workflows/build-and-test-scheduled-3.2.yml @@ -60,16 +60,7 @@ jobs: - name: "Build Dubbo with Maven" run: | cd ./dubbo - ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,rat,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - - name: "Pack rat file if failure" - if: failure() - run: 7z a ${{ github.workspace }}/rat.zip *rat.txt -r - - name: "Upload rat file if failure" - if: failure() - uses: actions/upload-artifact@v3 - with: - name: "rat-file" - path: ${{ github.workspace }}/rat.zip + ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - name: "Pack checkstyle file if failure" if: failure() run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r diff --git a/.github/workflows/release-test.yml b/.github/workflows/release-test.yml index f8492e8517..3986baadbc 100644 --- a/.github/workflows/release-test.yml +++ b/.github/workflows/release-test.yml @@ -58,16 +58,7 @@ jobs: - name: "Build Dubbo with Maven" run: | cd ./dubbo - ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,rat,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - - name: "Pack rat file if failure" - if: failure() - run: 7z a ${{ github.workspace }}/rat.zip *rat.txt -r - - name: "Upload rat file if failure" - if: failure() - uses: actions/upload-artifact@v2 - with: - name: "rat-file" - path: ${{ github.workspace }}/rat.zip + ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean source:jar install -Pjacoco,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper - name: "Pack checkstyle file if failure" if: failure() run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r diff --git a/dubbo-build-tools/pom.xml b/dubbo-build-tools/pom.xml index a1a0c60df1..28bae806b1 100644 --- a/dubbo-build-tools/pom.xml +++ b/dubbo-build-tools/pom.xml @@ -27,55 +27,4 @@ true - - - - org.apache.rat - apache-rat-plugin - 0.13 - - - verify.rat - verify - - check - - - - - - **/*.versionsBackup - **/.idea/ - **/*.iml - **/*.txt - **/*.load - **/*.flex - **/*.fc - **/*.javascript - **/*.properties - **/*.thrift - **/*.sh - **/*.bat - **/*.md - .git/ - .gitignore - .repository/ - **/.settings/* - **/.classpath - **/.project - **/target/** - **/generated/** - **/*.log - CONTRIBUTING.md - README.md - **/codestyle/* - **/resources/META-INF/** - .github/** - compiler/** - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 38de091be0..c414486d82 100644 --- a/pom.xml +++ b/pom.xml @@ -124,7 +124,6 @@ 0.8.8 1.3.0 3.0.0-M3 - 0.13 true true @@ -273,13 +272,6 @@ false - - - rat - - false - - checkstyle @@ -655,80 +647,6 @@ ${file_encoding} - - org.apache.rat - apache-rat-plugin - ${apache-rat-plugin.version} - - - rat-validate - validate - - check - - - - - - **/*.versionsBackup - **/.idea/ - **/*.iml - **/*.txt - **/*.load - **/*.flex - **/*.fc - **/*.properties - **/*.sh - **/*.bat - **/*.md - .git/ - .tmp/ - .gitignore - - .repository/ - **/.settings/* - **/.classpath - **/.project - **/target/** - **/*.log - CODE_OF_CONDUCT.md - .codecov.yml - .travis.yml - PULL_REQUEST_TEMPLATE.md - CONTRIBUTING.md - README.md - Jenkinsfile - **/codestyle/* - **/resources/META-INF/** - - **/org/apache/dubbo/common/threadpool/serial/SerializingExecutor.java - - **/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java - **/org/apache/dubbo/common/threadlocal/InternalThreadLocalMap.java - **/org/apache/dubbo/common/timer/TimerTask.java - **/org/apache/dubbo/common/timer/Timer.java - **/org/apache/dubbo/common/timer/Timeout.java - **/org/apache/dubbo/common/timer/HashedWheelTimer.java - - **/org/apache/dubbo/common/utils/CIDRUtils.java - - **/org/apache/dubbo/common/serialize/protobuf/support/wrapper/MapValue.java - - - **/org/apache/dubbo/common/serialize/protobuf/support/wrapper/ThrowablePB.java - - - **/org/apache/dubbo/common/utils/Utf8Utils.java - - .github/** - compiler/** - **/generated/** - - **/mockito-extensions/* - **/*.dubbo.cache - - - org.apache.maven.plugins maven-release-plugin From a8bbc234d94f068bc696c65ee0beb668d57ccbce Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Mon, 20 Feb 2023 17:28:08 +0800 Subject: [PATCH 004/144] Bump version to 3.1.8-SNAPSHOT --- dubbo-dependencies-bom/pom.xml | 2 +- .../dubbo-dependencies-zookeeper-curator5/pom.xml | 2 +- dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 43859302af..a20edf2fed 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -182,7 +182,7 @@ 2.0 1.1.0 1.21 - 3.1.7 + 3.1.8-SNAPSHOT diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml index 3ad5c481ed..b31835d2d0 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.7 + 3.1.8-SNAPSHOT 1.1.0 5.1.0 3.7.0 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml index a57db72ed3..964b000b5c 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.7 + 3.1.8-SNAPSHOT 1.1.0 4.2.0 3.4.14 diff --git a/pom.xml b/pom.xml index 0fb0a34c97..aafb747c2d 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ true true true - 3.1.7 + 3.1.8-SNAPSHOT From 10e7162268597fbee8e9e42db996969f10346cfa Mon Sep 17 00:00:00 2001 From: PlutoOfCharon <125440332+PlutoOfCharon@users.noreply.github.com> Date: Tue, 21 Feb 2023 10:27:46 +0800 Subject: [PATCH 005/144] Update DubboReference.java (#11621) --- .../java/org/apache/dubbo/config/annotation/DubboReference.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java index bcf4869b78..05b8d83cde 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java @@ -163,7 +163,7 @@ public @interface DubboReference { String proxy() default ""; /** - * Service stub name, use interface name + Local if not set + * Service stub name, use interface name + Stub if not set */ String stub() default ""; From 02a59e2f4074889500ea29130b82aa80ced44d5e Mon Sep 17 00:00:00 2001 From: suncairong163 <105478245+suncairong163@users.noreply.github.com> Date: Wed, 22 Feb 2023 14:02:16 +0800 Subject: [PATCH 006/144] 3.2 consumer proxy invocation handler (#11108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add dubbo mvc feign client to support mvc remote call * add dubbo mvc dispatcher servlet * add dubbo mvc dispatcher servlet * add MvcDispatcherServlet unit test * add dubbo mvc feign client to support mvc remote call * add dubbo mvc dispatcher servlet * add Dubbo mvc Provider RPCInvocation create * mvc remove unused code * remove mvc unused test code * remove unused code * BodyProviderParamParser param type modify * modify pom dependency version * add dubbo-metadata-api dependency * 新增依赖Jakarta支持 tomcat10 * ApplicationModel load ParamParser * ParamParser header & param map convert * ParamParser header & param map convert * 1 增加mvc协议 2 删除多余的resource包 * 1 增加mvc协议 2 增加netter server for http * 重构 NettyHttpClient NettyHttpServer * add path parse util & requestTemplate * add mvc consumer http-connection * mvc change HttpConnectionPreBuildIntercept name and add SerializeBodyIntercept extend * 1. 迁移mvc代码到rest下,合并http统一解析逻辑 2. 删除多余新增的remoting 调用模块 * 解决报错 * 1 抽象http 调用 2 改造rest调用风格 * 修改方法命名 * 修改方法名 * 删除多余的clients * 还原restprotocol,逻辑迁移至新分支 3.2_refactor_rest_protocol * add provider PathMatcher * add ServiceRestMetadata PathMatcher * add ServiceRestMetadata PathMatcher * add jax_rs and mvc annotation class constants * refactor PathMatcher name * add annotation class * maintain rest metadata * maintain jax_rs and mvc annotation * maintain jax_rs and mvc annotation * remove mvc module * remove rest mvc code to code review * add springmvc & rest annotation api module * add springmvc & rest annotation api module * add pathMatcher equal test * remove mvc module * rest provider RPCInvocation build * RPCInvocation build add dubbo-metadata-api dependency * RestMethodMetadata add method to consumer service map * RestMethodMetadata add method to consumer service map * rest consumer HttpInvokeInvocationHandler * rest consumer HttpInvokeInvocationHandler * add dubbo-metadata-api dependency * dubbo-rpc pom fix * 移动模块 * 删除模块引用 * consumer metadata resolve * RestProtocol consumer * RestProtocol consumer * requestConvert adaptive * JSON serializeObject to outputStream * JsonUtilsTest serialize & unSerialize * ok http client * http client reconstruct * rest protocol BaseConvert * rest protocol ParamParser reconstruct * rest protocol addKeepAliveHeader * requestTemplate isBodyEmpty() * remove unused code * create ConsumerParseContext * body default byte[0] * rest http message decode * writeTextContent & writeJsonContent & writeFormContent * remove mvc & rest annotation module * remove provider code * fix some pr advice * Add ASF license header for newly created files * move RestClientFactory code to dubbo-remoting-http * exact request convert code to a factory class * modify request convert code * modify dubbo-dependencies-bom * modify dubbo-remoting-http pom * refactor spi resource file name * dubbo-metadata-api remove dubbo-configcenter-zookeeper dependency for cyclic reference * newly create file add ASF * fix compile error * Enhance Code * add rest protocol ConsumerParamParser * some fix * rest json content-type test * RestProtocol merge doRefer code to protocolBindingRefer * remove restInvoker * rest protocol add JsonFactory to support custom * rest protocol add JsonFactory to support custom * jaxrs rest ParamNoAnnotatedProcessor support fix * add rest http message encode * add rest http message encode * rest okHttpClient requestBody fix * rest jaxrs form content-type support * RestProtocol protocolBindingRefer reconstruct * RestProtocol protocolBindingRefer reconstruct object to invoker & Invocation * move RequestTemplate to remoting-http * rest unit test * add httpclient & url connection rest client * Enhance invocation * enhance * add ParameterTypesComparator for metadataMap * add ASF for new file * Fix conflict * Fix header * fix import * fix import * fix import * fix import * fix import * Fix json * revert some change * Remove jsonfactory * Remove jsonfactory * Simplify rest client * Fix protocol * fix codec * tmp disable test * rest metadata resolver add interface judge * add rest metadata resolve unit test & fix AbstractServiceRestMetadataResolver * org.apache.dubbo.metadata.rest.ParamType null exclude & add default accept header * RestProtocolTest refer add context path unit test * some fix * ADD TODO * RESOLVE HTTP client java.net.SocketException: socket closed * RESOLVE HTTP client java.net.SocketException: socket closed * add spring mvc rest protocol unit test * rest protocol http response code deal * rest protocol http response message * fix some review advice * fix some review advice * add rest metadata resolve unit test & fix AbstractServiceRestMetadataResolver * org.apache.dubbo.metadata.rest.ParamType null exclude & add default accept header * RestProtocolTest refer add context path unit test * some fix * fix some review advice * add spring mvc rest protocol unit test * rest protocol http response code deal * rest protocol http response message * URLConnectionRestClient getMessage * remove unused import * import fix * code merge * code merge * code merge * code merge * code merge * Fix conflicts * change restResult InputStream to bytes protect from fd leak * merge code * Fix import * Fix import * Fix uts * Remove unused code * Fix logger * Update okhttp version * Update okhttp version * rest protocol add AnotherUserRestService service ut * rest protocol add String & byteArray codec * Fix version * Fix uts * rest protocol add XMLCodec * stream release * ServiceRestMetadata port change int to Integer * service RestMetadata service map init * xml codec change for xxe * Fix import * code style * code style * Fix shade --------- Co-authored-by: suncr Co-authored-by: Liujunjie <42363259+LiujunjieALiling@users.noreply.github.com> Co-authored-by: junjie3.liu Co-authored-by: Albumen Kevin --- .../org/apache/dubbo/common/json/JSON.java | 1 - .../dubbo/common/json/impl/FastJson2Impl.java | 1 - .../dubbo/common/json/impl/FastJsonImpl.java | 1 + .../dubbo/common/json/impl/JacksonImpl.java | 3 + .../ServiceDefinitionBuilderTest.java | 4 +- dubbo-demo/dubbo-demo-interface/pom.xml | 14 + .../apache/dubbo/demo/RestDemoService.java | 54 +++- .../src/main/java/po/TestPO.java | 69 ++++ .../dubbo/demo/consumer/Application.java | 31 +- .../demo/provider/RestDemoServiceImpl.java | 37 +++ dubbo-dependencies-bom/pom.xml | 21 ++ dubbo-distribution/dubbo-all/pom.xml | 30 ++ dubbo-metadata/dubbo-metadata-api/pom.xml | 8 - .../metadata/AbstractServiceNameMapping.java | 1 - .../dubbo/metadata/MetadataConstants.java | 38 ++- .../metadata/ParameterTypesComparator.java | 49 +++ ...ractAnnotatedMethodParameterProcessor.java | 30 +- ...AbstractNoAnnotatedParameterProcessor.java | 68 ++++ .../AbstractServiceRestMetadataResolver.java | 113 +++++-- .../AnnotatedMethodParameterProcessor.java | 15 +- .../apache/dubbo/metadata/rest/ArgInfo.java | 151 +++++++++ .../metadata/rest/JAXRSClassConstants.java | 62 ++++ ...AnnotatedParameterRequestTagProcessor.java | 32 ++ .../apache/dubbo/metadata/rest/ParamType.java | 97 ++++++ .../dubbo/metadata/rest/PathMatcher.java | 146 +++++++++ .../apache/dubbo/metadata/rest/PathUtil.java | 157 +++++++++ .../dubbo/metadata/rest/RequestMetadata.java | 19 +- .../metadata/rest/RestMetadataConstants.java | 20 ++ .../metadata/rest/RestMethodMetadata.java | 67 +++- .../metadata/rest/ServiceRestMetadata.java | 104 +++++- .../rest/ServiceRestMetadataResolver.java | 7 +- .../rest/SpringMvcClassConstants.java | 51 +++ .../rest/jaxrs/BodyParameterProcessor.java | 52 +++ .../jaxrs/DefaultValueParameterProcessor.java | 5 +- .../jaxrs/FormParamParameterProcessor.java | 2 +- .../jaxrs/HeaderParamParameterProcessor.java | 5 +- .../JAXRSServiceRestMetadataResolver.java | 12 + .../jaxrs/MatrixParamParameterProcessor.java | 2 +- .../ParamAnnotationParameterProcessor.java | 3 +- .../jaxrs/PathParamParameterProcessor.java | 37 +++ .../jaxrs/QueryParamParameterProcessor.java | 2 +- .../dubbo/metadata/rest/media/MediaType.java | 46 +++ .../FormBodyNoAnnotatedProcessor.java | 41 +++ .../JsonBodyNoAnnotatedProcessor.java | 36 +++ .../springmvc/ParamNoAnnotatedProcessor.java | 43 +++ .../PathVariableParameterProcessor.java | 43 +++ .../RequestBodyParameterProcessor.java | 46 +++ .../RequestHeaderParameterProcessor.java | 5 +- .../RequestParamParameterProcessor.java | 6 +- .../SpringMvcServiceRestMetadataResolver.java | 15 + .../dubbo/metadata/rest/tag/BodyTag.java | 20 ++ ...ata.rest.AnnotatedMethodParameterProcessor | 6 +- ...st.NoAnnotatedParameterRequestTagProcessor | 3 + .../dubbo/metadata/PathMatcherTest.java | 32 ++ .../metadata/rest/DefaultRestService.java | 15 + .../dubbo/metadata/rest/RestService.java | 4 + .../metadata/rest/SpringRestService.java | 28 +- .../metadata/rest/StandardRestService.java | 24 ++ .../rest/api/AnotherUserRestService.java | 45 +++ .../metadata/rest/api/JaxrsRestService.java | 65 ++++ .../rest/api/JaxrsRestServiceImpl.java | 50 +++ .../metadata/rest/api/SpringRestService.java | 52 +++ .../rest/api/SpringRestServiceImpl.java | 53 +++ .../JAXRSServiceRestMetadataResolverTest.java | 86 ++++- ...ingMvcServiceRestMetadataResolverTest.java | 67 +++- .../metrics/filter/MetricsFilterTest.java | 20 +- .../PrometheusMetricsReporterTest.java | 1 - .../command/DefaultCommandExecutorTest.java | 2 - .../MetadataServiceNameMappingTest.java | 2 - .../org/apache/dubbo/remoting/Constants.java | 14 +- dubbo-remoting/dubbo-remoting-http/pom.xml | 20 +- .../dubbo/remoting/http/BaseRestClient.java | 43 +++ .../dubbo/remoting/http/RequestTemplate.java | 303 ++++++++++++++++++ .../dubbo/remoting/http/RestClient.java | 50 +++ .../dubbo/remoting/http/RestResult.java | 35 ++ .../http/config/HttpClientConfig.java | 62 ++++ .../factory/AbstractHttpClientFactory.java | 87 +++++ .../http/factory/RestClientFactory.java | 38 +++ .../factory/impl/ApacheHttpClientFactory.java | 37 +++ .../factory/impl/OkHttpClientFactory.java | 36 +++ .../impl/URLConnectionClientFactory.java | 36 +++ .../http/restclient/HttpClientRestClient.java | 153 +++++++++ .../http/restclient/OKHttpRestClient.java | 144 +++++++++ .../restclient/URLConnectionRestClient.java | 181 +++++++++++ ...bo.remoting.http.factory.RestClientFactory | 4 + ...ultiplexProtocolConnectionManagerTest.java | 1 - .../rpc/protocol/AbstractProxyProtocol.java | 51 +-- .../org/apache/dubbo/rpc/RpcContextTest.java | 2 - dubbo-rpc/dubbo-rpc-rest/pom.xml | 40 ++- .../rest/NettyRestProtocolServer.java | 4 +- .../protocol/rest/ReferenceCountedClient.java | 19 +- .../dubbo/rpc/protocol/rest/RestProtocol.java | 262 +++++++-------- .../rpc/protocol/rest/RestServerFactory.java | 8 +- .../rest/annotation/BaseParseContext.java | 51 +++ .../protocol/rest/annotation/ParamParser.java | 24 ++ .../rest/annotation/ParamParserManager.java | 61 ++++ .../consumer/HttpConnectionConfig.java | 51 +++ .../consumer/HttpConnectionCreateContext.java | 81 +++++ .../HttpConnectionPreBuildIntercept.java | 25 ++ .../inercept/AddMustAttachmentIntercept.java | 48 +++ .../inercept/AttachmentIntercept.java | 70 ++++ .../inercept/ParamParseIntercept.java | 39 +++ .../inercept/PathVariableIntercept.java | 51 +++ .../inercept/RequestHeaderIntercept.java | 54 ++++ .../inercept/SerializeBodyIntercept.java | 66 ++++ .../annotation/metadata/MetadataResolver.java | 57 ++++ .../consumer/BaseConsumerParamParser.java | 29 ++ .../consumer/BodyConsumerParamParser.java | 45 +++ .../parse/consumer/ConsumerParseContext.java | 34 ++ .../consumer/FormConsumerParamParser.java | 54 ++++ .../consumer/HeaderConsumerParamParser.java | 41 +++ .../ParameterConsumerParamParser.java | 41 +++ .../protocol/rest/constans/RestConstant.java | 60 ++++ .../CodeStyleNotSupportException.java | 24 ++ .../rest/exception/HttpClientException.java | 24 ++ .../RemoteServerInternalException.java | 24 ++ .../UnSupportContentTypeException.java | 27 ++ .../rest/message/HttpMessageCodec.java | 30 ++ .../rest/message/HttpMessageCodecManager.java | 51 +++ .../rest/message/HttpMessageDecode.java | 24 ++ .../rest/message/HttpMessageEncode.java | 28 ++ .../rest/message/MediaTypeMatcher.java | 64 ++++ .../rest/message/codec/ByteArrayCodec.java | 45 +++ .../rest/message/codec/JsonCodec.java | 57 ++++ .../rest/message/codec/MultiValueCodec.java | 48 +++ .../rest/message/codec/StringCodec.java | 47 +++ .../rest/message/codec/TextCodec.java | 47 +++ .../protocol/rest/message/codec/XMLCodec.java | 72 +++++ .../protocol/rest/util/DataParseUtils.java | 215 +++++++++++++ .../rpc/protocol/rest/util/MediaTypeUtil.java | 42 +++ .../protocol/rest/util/MultiValueCreator.java | 55 ++++ .../rpc/protocol/rest/util/NumberUtils.java | 149 +++++++++ .../rpc/protocol/rest/util/ReflectUtils.java | 269 ++++++++++++++++ .../rpc/protocol/rest/util/StreamUtils.java | 41 +++ .../rpc/protocol/rest/util/TypeUtil.java | 38 +++ ...n.consumer.HttpConnectionPreBuildIntercept | 6 + ...ram.parse.consumer.BaseConsumerParamParser | 5 + ...rpc.protocol.rest.message.HttpMessageCodec | 6 + .../dubbo/rpc/protocol/rest/DemoService.java | 29 +- .../rpc/protocol/rest/DemoServiceImpl.java | 19 +- ...olTest.java => JaxrsRestProtocolTest.java} | 44 ++- .../rest/SpringMvcRestProtocolTest.java | 278 ++++++++++++++++ .../apache/dubbo/rpc/protocol/rest/User.java | 62 ++++ .../rpc/protocol/rest/mvc/DemoService.java | 36 +++ .../rest/mvc/SpringDemoServiceImpl.java | 55 ++++ .../rest/rest/AnotherUserRestService.java | 57 ++++ .../rest/rest/AnotherUserRestServiceImpl.java | 53 +++ .../rest/rest/RegistrationResult.java | 44 +++ .../protocol/rest/rest/RestDemoService.java | 43 +++ .../rest/rest/RestDemoServiceImpl.java | 55 ++++ .../test/common/api/SpringmvcDemoService.java | 21 ++ 151 files changed, 6947 insertions(+), 376 deletions(-) create mode 100644 dubbo-demo/dubbo-demo-interface/src/main/java/po/TestPO.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ParameterTypesComparator.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/NoAnnotatedParameterRequestTagProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathUtil.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/SpringMvcClassConstants.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/BodyParameterProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/PathParamParameterProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/media/MediaType.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/FormBodyNoAnnotatedProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/JsonBodyNoAnnotatedProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/ParamNoAnnotatedProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/PathVariableParameterProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestBodyParameterProcessor.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/tag/BodyTag.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.NoAnnotatedParameterRequestTagProcessor create mode 100644 dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/AnotherUserRestService.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestService.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestServiceImpl.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestService.java create mode 100644 dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestServiceImpl.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/BaseRestClient.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RequestTemplate.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestClient.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestResult.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/config/HttpClientConfig.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/AbstractHttpClientFactory.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/RestClientFactory.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/ApacheHttpClientFactory.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/OkHttpClientFactory.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/URLConnectionClientFactory.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/HttpClientRestClient.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/OKHttpRestClient.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/URLConnectionRestClient.java create mode 100644 dubbo-remoting/dubbo-remoting-http/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/BaseParseContext.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParser.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionConfig.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionCreateContext.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionPreBuildIntercept.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AddMustAttachmentIntercept.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AttachmentIntercept.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/ParamParseIntercept.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/PathVariableIntercept.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/SerializeBodyIntercept.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/metadata/MetadataResolver.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BaseConsumerParamParser.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BodyConsumerParamParser.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ConsumerParseContext.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/FormConsumerParamParser.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/HeaderConsumerParamParser.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ParameterConsumerParamParser.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/CodeStyleNotSupportException.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/HttpClientException.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/RemoteServerInternalException.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/UnSupportContentTypeException.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodec.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageEncode.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/MediaTypeMatcher.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MediaTypeUtil.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NumberUtils.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/ReflectUtils.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/StreamUtils.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/TypeUtil.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec rename dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/{RestProtocolTest.java => JaxrsRestProtocolTest.java} (85%) create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/SpringMvcRestProtocolTest.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/DemoService.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/SpringDemoServiceImpl.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestService.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestServiceImpl.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RegistrationResult.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoService.java create mode 100644 dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoServiceImpl.java create mode 100644 dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/SpringmvcDemoService.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java index c4210c60cb..7eddf3d988 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java @@ -48,5 +48,4 @@ public interface JSON { List> checkObjectList(List rawList); List checkStringList(List rawList); - } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java index a4021f059a..88f8920e37 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java @@ -22,7 +22,6 @@ import java.lang.reflect.Type; import java.util.List; public class FastJson2Impl extends AbstractJSONImpl { - @Override public T toJavaObject(String json, Type type) { return com.alibaba.fastjson2.JSON.parseObject(json, type); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java index 0bd3201ed7..9397183f61 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java @@ -37,4 +37,5 @@ public class FastJsonImpl extends AbstractJSONImpl { public String toJson(Object obj) { return com.alibaba.fastjson.JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect); } + } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java index 1e4387854e..dc6f6e380b 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java @@ -16,8 +16,10 @@ */ package org.apache.dubbo.common.json.impl; + import com.fasterxml.jackson.annotation.JsonInclude.Include; 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; @@ -25,6 +27,7 @@ import java.lang.reflect.Type; import java.util.List; public class JacksonImpl extends AbstractJSONImpl { + private ObjectMapper objectMapper = new ObjectMapper(); private volatile Object jacksonCache = null; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java index 1df9ebdcdf..1fe844ac2c 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java @@ -21,8 +21,6 @@ import org.apache.dubbo.metadata.definition.model.MethodDefinition; import org.apache.dubbo.metadata.definition.model.TypeDefinition; import org.apache.dubbo.metadata.definition.service.ComplexObject; import org.apache.dubbo.metadata.definition.service.DemoService; -import org.apache.dubbo.rpc.model.FrameworkModel; - import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; @@ -134,4 +132,4 @@ class ServiceDefinitionBuilderTest { Assertions.assertEquals(Integer.class.getCanonicalName(), listTypeDefinition.getItems().get(0)); } -} \ No newline at end of file +} diff --git a/dubbo-demo/dubbo-demo-interface/pom.xml b/dubbo-demo/dubbo-demo-interface/pom.xml index b2b1cd7332..7cc0c57707 100644 --- a/dubbo-demo/dubbo-demo-interface/pom.xml +++ b/dubbo-demo/dubbo-demo-interface/pom.xml @@ -35,5 +35,19 @@ org.apache.dubbo dubbo-rpc-rest + + + + org.springframework + spring-web + test + + + + + org.springframework + spring-context + test + diff --git a/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/RestDemoService.java b/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/RestDemoService.java index 308b061c49..8caa8ccebc 100644 --- a/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/RestDemoService.java +++ b/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/RestDemoService.java @@ -16,18 +16,26 @@ */ package org.apache.dubbo.demo; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; + +import po.TestPO; + import javax.ws.rs.Path; +import javax.ws.rs.GET; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.POST; +import javax.ws.rs.FormParam; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; @Path("/demoService") public interface RestDemoService { @GET @Path("/hello") + @Consumes(MediaType.TEXT_PLAIN) + @Produces(MediaType.TEXT_PLAIN) Integer hello(@QueryParam("a") Integer a, @QueryParam("b") Integer b); @GET @@ -42,4 +50,44 @@ public interface RestDemoService { @GET @Path("/getRemoteApplicationName") String getRemoteApplicationName(); + + @POST + @Path("/testBody1") + @Consumes({MediaType.TEXT_PLAIN}) + Integer testBody(Integer b); + + @POST + @Path("/testBody2") + @Consumes({MediaType.TEXT_PLAIN}) + String testBody2(String b); + + @POST + @Path("/testBody3") + @Consumes({MediaType.TEXT_PLAIN}) + Boolean testBody2(Boolean b); + + @POST + @Path("/testBody3") + @Consumes({MediaType.TEXT_PLAIN}) + TestPO testBody2(TestPO b); + + + @POST + @Path("/testBody5") + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + TestPO testBody5(TestPO testPO); + + @POST + @Path("/testForm1") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + String testForm1(@FormParam("name") String test); + + + @POST + @Path("/testForm2") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.APPLICATION_FORM_URLENCODED) + MultivaluedMap testForm2(MultivaluedMap map); } diff --git a/dubbo-demo/dubbo-demo-interface/src/main/java/po/TestPO.java b/dubbo-demo/dubbo-demo-interface/src/main/java/po/TestPO.java new file mode 100644 index 0000000000..4cd1df96d8 --- /dev/null +++ b/dubbo-demo/dubbo-demo-interface/src/main/java/po/TestPO.java @@ -0,0 +1,69 @@ +/* + * 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 po; + +public class TestPO { + private String name; + private String address; + private int age; + + public TestPO(String name, String address, int age) { + this.name = name; + this.address = address; + this.age = age; + } + + public TestPO() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public static TestPO getInstance() { + return new TestPO("dubbo", "hangzhou", 10); + } + + @Override + public String toString() { + return "TestPO{" + + "name='" + name + '\'' + + ", address='" + address + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java index 01adf4a60d..b32502fcc3 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java @@ -22,7 +22,11 @@ import org.apache.dubbo.demo.RestDemoService; import org.apache.dubbo.demo.TripleService; import org.springframework.context.support.ClassPathXmlApplicationContext; +import po.TestPO; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import java.util.Arrays; import java.util.concurrent.CompletableFuture; public class Application { @@ -56,23 +60,22 @@ public class Application { new Thread(() -> { while (true) { try { - String restResult = restDemoService.sayHello("rest"); + Object restResult = restDemoService.sayHello("rest"); + System.out.println(restResult + " from separated thread."); + restResult = restDemoService.testBody5(TestPO.getInstance()); System.out.println(restResult + " from separated thread."); - } catch (Exception e) { - e.printStackTrace(); - } - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - } - } - }).start(); - new Thread(() -> { - while (true) { - try { - String restResult = tripleService.hello(); + restResult = restDemoService.hello(1, 2); System.out.println(restResult + " from separated thread."); + + String form1 = restDemoService.testForm1("form1"); + System.out.println(form1); + + MultivaluedHashMap multivaluedHashMap = new MultivaluedHashMap(); + multivaluedHashMap.put("1", Arrays.asList("1")); + multivaluedHashMap.put("2", Arrays.asList("2")); + MultivaluedMap form2 = restDemoService.testForm2(multivaluedHashMap); + System.out.println(form2); } catch (Exception e) { e.printStackTrace(); } diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/RestDemoServiceImpl.java b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/RestDemoServiceImpl.java index 67d523aee0..c0864c7a1b 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/RestDemoServiceImpl.java +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/RestDemoServiceImpl.java @@ -19,7 +19,9 @@ package org.apache.dubbo.demo.provider; import org.apache.dubbo.demo.RestDemoService; import org.apache.dubbo.rpc.RpcContext; +import po.TestPO; +import javax.ws.rs.core.MultivaluedMap; import java.util.Map; public class RestDemoServiceImpl implements RestDemoService { @@ -55,4 +57,39 @@ public class RestDemoServiceImpl implements RestDemoService { public String getRemoteApplicationName() { return RpcContext.getServiceContext().getRemoteApplicationName(); } + + @Override + public Integer testBody(Integer b) { + return b; + } + + @Override + public String testBody2(String b) { + return b; + } + + @Override + public Boolean testBody2(Boolean b) { + return b; + } + + @Override + public TestPO testBody2(TestPO b) { + return b; + } + + @Override + public TestPO testBody5(TestPO testPO) { + return testPO; + } + + + public String testForm1(String test) { + return test; + } + + + public MultivaluedMap testForm2(MultivaluedMap map) { + return map; + } } diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index ed95d08993..cc437deab3 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -117,6 +117,7 @@ 3.19.6 1.3.2 3.1.0 + 5.0.0 9.4.50.v20221201 3.0.1 1.1.0.Final @@ -139,6 +140,7 @@ 0.16.0 1.0.4 3.5.2 + 4.10.0 2.1.1 3.15.3.Final @@ -419,6 +421,25 @@ javax.servlet-api ${servlet_version} + + + + jakarta.servlet + jakarta.servlet-api + ${jakarta.servlet_version} + + + + com.squareup.okhttp3 + okhttp + ${okhttp_version} + + + com.squareup.okhttp3 + mockwebserver + ${okhttp_version} + + org.eclipse.jetty jetty-server diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index b9bb45e01a..23b1192686 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -906,6 +906,36 @@ META-INF/dubbo/internal/org.apache.dubbo.registry.xds.XdsCertificateSigner + + + META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.NoAnnotatedParameterRequestTagProcessor + + + + + META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec + + + + + META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept + + + + + META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser + + + + + META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory + + diff --git a/dubbo-metadata/dubbo-metadata-api/pom.xml b/dubbo-metadata/dubbo-metadata-api/pom.xml index 67e4dd8ff0..9fc83dd32f 100644 --- a/dubbo-metadata/dubbo-metadata-api/pom.xml +++ b/dubbo-metadata/dubbo-metadata-api/pom.xml @@ -45,14 +45,6 @@ ${project.parent.version} - - - org.apache.dubbo - dubbo-configcenter-zookeeper - ${project.parent.version} - test - - javax.ws.rs diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java index e714b0d003..675067276d 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java @@ -41,7 +41,6 @@ import static java.util.Collections.emptySet; import static java.util.Collections.unmodifiableSet; import static java.util.stream.Collectors.toSet; import static java.util.stream.Stream.of; - import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_FAILED_LOAD_MAPPING_CACHE; import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY; import static org.apache.dubbo.common.utils.CollectionUtils.toTreeSet; diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java index c6bda320c6..3fe976a1de 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java @@ -16,16 +16,30 @@ */ package org.apache.dubbo.metadata; -public class MetadataConstants { - public static final String KEY_SEPARATOR = ":"; - public static final String DEFAULT_PATH_TAG = "metadata"; - public static final String KEY_REVISON_PREFIX = "revision"; - public static final String META_DATA_STORE_TAG = ".metaData"; - public static final String SERVICE_META_DATA_STORE_TAG = ".smd"; - public static final String CONSUMER_META_DATA_STORE_TAG = ".cmd"; - public static final String METADATA_PUBLISH_DELAY_KEY = "dubbo.application.metadata.publish.delay"; - public static final int DEFAULT_METADATA_PUBLISH_DELAY = 1000; - public static final String METADATA_PROXY_TIMEOUT_KEY = "dubbo.application.metadata.proxy.delay"; - public static final int DEFAULT_METADATA_TIMEOUT_VALUE = 5000; - public static String REPORT_CONSUMER_URL_KEY = "report-consumer-definition"; +import static org.apache.dubbo.common.utils.ClassUtils.getClassLoader; +import static org.apache.dubbo.common.utils.ClassUtils.resolveClass; + +public interface MetadataConstants { + String KEY_SEPARATOR = ":"; + String DEFAULT_PATH_TAG = "metadata"; + String KEY_REVISON_PREFIX = "revision"; + String META_DATA_STORE_TAG = ".metaData"; + String SERVICE_META_DATA_STORE_TAG = ".smd"; + String CONSUMER_META_DATA_STORE_TAG = ".cmd"; + String METADATA_PUBLISH_DELAY_KEY = "dubbo.application.metadata.publish.delay"; + int DEFAULT_METADATA_PUBLISH_DELAY = 1000; + String METADATA_PROXY_TIMEOUT_KEY = "dubbo.application.metadata.proxy.delay"; + int DEFAULT_METADATA_TIMEOUT_VALUE = 5000; + String REPORT_CONSUMER_URL_KEY = "report-consumer-definition"; + String JAVAX_SERVLET_REQ_CLASS_NAME = "javax.servlet.ServletRequest"; + Class JAVAX_SERVLET_REQ_CLASS = resolveClass(JAVAX_SERVLET_REQ_CLASS_NAME, getClassLoader()); + String JAVAX_SERVLET_RES_CLASS_NAME = "javax.servlet.ServletResponse"; + Class JAVAX_SERVLET_RES_CLASS = resolveClass(JAVAX_SERVLET_RES_CLASS_NAME, getClassLoader()); + String JAKARTA_SERVLET_REQ_CLASS_NAME = "jakarta.servlet.ServletRequest"; + Class JAKARTA_SERVLET_REQ_CLASS = resolveClass(JAKARTA_SERVLET_REQ_CLASS_NAME, getClassLoader()); + String JAKARTA_SERVLET_RES_CLASS_NAME = "jakarta.servlet.ServletResponse"; + Class JAKARTA_SERVLET_RES_CLASS = resolveClass(JAKARTA_SERVLET_RES_CLASS_NAME, getClassLoader()); + String PATH_SEPARATOR = "/"; + String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded"; + String APPLICATION_JSON_VALUE = "application/json"; } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ParameterTypesComparator.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ParameterTypesComparator.java new file mode 100644 index 0000000000..35527d0356 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ParameterTypesComparator.java @@ -0,0 +1,49 @@ +/* + * 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.metadata; + +import java.util.Arrays; + +public class ParameterTypesComparator { + + private Class[] parameterTypes; + + + public ParameterTypesComparator(Class[] parameterTypes) { + this.parameterTypes = parameterTypes; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ParameterTypesComparator that = (ParameterTypesComparator) o; + return Arrays.equals(parameterTypes, that.parameterTypes); + } + + @Override + public int hashCode() { + return Arrays.hashCode(parameterTypes); + } + + + public static ParameterTypesComparator getInstance(Class[] parameterTypes) { + return new ParameterTypesComparator(parameterTypes); + } + + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractAnnotatedMethodParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractAnnotatedMethodParameterProcessor.java index a168f0f96b..71d47cfda6 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractAnnotatedMethodParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractAnnotatedMethodParameterProcessor.java @@ -16,12 +16,14 @@ */ package org.apache.dubbo.metadata.rest; + import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import static org.apache.dubbo.common.utils.AnnotationUtils.getValue; -import static org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor.buildDefaultValue; +import static org.apache.dubbo.common.utils.ClassUtils.getClassLoader; +import static org.apache.dubbo.common.utils.ClassUtils.resolveClass; /** * The abstract {@link AnnotatedMethodParameterProcessor} implementation @@ -33,19 +35,39 @@ public abstract class AbstractAnnotatedMethodParameterProcessor implements Annot @Override public void process(Annotation annotation, Parameter parameter, int parameterIndex, Method method, Class serviceType, Class serviceInterfaceClass, RestMethodMetadata restMethodMetadata) { + String annotationValue = getAnnotationValue(annotation, parameter, parameterIndex); String defaultValue = getDefaultValue(annotation, parameter, parameterIndex); + addArgInfo(parameter, parameterIndex, restMethodMetadata, annotationValue, defaultValue); process(annotationValue, defaultValue, annotation, parameter, parameterIndex, method, restMethodMetadata); } + + protected void process(String annotationValue, String defaultValue, Annotation annotation, Parameter parameter, + int parameterIndex, Method method, RestMethodMetadata restMethodMetadata) { + + } + + + @Override + public Class getAnnotationClass() { + return resolveClass(getAnnotationName(), getClassLoader()); + } + + protected void addArgInfo(Parameter parameter, int parameterIndex, + RestMethodMetadata restMethodMetadata, String annotationValue, Object defaultValue) { + ArgInfo argInfo = ArgInfo.build(parameterIndex, parameter) + .setParamAnnotationType(getAnnotationClass()) + .setAnnotationNameAttribute(annotationValue).setDefaultValue(defaultValue); + restMethodMetadata.addArgInfo(argInfo); + } + protected String getAnnotationValue(Annotation annotation, Parameter parameter, int parameterIndex) { return getValue(annotation); } protected String getDefaultValue(Annotation annotation, Parameter parameter, int parameterIndex) { - return buildDefaultValue(parameterIndex); + return AnnotatedMethodParameterProcessor.buildDefaultValue(parameterIndex); } - protected abstract void process(String annotationValue, String defaultValue, Annotation annotation, Object parameter, - int parameterIndex, Method method, RestMethodMetadata restMethodMetadata); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java new file mode 100644 index 0000000000..10748375b9 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java @@ -0,0 +1,68 @@ +/* + * 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.metadata.rest; + +import org.apache.dubbo.metadata.rest.media.MediaType; + +import java.lang.reflect.Parameter; +import java.util.Set; + +import static org.apache.dubbo.common.utils.ClassUtils.getClassLoader; +import static org.apache.dubbo.common.utils.ClassUtils.resolveClass; + +public abstract class AbstractNoAnnotatedParameterProcessor implements NoAnnotatedParameterRequestTagProcessor { + + public void process(Parameter parameter, int parameterIndex, RestMethodMetadata restMethodMetadata) { + MediaType mediaType = consumerContentType(); + if (!contentTypeSupport(restMethodMetadata, mediaType, parameter.getType())) { + return; + } + boolean isFormBody = isFormContentType(restMethodMetadata); + addArgInfo(parameter, parameterIndex, restMethodMetadata, isFormBody); + } + + private boolean contentTypeSupport(RestMethodMetadata restMethodMetadata, MediaType mediaType, Class paramType) { + + // @RequestParam String,number param + if (mediaType.equals(MediaType.ALL_VALUE) && (String.class == paramType || Number.class.isAssignableFrom(paramType))) { + return true; + } + + Set consumes = restMethodMetadata.getRequest().getConsumes(); + for (String consume : consumes) { + if (consume.contains(mediaType.value)) { + return true; + } + } + + return false; + } + + protected boolean isFormContentType(RestMethodMetadata restMethodMetadata) { + + return false; + } + + + protected void addArgInfo(Parameter parameter, int parameterIndex, + RestMethodMetadata restMethodMetadata, boolean isFormBody) { + ArgInfo argInfo = ArgInfo.build(parameterIndex, parameter) + .setParamAnnotationType(resolveClass(defaultAnnotationClassName(restMethodMetadata), getClassLoader())) + .setAnnotationNameAttribute(parameter.getName()).setFormContentType(isFormBody); + restMethodMetadata.addArgInfo(argInfo); + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractServiceRestMetadataResolver.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractServiceRestMetadataResolver.java index 70434278da..574a61e2c3 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractServiceRestMetadataResolver.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractServiceRestMetadataResolver.java @@ -43,6 +43,8 @@ import static org.apache.dubbo.common.function.ThrowableFunction.execute; import static org.apache.dubbo.common.utils.AnnotationUtils.isAnyAnnotationPresent; import static org.apache.dubbo.common.utils.ClassUtils.forName; import static org.apache.dubbo.common.utils.ClassUtils.getAllInterfaces; +import static org.apache.dubbo.common.utils.MemberUtils.isPrivate; +import static org.apache.dubbo.common.utils.MemberUtils.isStatic; import static org.apache.dubbo.common.utils.MethodUtils.excludedDeclaredClass; import static org.apache.dubbo.common.utils.MethodUtils.getAllMethods; import static org.apache.dubbo.common.utils.MethodUtils.overrides; @@ -56,13 +58,27 @@ import static org.apache.dubbo.common.utils.MethodUtils.overrides; public abstract class AbstractServiceRestMetadataResolver implements ServiceRestMetadataResolver { private final Map> parameterProcessorsMap; + private final Set noAnnotatedParameterRequestTagProcessors; public AbstractServiceRestMetadataResolver(ApplicationModel applicationModel) { this.parameterProcessorsMap = loadAnnotatedMethodParameterProcessors(applicationModel); + this.noAnnotatedParameterRequestTagProcessors = loadNoAnnotatedMethodParameterProcessors(applicationModel); } @Override public final boolean supports(Class serviceType) { + return supports(serviceType, false); + } + + @Override + public final boolean supports(Class serviceType, boolean consumer) { + // for consumer + if (consumer) { + // it is possible serviceType is impl + return supports0(serviceType); + } + + // for provider return isImplementedInterface(serviceType) && isServiceAnnotationPresent(serviceType) && supports0(serviceType); } @@ -72,7 +88,7 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest protected final boolean isServiceAnnotationPresent(Class serviceType) { return isAnyAnnotationPresent(serviceType, DubboService.class, Service.class, - com.alibaba.dubbo.config.annotation.Service.class); + com.alibaba.dubbo.config.annotation.Service.class); } /** @@ -85,12 +101,18 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest @Override public final ServiceRestMetadata resolve(Class serviceType) { - ServiceRestMetadata serviceRestMetadata = new ServiceRestMetadata(); // Process ServiceRestMetadata processServiceRestMetadata(serviceRestMetadata, serviceType); + return resolve(serviceType, serviceRestMetadata); + } + + + @Override + public final ServiceRestMetadata resolve(Class serviceType, ServiceRestMetadata serviceRestMetadata) { + serviceRestMetadata.setCodeStyle(this.getClass()); // Process RestMethodMetadata processAllRestMethodMetadata(serviceRestMetadata, serviceType); @@ -128,10 +150,10 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest // try the overrider method first Method serviceMethod = entry.getKey(); // If failed, it indicates the overrider method does not contain metadata , then try the declared method - if (!processRestMethodMetadata(serviceMethod, serviceType, serviceInterfaceClass, serviceRestMetadata.getMeta()::add)) { + if (!processRestMethodMetadata(serviceMethod, serviceType, serviceInterfaceClass, serviceRestMetadata::addRestMethodMetadata)) { Method declaredServiceMethod = entry.getValue(); processRestMethodMetadata(declaredServiceMethod, serviceType, serviceInterfaceClass, - serviceRestMetadata.getMeta()::add); + serviceRestMetadata::addRestMethodMetadata); } } } @@ -148,8 +170,16 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest Map serviceMethodsMap = new LinkedHashMap<>(); // exclude the public methods declared in java.lang.Object.class List declaredServiceMethods = new ArrayList<>(getAllMethods(serviceInterfaceClass, excludedDeclaredClass(Object.class))); + + // for interface , such as consumer interface + if (serviceType.isInterface()) { + putInterfaceMethodToMap(serviceMethodsMap, declaredServiceMethods); + return unmodifiableMap(serviceMethodsMap); + } + List serviceMethods = new ArrayList<>(getAllMethods(serviceType, excludedDeclaredClass(Object.class))); + // sort methods sort(declaredServiceMethods, MethodComparator.INSTANCE); sort(serviceMethods, MethodComparator.INSTANCE); @@ -158,7 +188,8 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest for (Method serviceMethod : serviceMethods) { if (overrides(serviceMethod, declaredServiceMethod)) { serviceMethodsMap.put(serviceMethod, declaredServiceMethod); - continue; + // once method match ,break for decrease loop times + break; } } } @@ -166,6 +197,17 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest return unmodifiableMap(serviceMethodsMap); } + private void putInterfaceMethodToMap(Map serviceMethodsMap, List declaredServiceMethods) { + declaredServiceMethods.stream().forEach(method -> { + + // filter static private default + if (isStatic(method) || isPrivate(method) || method.isDefault()) { + return; + } + serviceMethodsMap.put(method, method); + }); + } + /** * Resolve the class of Dubbo Service interface * @@ -212,13 +254,15 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest RestMethodMetadata metadata = new RestMethodMetadata(); + metadata.setCodeStyle(this.getClass()); + + // to consumer service map + metadata.setReflectMethod(serviceMethod); + MethodDefinition methodDefinition = resolveMethodDefinition(serviceMethod, serviceType, serviceInterfaceClass); // Set MethodDefinition metadata.setMethod(methodDefinition); - // process the annotated method parameters - processAnnotatedMethodParameters(serviceMethod, serviceType, serviceInterfaceClass, metadata); - // process produces Set produces = new LinkedHashSet<>(); processProduces(serviceMethod, serviceType, serviceInterfaceClass, produces); @@ -234,6 +278,10 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest request.setProduces(produces); request.setConsumes(consumes); + // process the annotated method parameters + processAnnotatedMethodParameters(serviceMethod, serviceType, serviceInterfaceClass, metadata); + + // Post-Process postResolveRestMethodMetadata(serviceMethod, serviceType, serviceInterfaceClass, metadata); @@ -252,7 +300,7 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest * @return If capable, return true */ protected abstract boolean isRestCapableMethod(Method serviceMethod, Class serviceType, Class - serviceInterfaceClass); + serviceInterfaceClass); /** * Resolve the request method @@ -263,7 +311,7 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest * @return if can't be resolve, return null */ protected abstract String resolveRequestMethod(Method serviceMethod, Class serviceType, Class - serviceInterfaceClass); + serviceInterfaceClass); /** * Resolve the request path @@ -274,7 +322,7 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest * @return if can't be resolve, return null */ protected abstract String resolveRequestPath(Method serviceMethod, Class serviceType, Class - serviceInterfaceClass); + serviceInterfaceClass); /** * Resolve the {@link MethodDefinition} @@ -307,37 +355,56 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest Class serviceType, Class serviceInterfaceClass, RestMethodMetadata metadata) { Annotation[] annotations = parameter.getAnnotations(); + + if (annotations == null || annotations.length == 0) { + + for (NoAnnotatedParameterRequestTagProcessor processor : noAnnotatedParameterRequestTagProcessors) { + processor.process(parameter, parameterIndex, metadata); + } + return; + } + for (Annotation annotation : annotations) { String annotationType = annotation.annotationType().getName(); parameterProcessorsMap.getOrDefault(annotationType, emptyList()) - .forEach(processor -> { - processor.process(annotation, parameter, parameterIndex, serviceMethod, serviceType, - serviceInterfaceClass, metadata); - }); + .forEach(processor -> { + processor.process(annotation, parameter, parameterIndex, serviceMethod, serviceType, + serviceInterfaceClass, metadata); + }); } } protected abstract void processProduces(Method serviceMethod, Class serviceType, Class - serviceInterfaceClass, + serviceInterfaceClass, Set produces); protected abstract void processConsumes(Method serviceMethod, Class serviceType, Class - serviceInterfaceClass, + serviceInterfaceClass, Set consumes); protected void postResolveRestMethodMetadata(Method serviceMethod, Class serviceType, Class serviceInterfaceClass, RestMethodMetadata metadata) { + + // parse pathVariable index from url by annotation info + PathUtil.setArgInfoSplitIndex(metadata.getRequest().getPath(), metadata.getArgInfos()); } private static Map> loadAnnotatedMethodParameterProcessors(ApplicationModel applicationModel) { Map> parameterProcessorsMap = new LinkedHashMap<>(); applicationModel.getExtensionLoader(AnnotatedMethodParameterProcessor.class) - .getSupportedExtensionInstances() - .forEach(processor -> { - List processors = - parameterProcessorsMap.computeIfAbsent(processor.getAnnotationType(), k -> new LinkedList<>()); - processors.add(processor); - }); + .getSupportedExtensionInstances() + .forEach(processor -> { + List processors = + parameterProcessorsMap.computeIfAbsent(processor.getAnnotationName(), k -> new LinkedList<>()); + processors.add(processor); + }); return parameterProcessorsMap; } + + private static Set loadNoAnnotatedMethodParameterProcessors(ApplicationModel applicationModel) { + Set supportedExtensionInstances = applicationModel.getExtensionLoader(NoAnnotatedParameterRequestTagProcessor.class) + .getSupportedExtensionInstances(); + + return supportedExtensionInstances; + } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AnnotatedMethodParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AnnotatedMethodParameterProcessor.java index bd520179ad..506b6cf665 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AnnotatedMethodParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AnnotatedMethodParameterProcessor.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.metadata.rest; +import org.apache.dubbo.common.extension.ExtensionScope; import org.apache.dubbo.common.extension.SPI; import org.apache.dubbo.common.lang.Prioritized; @@ -29,20 +30,28 @@ import java.lang.reflect.Parameter; * * @since 2.7.6 */ -@SPI +@SPI(scope = ExtensionScope.FRAMEWORK) public interface AnnotatedMethodParameterProcessor extends Prioritized { + /** + * The string presenting the annotation name + * + * @return non-null + */ + String getAnnotationName(); + + /** * The string presenting the annotation type * * @return non-null */ - String getAnnotationType(); + Class getAnnotationClass(); /** * Process the specified method {@link VariableElement parameter} * - * @param annotation {@link Annotation the target annotation} whose type is {@link #getAnnotationType()} + * @param annotation {@link Annotation the target annotation} whose type is {@link #getAnnotationName()} * @param parameter the method parameter * @param parameterIndex the index of method parameter * @param method {@link Method method that parameter belongs to} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java new file mode 100644 index 0000000000..599726e1e0 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest; + + +import java.lang.reflect.Parameter; + +public class ArgInfo { + /** + * method arg index 0,1,2,3 + */ + private int index; + /** + * method annotation name or name + */ + private String annotationNameAttribute; + + /** + * param annotation type + */ + private Class paramAnnotationType; + + /** + * param Type + */ + private Class paramType; + + /** + * param name + */ + private String paramName; + + /** + * url split("/") String[n] index + */ + private int urlSplitIndex; + + private Object defaultValue; + + private boolean formContentType; + + public ArgInfo(int index, String name, Class paramType) { + this.index = index; + this.paramName = name; + this.paramType = paramType; + } + + public ArgInfo(int index, Parameter parameter) { + this(index, parameter.getName(), parameter.getType()); + } + + public ArgInfo() { + } + + public int getIndex() { + return index; + } + + public ArgInfo setIndex(int index) { + this.index = index; + return this; + } + + public String getAnnotationNameAttribute() { + if (annotationNameAttribute == null) { + // such as String param no annotation + return paramName; + } + return annotationNameAttribute; + } + + public ArgInfo setAnnotationNameAttribute(String annotationNameAttribute) { + this.annotationNameAttribute = annotationNameAttribute; + return this; + } + + public Class getParamAnnotationType() { + return paramAnnotationType; + } + + public ArgInfo setParamAnnotationType(Class paramAnnotationType) { + this.paramAnnotationType = paramAnnotationType; + return this; + } + + public Class getParamType() { + return paramType; + } + + public void setParamType(Class paramType) { + this.paramType = paramType; + } + + + public int getUrlSplitIndex() { + return urlSplitIndex; + } + + public void setUrlSplitIndex(int urlSplitIndex) { + this.urlSplitIndex = urlSplitIndex; + } + + public static ArgInfo build() { + return new ArgInfo(); + } + + public static ArgInfo build(int index, Parameter parameter) { + return new ArgInfo(index, parameter); + } + + public String getParamName() { + return paramName; + } + + public ArgInfo setParamName(String paramName) { + this.paramName = paramName; + return this; + } + + public Object getDefaultValue() { + return defaultValue; + } + + public ArgInfo setDefaultValue(Object defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + public boolean isFormContentType() { + return formContentType; + } + + public ArgInfo setFormContentType(boolean isFormContentType) { + this.formContentType = isFormContentType; + return this; + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java new file mode 100644 index 0000000000..f1797cfc41 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java @@ -0,0 +1,62 @@ +/* + * 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.metadata.rest; + +import static org.apache.dubbo.common.utils.ClassUtils.getClassLoader; +import static org.apache.dubbo.common.utils.ClassUtils.resolveClass; + +public interface JAXRSClassConstants extends RestMetadataConstants.JAX_RS { + /** + * The annotation class of @Path + */ + Class PATH_ANNOTATION_CLASS = resolveClass(PATH_ANNOTATION_CLASS_NAME, getClassLoader()); + + + /** + * The annotation class of @FormParam + */ + Class FORM_PARAM_ANNOTATION_CLASS = resolveClass(FORM_PARAM_ANNOTATION_CLASS_NAME, getClassLoader()); + + /** + * The annotation class of @HeaderParam + */ + Class HEADER_PARAM_ANNOTATION_CLASS = resolveClass(HEADER_PARAM_ANNOTATION_CLASS_NAME, getClassLoader()); + + + /** + * The annotation class of @MatrixParam + */ + Class MATRIX_PARAM_ANNOTATION_CLASS = resolveClass(MATRIX_PARAM_ANNOTATION_CLASS_NAME, getClassLoader()); + + + /** + * The annotation class of @QueryParam + */ + Class QUERY_PARAM_ANNOTATION_CLASS = resolveClass(QUERY_PARAM_ANNOTATION_CLASS_NAME, getClassLoader()); + + /** + * The annotation class of @Body + */ + Class REST_EASY_BODY_ANNOTATION_CLASS = resolveClass(REST_EASY_BODY_ANNOTATION_CLASS_NAME, getClassLoader()); + + /** + * The annotation class of @PathParam + */ + Class PATH_PARAM_ANNOTATION_CLASS = resolveClass(PATH_PARAM_ANNOTATION_CLASS_NAME, getClassLoader()); + + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/NoAnnotatedParameterRequestTagProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/NoAnnotatedParameterRequestTagProcessor.java new file mode 100644 index 0000000000..70f673c7e7 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/NoAnnotatedParameterRequestTagProcessor.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest; + +import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.metadata.rest.media.MediaType; + +import java.lang.reflect.Parameter; + +@SPI(scope = ExtensionScope.FRAMEWORK) +public interface NoAnnotatedParameterRequestTagProcessor { + MediaType consumerContentType(); + + String defaultAnnotationClassName(RestMethodMetadata restMethodMetadata); + + void process(Parameter parameter, int parameterIndex, RestMethodMetadata restMethodMetadata); +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java new file mode 100644 index 0000000000..f517794d63 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java @@ -0,0 +1,97 @@ +/* + * 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.metadata.rest; + +import org.apache.dubbo.metadata.MetadataConstants; +import org.apache.dubbo.metadata.rest.tag.BodyTag; + +import java.util.ArrayList; +import java.util.List; + +public enum ParamType { + HEADER(addSupportTypes(JAXRSClassConstants.HEADER_PARAM_ANNOTATION_CLASS, + SpringMvcClassConstants.REQUEST_HEADER_ANNOTATION_CLASS)), + + PARAM(addSupportTypes(JAXRSClassConstants.QUERY_PARAM_ANNOTATION_CLASS, + SpringMvcClassConstants.REQUEST_PARAM_ANNOTATION_CLASS)), + + BODY(addSupportTypes( + JAXRSClassConstants.REST_EASY_BODY_ANNOTATION_CLASS, + SpringMvcClassConstants.REQUEST_BODY_ANNOTATION_CLASS, BodyTag.class)), + // TODO how to match arg type ? + REQ_OR_RES(addSupportTypes(MetadataConstants.JAKARTA_SERVLET_REQ_CLASS, + MetadataConstants.JAKARTA_SERVLET_RES_CLASS, + MetadataConstants.JAVAX_SERVLET_REQ_CLASS, + MetadataConstants.JAKARTA_SERVLET_RES_CLASS)), + + PATH(addSupportTypes(JAXRSClassConstants.PATH_PARAM_ANNOTATION_CLASS, + SpringMvcClassConstants.PATH_VARIABLE_ANNOTATION_CLASS)), + + FORM(addSupportTypes(JAXRSClassConstants.FORM_PARAM_ANNOTATION_CLASS)), + + EMPTY(addSupportTypes()); + private List annotationClasses; + + + ParamType(List annotationClasses) { + this.annotationClasses = annotationClasses; + } + + + public boolean supportAnno(Class anno) { + if (anno == null) { + return false; + } + return this.annotationClasses.contains(anno); + } + + public boolean isReqOrRes(Class clazz) { + for (Class annotationClass : annotationClasses) { + if (annotationClass.isAssignableFrom(clazz)) { + return true; + } + } + + return false; + } + + /** + * exclude null types + * + * @param classes + * @return + */ + private static List addSupportTypes(Class... classes) { + + ArrayList types = new ArrayList<>(); + + for (Class clazz : classes) { + + if (clazz == null) { + continue; + } + + types.add(clazz); + } + + return types; + + + } + + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java new file mode 100644 index 0000000000..6e7dcdcbe9 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathMatcher.java @@ -0,0 +1,146 @@ +/* + * 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.metadata.rest; + + +import java.util.Objects; + +public class PathMatcher { + private static final String SEPARATOR = "/"; + private String path; + private String version; + private String group; + private Integer port; + private String[] pathSplits; + private boolean hasPathVariable; + + + public PathMatcher(String path) { + this(path, null, null, 0); + } + + public PathMatcher(String path, String version, String group, Integer port) { + this.path = path; + this.pathSplits = path.split(SEPARATOR); + + for (String pathSplit : pathSplits) { + + if (isPlaceHold(pathSplit)) { + hasPathVariable = true; + break; + } + } + this.version = version; + this.group = group; + this.port = port; + } + + public void setPath(String path) { + this.path = path; + } + + public void setVersion(String version) { + this.version = version; + } + + public void setGroup(String group) { + this.group = group; + } + + public void setPort(Integer port) { + this.port = port; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PathMatcher that = (PathMatcher) o; + return pathEqual(that.path) && Objects.equals(version, that.version) + && Objects.equals(group, that.group) && Objects.equals(port, that.port); + } + + @Override + public int hashCode() { + return Objects.hash(version, group, port); + } + + private boolean pathEqual(String path) { + + // no place hold + if (!hasPathVariable) { + return this.path.equals(path); + } + + String[] split = path.split(SEPARATOR); + + + if (split.length != pathSplits.length) { + return false; + } + + for (int i = 0; i < pathSplits.length; i++) { + boolean equals = split[i].equals(pathSplits[i]); + if (equals) { + continue; + } else { + if (placeHoldCompare(pathSplits[i])) { + continue; + } else { + return false; + } + } + } + + return true; + + } + + private boolean placeHoldCompare(String pathSplit) { + boolean startAndEndEqual = isPlaceHold(pathSplit); + + // start { end } + if (!startAndEndEqual) { + return false; + } + + // exclude {} + boolean lengthCondition = pathSplit.length() >= 3; + + if (!lengthCondition) { + return false; + } + + return true; + } + + private boolean isPlaceHold(String pathSplit) { + return pathSplit.startsWith("{") && pathSplit.endsWith("}"); + } + + + @Override + public String toString() { + return "PathMather{" + + "path='" + path + '\'' + + ", version='" + version + '\'' + + ", group='" + group + '\'' + + ", port='" + port + '\'' + + '}'; + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathUtil.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathUtil.java new file mode 100644 index 0000000000..f105461268 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/PathUtil.java @@ -0,0 +1,157 @@ +/* + * 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.metadata.rest; + + +import org.apache.dubbo.metadata.MetadataConstants; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * is used to parse url pathVariable + *

+ * String[] splits= url.split("/") + * List strings = Arrays.asList(split); + * strings.set(UrlSplitIndex, (String) args.get(argIndex)); + */ +public class PathUtil { + private static final String SEPARATOR = MetadataConstants.PATH_SEPARATOR; + + /** + * generate real path from rawPath according to argInfo and method args + * + * @param rawPath + * @param argInfos + * @param args + * @return + */ + public static String resolvePathVariable(String rawPath, List argInfos, List args) { + + String[] split = rawPath.split(SEPARATOR); + + List strings = Arrays.asList(split); + + List pathArgInfos = new ArrayList<>(); + + for (ArgInfo argInfo : argInfos) { + if (ParamType.PATH.supportAnno(argInfo.getParamAnnotationType())) { + pathArgInfos.add(argInfo); + } + } + + + for (ArgInfo pathArgInfo : pathArgInfos) { + strings.set(pathArgInfo.getUrlSplitIndex(), String.valueOf(args.get(pathArgInfo.getIndex()))); + } + + + String pat = SEPARATOR; + + for (String string : strings) { + + if (string.length() == 0) { + continue; + } + + pat = pat + string + SEPARATOR; + } + + if (pat.endsWith(SEPARATOR)) { + pat = pat.substring(0, pat.lastIndexOf(SEPARATOR)); + } + + return pat; + + } + + + /** + * parse pathVariable index from url by annotation info + * + * @param rawPath + * @param argInfos + */ + public static void setArgInfoSplitIndex(String rawPath, List argInfos) { + String[] split = rawPath.split(SEPARATOR); + + List pathPairs = new ArrayList<>(); + + for (ArgInfo argInfo : argInfos) { + if (ParamType.PATH.supportAnno(argInfo.getParamAnnotationType())) { + pathPairs.add(new PathPair(argInfo)); + } + } + + for (int i = 0; i < split.length; i++) { + String s = split[i]; + for (PathPair pathPair : pathPairs) { + boolean match = pathPair.match(s); + if (match) { + pathPair.setArgInfoSplitIndex(i); + } + } + } + + } + + public static class PathPair { + + String value; + + ArgInfo argInfo; + + + public PathPair(ArgInfo argInfo) { + this.argInfo = argInfo; + this.value = argInfo.getAnnotationNameAttribute(); + } + + public String getPatten() { + return "{" + value + "}"; + } + + public String getLeftPatten() { + return "{" + value; + } + + public String getRightPatten() { + return "}"; + } + + public boolean match(String value) { + return getPatten().equals(value)// for : {id} + || (value.startsWith(getLeftPatten()) && value.endsWith(getRightPatten()));// for : {id: \d+} + } + + + public String getValue() { + return value; + } + + public void setArgInfo(ArgInfo argInfo) { + this.argInfo = argInfo; + } + + public void setArgInfoSplitIndex(int urlSplitIndex) { + this.argInfo.setUrlSplitIndex(urlSplitIndex); + } + } +} + + diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java index 9a9983e4e8..77d2d4d2bb 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java @@ -55,6 +55,7 @@ public class RequestMetadata implements Serializable { private Set produces = new LinkedHashSet<>(); + /** * Default Constructor */ @@ -202,12 +203,12 @@ public class RequestMetadata implements Serializable { } RequestMetadata that = (RequestMetadata) o; return Objects.equals(method, that.method) - && Objects.equals(path, that.path) - && Objects.equals(consumes, that.consumes) - && Objects.equals(produces, that.produces) && - // Metadata should not compare the values - Objects.equals(getParamNames(), that.getParamNames()) - && Objects.equals(getHeaderNames(), that.getHeaderNames()); + && Objects.equals(path, that.path) + && Objects.equals(consumes, that.consumes) + && Objects.equals(produces, that.produces) && + // Metadata should not compare the values + Objects.equals(getParamNames(), that.getParamNames()) + && Objects.equals(getHeaderNames(), that.getHeaderNames()); } @@ -215,13 +216,13 @@ public class RequestMetadata implements Serializable { public int hashCode() { // The values of metadata should not use for the hashCode() method return Objects.hash(method, path, consumes, produces, getParamNames(), - getHeaderNames()); + getHeaderNames()); } @Override public String toString() { return "RequestMetadata{" + "method='" + method + '\'' + ", path='" + path + '\'' - + ", params=" + params + ", headers=" + headers + ", consumes=" + consumes - + ", produces=" + produces + '}'; + + ", params=" + params + ", headers=" + headers + ", consumes=" + consumes + + ", produces=" + produces + '}'; } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java index 6c758bf23b..b96234d764 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java @@ -87,6 +87,16 @@ public interface RestMetadataConstants { * The annotation class name of @QueryParam */ String QUERY_PARAM_ANNOTATION_CLASS_NAME = "javax.ws.rs.QueryParam"; + + /** + * The annotation class name of @Body + */ + String REST_EASY_BODY_ANNOTATION_CLASS_NAME = "org.jboss.resteasy.annotations.Body"; + + /** + * The annotation class name of @PathParam + */ + String PATH_PARAM_ANNOTATION_CLASS_NAME = "javax.ws.rs.PathParam"; } /** @@ -114,6 +124,16 @@ public interface RestMetadataConstants { */ String REQUEST_PARAM_ANNOTATION_CLASS_NAME = "org.springframework.web.bind.annotation.RequestParam"; + /** + * The annotation class name of @RequestBody + */ + String REQUEST_BODY_ANNOTATION_CLASS_NAME = "org.springframework.web.bind.annotation.RequestBody"; + + /** + * The annotation class name of @PathVariable + */ + String PATH_VARIABLE_ANNOTATION_CLASS_NAME = "org.springframework.web.bind.annotation.PathVariable"; + /** * The class of @Controller * diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMethodMetadata.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMethodMetadata.java index 1531c973fd..a2c718c563 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMethodMetadata.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMethodMetadata.java @@ -19,9 +19,10 @@ package org.apache.dubbo.metadata.rest; import org.apache.dubbo.metadata.definition.model.MethodDefinition; import java.io.Serializable; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -56,6 +57,17 @@ public class RestMethodMetadata implements Serializable { private Map indexToEncoded; + private ServiceRestMetadata serviceRestMetadata; + + private List argInfos; + + private Method reflectMethod; + + /** + * make a distinction between mvc & resteasy + */ + private Class codeStyle; + public MethodDefinition getMethod() { if (method == null) { method = new MethodDefinition(); @@ -112,7 +124,7 @@ public class RestMethodMetadata implements Serializable { public Map> getIndexToName() { if (indexToName == null) { - indexToName = new HashMap<>(); + indexToName = new LinkedHashMap<>(); } return indexToName; } @@ -157,6 +169,43 @@ public class RestMethodMetadata implements Serializable { this.indexToEncoded = indexToEncoded; } + + public ServiceRestMetadata getServiceRestMetadata() { + return serviceRestMetadata; + } + + public void setServiceRestMetadata(ServiceRestMetadata serviceRestMetadata) { + this.serviceRestMetadata = serviceRestMetadata; + } + + public List getArgInfos() { + if (argInfos == null) { + argInfos = new ArrayList<>(); + } + return argInfos; + } + + public void addArgInfo(ArgInfo argInfo) { + getArgInfos().add(argInfo); + } + + + public Method getReflectMethod() { + return reflectMethod; + } + + public void setReflectMethod(Method reflectMethod) { + this.reflectMethod = reflectMethod; + } + + public Class getCodeStyle() { + return codeStyle; + } + + public void setCodeStyle(Class codeStyle) { + this.codeStyle = codeStyle; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -167,13 +216,13 @@ public class RestMethodMetadata implements Serializable { } RestMethodMetadata that = (RestMethodMetadata) o; return Objects.equals(getMethod(), that.getMethod()) && - Objects.equals(getRequest(), that.getRequest()) && - Objects.equals(getUrlIndex(), that.getUrlIndex()) && - Objects.equals(getBodyIndex(), that.getBodyIndex()) && - Objects.equals(getHeaderMapIndex(), that.getHeaderMapIndex()) && - Objects.equals(getBodyType(), that.getBodyType()) && - Objects.equals(getFormParams(), that.getFormParams()) && - Objects.equals(getIndexToEncoded(), that.getIndexToEncoded()); + Objects.equals(getRequest(), that.getRequest()) && + Objects.equals(getUrlIndex(), that.getUrlIndex()) && + Objects.equals(getBodyIndex(), that.getBodyIndex()) && + Objects.equals(getHeaderMapIndex(), that.getHeaderMapIndex()) && + Objects.equals(getBodyType(), that.getBodyType()) && + Objects.equals(getFormParams(), that.getFormParams()) && + Objects.equals(getIndexToEncoded(), that.getIndexToEncoded()); } @Override diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java index df396b0d70..19f0aab77b 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java @@ -16,8 +16,12 @@ */ package org.apache.dubbo.metadata.rest; +import org.apache.dubbo.metadata.ParameterTypesComparator; + import java.io.Serializable; +import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Objects; import java.util.Set; @@ -39,6 +43,32 @@ public class ServiceRestMetadata implements Serializable { private Set meta; + private Integer port; + + private boolean consumer; + + /** + * make a distinction between mvc & resteasy + */ + private Class codeStyle; + + private Map pathToServiceMap = new HashMap<>(); + private Map> methodToServiceMap = new HashMap<>(); + + public ServiceRestMetadata(String serviceInterface, String version, String group, boolean consumer) { + this.serviceInterface = serviceInterface; + this.version = version; + this.group = group; + this.consumer = consumer; + } + + public ServiceRestMetadata() { + } + + public ServiceRestMetadata(String serviceInterface, String version, String group) { + this(serviceInterface, version, group, false); + } + public String getServiceInterface() { return serviceInterface; } @@ -74,6 +104,70 @@ public class ServiceRestMetadata implements Serializable { this.meta = meta; } + public void addRestMethodMetadata(RestMethodMetadata restMethodMetadata) { + restMethodMetadata.setServiceRestMetadata(this); + PathMatcher pathMather = new PathMatcher(restMethodMetadata.getRequest().getPath(), + this.getVersion(), this.getGroup(), this.getPort()); + addPathToServiceMap(pathMather, restMethodMetadata); + addMethodToServiceMap(restMethodMetadata); + getMeta().add(restMethodMetadata); + } + + public Map getPathToServiceMap() { + return pathToServiceMap; + } + + public void addPathToServiceMap(PathMatcher pathMather, RestMethodMetadata restMethodMetadata) { + if (this.pathToServiceMap == null) { + this.pathToServiceMap = new HashMap<>(); + } + + this.pathToServiceMap.put(pathMather, restMethodMetadata); + + + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + Map pathToServiceMap = getPathToServiceMap(); + for (PathMatcher pathMather : pathToServiceMap.keySet()) { + pathMather.setPort(port); + } + } + + public boolean isConsumer() { + return consumer; + } + + public void setConsumer(boolean consumer) { + this.consumer = consumer; + } + + public Map> getMethodToServiceMap() { + return methodToServiceMap; + } + + public void addMethodToServiceMap(RestMethodMetadata restMethodMetadata) { + if (this.methodToServiceMap == null) { + this.methodToServiceMap = new HashMap<>(); + } + + this.methodToServiceMap.computeIfAbsent(restMethodMetadata.getReflectMethod().getName(), k -> new HashMap<>()) + .put(ParameterTypesComparator.getInstance(restMethodMetadata.getReflectMethod().getParameterTypes()), restMethodMetadata); + } + + public Class getCodeStyle() { + return codeStyle; + } + + public void setCodeStyle(Class codeStyle) { + this.codeStyle = codeStyle; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -84,14 +178,15 @@ public class ServiceRestMetadata implements Serializable { } ServiceRestMetadata that = (ServiceRestMetadata) o; return Objects.equals(getServiceInterface(), that.getServiceInterface()) && - Objects.equals(getVersion(), that.getVersion()) && - Objects.equals(getGroup(), that.getGroup()) && - Objects.equals(getMeta(), that.getMeta()); + Objects.equals(getVersion(), that.getVersion()) && + Objects.equals(getGroup(), that.getGroup()) && + Objects.equals(getMeta(), that.getMeta()) && + Objects.equals(getPort(), that.getPort()); } @Override public int hashCode() { - return Objects.hash(getServiceInterface(), getVersion(), getGroup(), getMeta()); + return Objects.hash(getServiceInterface(), getVersion(), getGroup(), getMeta(), getPort()); } @Override @@ -101,6 +196,7 @@ public class ServiceRestMetadata implements Serializable { sb.append(", version='").append(version).append('\''); sb.append(", group='").append(group).append('\''); sb.append(", meta=").append(meta); + sb.append(", port=").append(port); sb.append('}'); return sb.toString(); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadataResolver.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadataResolver.java index 41ea25d999..492dc942fb 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadataResolver.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadataResolver.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.metadata.rest; +import org.apache.dubbo.common.extension.ExtensionScope; import org.apache.dubbo.common.extension.SPI; /** @@ -24,7 +25,7 @@ import org.apache.dubbo.common.extension.SPI; * * @since 2.7.6 */ -@SPI +@SPI(scope = ExtensionScope.APPLICATION) public interface ServiceRestMetadataResolver { /** @@ -35,6 +36,8 @@ public interface ServiceRestMetadataResolver { */ boolean supports(Class serviceType); + boolean supports(Class serviceType,boolean consumer); + /** * Resolve the {@link ServiceRestMetadata REST metadata} from the specified * Dubbo Service interface or type @@ -43,4 +46,6 @@ public interface ServiceRestMetadataResolver { * @return */ ServiceRestMetadata resolve(Class serviceType); + + ServiceRestMetadata resolve(Class serviceType, ServiceRestMetadata serviceRestMetadata); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/SpringMvcClassConstants.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/SpringMvcClassConstants.java new file mode 100644 index 0000000000..bd3cabf4db --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/SpringMvcClassConstants.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest; + +import static org.apache.dubbo.common.utils.ClassUtils.getClassLoader; +import static org.apache.dubbo.common.utils.ClassUtils.resolveClass; + +public interface SpringMvcClassConstants extends RestMetadataConstants.SPRING_MVC { + /** + * The annotation class of @RequestMapping + */ + Class REQUEST_MAPPING_ANNOTATION_CLASS = resolveClass(REQUEST_MAPPING_ANNOTATION_CLASS_NAME, getClassLoader()); + + + /** + * The annotation class of @RequestHeader + */ + Class REQUEST_HEADER_ANNOTATION_CLASS = resolveClass(REQUEST_HEADER_ANNOTATION_CLASS_NAME, getClassLoader()); + + + /** + * The annotation class of @RequestParam + */ + Class REQUEST_PARAM_ANNOTATION_CLASS = resolveClass(REQUEST_PARAM_ANNOTATION_CLASS_NAME, getClassLoader()); + + + /** + * The annotation class of @RequestBody + */ + Class REQUEST_BODY_ANNOTATION_CLASS = resolveClass(REQUEST_BODY_ANNOTATION_CLASS_NAME, getClassLoader()); + + + /** + * The annotation class of @RequestBody + */ + Class PATH_VARIABLE_ANNOTATION_CLASS= resolveClass(PATH_VARIABLE_ANNOTATION_CLASS_NAME, getClassLoader()); +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/BodyParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/BodyParameterProcessor.java new file mode 100644 index 0000000000..9889553470 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/BodyParameterProcessor.java @@ -0,0 +1,52 @@ +/* + * 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.metadata.rest.jaxrs; + +import org.apache.dubbo.metadata.rest.AbstractAnnotatedMethodParameterProcessor; +import org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor; +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.REST_EASY_BODY_ANNOTATION_CLASS_NAME; + +/** + * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @FormParam + * + * @since 2.7.6 + */ +public class BodyParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { + + @Override + public String getAnnotationName() { + return REST_EASY_BODY_ANNOTATION_CLASS_NAME; + } + + @Override + public void process(Annotation annotation, Parameter parameter, int parameterIndex, Method method, Class serviceType, Class serviceInterfaceClass, RestMethodMetadata restMethodMetadata) { + ArgInfo argInfo = ArgInfo. + build(parameterIndex, parameter). + setParamAnnotationType(getAnnotationClass()); + restMethodMetadata.addArgInfo(argInfo); + + } + + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java index a3bfe8d4ba..475fbe9cd1 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/DefaultValueParameterProcessor.java @@ -23,6 +23,7 @@ import org.apache.dubbo.metadata.rest.RestMethodMetadata; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import java.util.List; import java.util.Map; @@ -38,12 +39,12 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.DEFAUL public class DefaultValueParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { @Override - public String getAnnotationType() { + public String getAnnotationName() { return DEFAULT_VALUE_ANNOTATION_CLASS_NAME; } @Override - protected void process(String annotationValue, String defaultValue, Annotation annotation, Object parameter, + protected void process(String annotationValue, String defaultValue, Annotation annotation, Parameter parameter, int parameterIndex, Method method, RestMethodMetadata restMethodMetadata) { RequestMetadata requestMetadata = restMethodMetadata.getRequest(); diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/FormParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/FormParamParameterProcessor.java index d102e397b7..6dae712118 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/FormParamParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/FormParamParameterProcessor.java @@ -28,7 +28,7 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.FORM_P public class FormParamParameterProcessor extends ParamAnnotationParameterProcessor { @Override - public String getAnnotationType() { + public String getAnnotationName() { return FORM_PARAM_ANNOTATION_CLASS_NAME; } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/HeaderParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/HeaderParamParameterProcessor.java index 16d21bfd3b..216f1091f2 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/HeaderParamParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/HeaderParamParameterProcessor.java @@ -23,6 +23,7 @@ import org.apache.dubbo.metadata.rest.RestMethodMetadata; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import static org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor.buildDefaultValue; import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.HEADER_PARAM_ANNOTATION_CLASS_NAME; @@ -35,12 +36,12 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.HEADER public class HeaderParamParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { @Override - public String getAnnotationType() { + public String getAnnotationName() { return HEADER_PARAM_ANNOTATION_CLASS_NAME; } @Override - protected void process(String headerName, String defaultValue, Annotation annotation, Object parameter, + protected void process(String headerName, String defaultValue, Annotation annotation, Parameter parameter, int parameterIndex, Method method, RestMethodMetadata restMethodMetadata) { RequestMetadata requestMetadata = restMethodMetadata.getRequest(); // Add the placeholder as header value diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolver.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolver.java index 35df2e7a7a..1e107edc22 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolver.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolver.java @@ -85,12 +85,16 @@ public class JAXRSServiceRestMetadataResolver extends AbstractServiceRestMetadat protected void processProduces(Method serviceMethod, Class serviceType, Class serviceInterfaceClass, Set produces) { addAnnotationValues(serviceMethod, PRODUCES_ANNOTATION_CLASS_NAME, produces); + addAnnotationValues(serviceType, PRODUCES_ANNOTATION_CLASS_NAME, produces); + addAnnotationValues(serviceInterfaceClass, PRODUCES_ANNOTATION_CLASS_NAME, produces); } @Override protected void processConsumes(Method serviceMethod, Class serviceType, Class serviceInterfaceClass, Set consumes) { addAnnotationValues(serviceMethod, CONSUMES_ANNOTATION_CLASS_NAME, consumes); + addAnnotationValues(serviceType, CONSUMES_ANNOTATION_CLASS_NAME, consumes); + addAnnotationValues(serviceInterfaceClass, CONSUMES_ANNOTATION_CLASS_NAME, consumes); } private void addAnnotationValues(Method serviceMethod, String annotationAttributeName, Set result) { @@ -100,4 +104,12 @@ public class JAXRSServiceRestMetadataResolver extends AbstractServiceRestMetadat Stream.of(value).forEach(result::add); } } + + private void addAnnotationValues(Class serviceType, String annotationAttributeName, Set result) { + Annotation annotation = findAnnotation(serviceType, annotationAttributeName); + String[] value = getValue(annotation); + if (value != null) { + Stream.of(value).forEach(result::add); + } + } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/MatrixParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/MatrixParamParameterProcessor.java index 894f33db2a..a75284a689 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/MatrixParamParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/MatrixParamParameterProcessor.java @@ -28,7 +28,7 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.MATRIX public class MatrixParamParameterProcessor extends ParamAnnotationParameterProcessor { @Override - public String getAnnotationType() { + public String getAnnotationName() { return MATRIX_PARAM_ANNOTATION_CLASS_NAME; } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/ParamAnnotationParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/ParamAnnotationParameterProcessor.java index b6be293e16..d7dd5c05c9 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/ParamAnnotationParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/ParamAnnotationParameterProcessor.java @@ -23,6 +23,7 @@ import org.apache.dubbo.metadata.rest.RestMethodMetadata; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; /** * The abstract {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @*Param @@ -30,7 +31,7 @@ import java.lang.reflect.Method; public abstract class ParamAnnotationParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { @Override - protected void process(String name, String defaultValue, Annotation annotation, Object parameter, + protected void process(String name, String defaultValue, Annotation annotation, Parameter parameter, int parameterIndex, Method method, RestMethodMetadata restMethodMetadata) { RequestMetadata requestMetadata = restMethodMetadata.getRequest(); requestMetadata.addParam(name, defaultValue); diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/PathParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/PathParamParameterProcessor.java new file mode 100644 index 0000000000..3ab3b8591d --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/PathParamParameterProcessor.java @@ -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.metadata.rest.jaxrs; + +import org.apache.dubbo.metadata.rest.AbstractAnnotatedMethodParameterProcessor; +import org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.PATH_PARAM_ANNOTATION_CLASS_NAME; + +/** + * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @PathParam + * + * @since 2.7.6 + */ +public class PathParamParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { + + @Override + public String getAnnotationName() { + return PATH_PARAM_ANNOTATION_CLASS_NAME; + } + + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/QueryParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/QueryParamParameterProcessor.java index bfe539c9cc..ed6972f17a 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/QueryParamParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/QueryParamParameterProcessor.java @@ -28,7 +28,7 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.QUERY_ public class QueryParamParameterProcessor extends ParamAnnotationParameterProcessor { @Override - public String getAnnotationType() { + public String getAnnotationName() { return QUERY_PARAM_ANNOTATION_CLASS_NAME; } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/media/MediaType.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/media/MediaType.java new file mode 100644 index 0000000000..8b5c96e405 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/media/MediaType.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.media; + + +public enum MediaType { + ALL_VALUE("*/*"), + APPLICATION_JSON_VALUE("application/json"), + APPLICATION_FORM_URLENCODED_VALUE("application/x-www-form-urlencoded"), + TEXT_PLAIN("text/plain"), + TEXT_XML("text/xml"), + OCTET_STREAM("application/octet-stream"), + ; + + MediaType(String value) { + this.value = value; + } + + public String value; + + public static String getAllContentType() { + + MediaType[] values = MediaType.values(); + + StringBuilder stringBuilder = new StringBuilder(); + + for (MediaType mediaType : values) { + stringBuilder.append(mediaType.value + " "); + } + return stringBuilder.toString(); + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/FormBodyNoAnnotatedProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/FormBodyNoAnnotatedProcessor.java new file mode 100644 index 0000000000..60bcbc9265 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/FormBodyNoAnnotatedProcessor.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.springmvc; + +import org.apache.dubbo.metadata.rest.AbstractNoAnnotatedParameterProcessor; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.metadata.rest.media.MediaType; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_BODY_ANNOTATION_CLASS_NAME; +import static org.apache.dubbo.metadata.rest.media.MediaType.APPLICATION_FORM_URLENCODED_VALUE; + +public class FormBodyNoAnnotatedProcessor extends AbstractNoAnnotatedParameterProcessor { + @Override + public MediaType consumerContentType() { + return APPLICATION_FORM_URLENCODED_VALUE; + } + + @Override + public String defaultAnnotationClassName(RestMethodMetadata restMethodMetadata) { + return REQUEST_BODY_ANNOTATION_CLASS_NAME; + } + + @Override + protected boolean isFormContentType(RestMethodMetadata restMethodMetadata) { + return true; + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/JsonBodyNoAnnotatedProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/JsonBodyNoAnnotatedProcessor.java new file mode 100644 index 0000000000..7fc55d5538 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/JsonBodyNoAnnotatedProcessor.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.springmvc; + +import org.apache.dubbo.metadata.rest.AbstractNoAnnotatedParameterProcessor; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.metadata.rest.media.MediaType; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_BODY_ANNOTATION_CLASS_NAME; +import static org.apache.dubbo.metadata.rest.media.MediaType.APPLICATION_JSON_VALUE; + +public class JsonBodyNoAnnotatedProcessor extends AbstractNoAnnotatedParameterProcessor { + @Override + public MediaType consumerContentType() { + return APPLICATION_JSON_VALUE; + } + + @Override + public String defaultAnnotationClassName(RestMethodMetadata restMethodMetadata) { + return REQUEST_BODY_ANNOTATION_CLASS_NAME; + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/ParamNoAnnotatedProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/ParamNoAnnotatedProcessor.java new file mode 100644 index 0000000000..b0591e4886 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/ParamNoAnnotatedProcessor.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.springmvc; + +import org.apache.dubbo.metadata.rest.AbstractNoAnnotatedParameterProcessor; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.metadata.rest.jaxrs.JAXRSServiceRestMetadataResolver; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.metadata.rest.tag.BodyTag; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_PARAM_ANNOTATION_CLASS_NAME; +import static org.apache.dubbo.metadata.rest.media.MediaType.ALL_VALUE; + +public class ParamNoAnnotatedProcessor extends AbstractNoAnnotatedParameterProcessor { + @Override + public MediaType consumerContentType() { + return ALL_VALUE; + } + + @Override + public String defaultAnnotationClassName(RestMethodMetadata restMethodMetadata) { + + if (JAXRSServiceRestMetadataResolver.class.equals(restMethodMetadata.getCodeStyle())) { + return BodyTag.class.getName(); + } + + return REQUEST_PARAM_ANNOTATION_CLASS_NAME; + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/PathVariableParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/PathVariableParameterProcessor.java new file mode 100644 index 0000000000..a1eccd888b --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/PathVariableParameterProcessor.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.springmvc; + +import org.apache.dubbo.metadata.rest.AbstractAnnotatedMethodParameterProcessor; +import org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Parameter; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.PATH_VARIABLE_ANNOTATION_CLASS_NAME; + +/** + * The {@link AnnotatedMethodParameterProcessor} implementation for Spring Web MVC's @PathVariable + */ +public class PathVariableParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { + + @Override + public String getAnnotationName() { + return PATH_VARIABLE_ANNOTATION_CLASS_NAME; + } + + + @Override + protected String getDefaultValue(Annotation annotation, Parameter parameter, int parameterIndex) { + return null; + } +} + diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestBodyParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestBodyParameterProcessor.java new file mode 100644 index 0000000000..0c93615e68 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestBodyParameterProcessor.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.springmvc; + +import org.apache.dubbo.metadata.rest.AbstractAnnotatedMethodParameterProcessor; +import org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Parameter; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_BODY_ANNOTATION_CLASS_NAME; + +/** + * The {@link AnnotatedMethodParameterProcessor} implementation for Spring Web MVC's @RequestBody + */ +public class RequestBodyParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { + + @Override + public String getAnnotationName() { + return REQUEST_BODY_ANNOTATION_CLASS_NAME; + } + + @Override + protected String getAnnotationValue(Annotation annotation, Parameter parameter, int parameterIndex) { + return null; + } + + @Override + protected String getDefaultValue(Annotation annotation, Parameter parameter, int parameterIndex) { + return null; + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestHeaderParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestHeaderParameterProcessor.java index 8d16898462..3eaae48e4f 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestHeaderParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestHeaderParameterProcessor.java @@ -21,6 +21,7 @@ import org.apache.dubbo.metadata.rest.RestMethodMetadata; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_HEADER_ANNOTATION_CLASS_NAME; @@ -30,12 +31,12 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.RE public class RequestHeaderParameterProcessor extends AbstractRequestAnnotationParameterProcessor { @Override - public String getAnnotationType() { + public String getAnnotationName() { return REQUEST_HEADER_ANNOTATION_CLASS_NAME; } @Override - protected void process(String name, String defaultValue, Annotation annotation, Object parameter, + protected void process(String name, String defaultValue, Annotation annotation, Parameter parameter, int parameterIndex, Method method, RestMethodMetadata restMethodMetadata) { restMethodMetadata.getRequest().addHeader(name, defaultValue); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestParamParameterProcessor.java index 5ae4727f3b..7549196fe4 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestParamParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/RequestParamParameterProcessor.java @@ -21,6 +21,7 @@ import org.apache.dubbo.metadata.rest.RestMethodMetadata; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_PARAM_ANNOTATION_CLASS_NAME; @@ -30,14 +31,13 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.RE public class RequestParamParameterProcessor extends AbstractRequestAnnotationParameterProcessor { @Override - public String getAnnotationType() { + public String getAnnotationName() { return REQUEST_PARAM_ANNOTATION_CLASS_NAME; } @Override - protected void process(String name, String defaultValue, Annotation annotation, Object parameter, int parameterIndex, + protected void process(String name, String defaultValue, Annotation annotation, Parameter parameter, int parameterIndex, Method method, RestMethodMetadata restMethodMetadata) { restMethodMetadata.getRequest().addParam(name, defaultValue); - } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolver.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolver.java index bd94509e7a..135696df6a 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolver.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolver.java @@ -89,11 +89,15 @@ public class SpringMvcServiceRestMetadataResolver extends AbstractServiceRestMet @Override protected void processProduces(Method serviceMethod, Class serviceType, Class serviceInterfaceClass, Set produces) { addMediaTypes(serviceMethod, "produces", produces); + addMediaTypes(serviceType, "produces", produces); + addMediaTypes(serviceInterfaceClass, "produces", produces); } @Override protected void processConsumes(Method serviceMethod, Class serviceType, Class serviceInterfaceClass, Set consumes) { addMediaTypes(serviceMethod, "consumes", consumes); + addMediaTypes(serviceType, "consumes", consumes); + addMediaTypes(serviceInterfaceClass, "consumes", consumes); } private String resolveRequestPath(AnnotatedElement annotatedElement) { @@ -124,6 +128,17 @@ public class SpringMvcServiceRestMetadataResolver extends AbstractServiceRestMet } } + private void addMediaTypes(Class serviceType, String annotationAttributeName, Set mediaTypesSet) { + + Annotation mappingAnnotation = getRequestMapping(serviceType); + + String[] mediaTypes = getAttribute(mappingAnnotation, annotationAttributeName); + + if (isNotEmpty(mediaTypes)) { + of(mediaTypes).forEach(mediaTypesSet::add); + } + } + private Annotation getRequestMapping(AnnotatedElement annotatedElement) { // try "@RequestMapping" first Annotation requestMapping = findAnnotation(annotatedElement, REQUEST_MAPPING_ANNOTATION_CLASS); diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/tag/BodyTag.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/tag/BodyTag.java new file mode 100644 index 0000000000..67dd291a8e --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/tag/BodyTag.java @@ -0,0 +1,20 @@ +/* + * 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.metadata.rest.tag; + +public class BodyTag { +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor index bcb620cdbe..c4df3bec14 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor +++ b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor @@ -4,7 +4,11 @@ jax-rs.form-param = org.apache.dubbo.metadata.rest.jaxrs.FormParamParameterProce jax-rs.matrix-param = org.apache.dubbo.metadata.rest.jaxrs.MatrixParamParameterProcessor jax-rs.header-param = org.apache.dubbo.metadata.rest.jaxrs.HeaderParamParameterProcessor jax-rs.default-value-param = org.apache.dubbo.metadata.rest.jaxrs.DefaultValueParameterProcessor +jax-rs.body = org.apache.dubbo.metadata.rest.jaxrs.BodyParameterProcessor +jax-rs.path-param = org.apache.dubbo.metadata.rest.jaxrs.PathParamParameterProcessor # Spring Web MVC's implementations spring-webmvc.request-param = org.apache.dubbo.metadata.rest.springmvc.RequestParamParameterProcessor -spring-webmvc.request-header = org.apache.dubbo.metadata.rest.springmvc.RequestHeaderParameterProcessor \ No newline at end of file +spring-webmvc.request-header = org.apache.dubbo.metadata.rest.springmvc.RequestHeaderParameterProcessor +spring-webmvc.request-body = org.apache.dubbo.metadata.rest.springmvc.RequestBodyParameterProcessor +spring-webmvc.request-path = org.apache.dubbo.metadata.rest.springmvc.PathVariableParameterProcessor diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.NoAnnotatedParameterRequestTagProcessor b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.NoAnnotatedParameterRequestTagProcessor new file mode 100644 index 0000000000..5324f22221 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.NoAnnotatedParameterRequestTagProcessor @@ -0,0 +1,3 @@ +body-form=org.apache.dubbo.metadata.rest.springmvc.FormBodyNoAnnotatedProcessor +body-json=org.apache.dubbo.metadata.rest.springmvc.JsonBodyNoAnnotatedProcessor +param=org.apache.dubbo.metadata.rest.springmvc.ParamNoAnnotatedProcessor diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java new file mode 100644 index 0000000000..e2498c2b95 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PathMatcherTest.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata; + +import org.apache.dubbo.metadata.rest.PathMatcher; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PathMatcherTest { + + @Test + public void testPathMatcher() { + PathMatcher pathMather = new PathMatcher("/a/b/c/{path1}/d/{path2}/e"); + + PathMatcher pathMather1 = new PathMatcher("/a/b/c/1/d/2/e"); + Assertions.assertEquals(true, pathMather.equals(pathMather1)); + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/DefaultRestService.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/DefaultRestService.java index 210952a86b..fd0f36cc62 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/DefaultRestService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/DefaultRestService.java @@ -63,6 +63,21 @@ public class DefaultRestService implements RestService { return null; } + @Override + public void noAnnotationJsonBody(User user) { + + } + + @Override + public void noAnnotationFormBody(User user) { + + } + + @Override + public void noAnnotationParam(String text) { + + } + public User user(User user) { return user; } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/RestService.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/RestService.java index 65d67ab475..60c78cf3ae 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/RestService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/RestService.java @@ -39,4 +39,8 @@ public interface RestService { User requestBodyMap(Map data, String param); Map requestBodyUser(User user); + + void noAnnotationJsonBody(User user); + void noAnnotationFormBody(User user); + void noAnnotationParam(String text); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/SpringRestService.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/SpringRestService.java index c2daf9b104..de26899585 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/SpringRestService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/SpringRestService.java @@ -19,13 +19,13 @@ package org.apache.dubbo.metadata.rest; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; import java.util.HashMap; import java.util.Map; @@ -92,4 +92,22 @@ public class SpringRestService implements RestService { map.put("age", user.getAge()); return map; } + + @PostMapping(value = "/request/body/user/json", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + @Override + public void noAnnotationJsonBody(User user) { + + } + + @PostMapping(value = "/request/body/user/form", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @Override + public void noAnnotationFormBody(User user) { + + } + + @PostMapping(value = "/request/body/user/param") + @Override + public void noAnnotationParam(String text) { + + } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/StandardRestService.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/StandardRestService.java index 684d76fd3b..44ee3514c6 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/StandardRestService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/StandardRestService.java @@ -27,6 +27,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; import java.util.HashMap; import java.util.Map; @@ -104,4 +105,27 @@ public class StandardRestService implements RestService { map.put("age", user.getAge()); return map; } + + @Path("noAnnotationJsonBody/json") + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Override + public void noAnnotationJsonBody(User user) { + + } + + @Path("noAnnotationFormBody/form") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @POST + @Override + public void noAnnotationFormBody(User user) { + + } + + @Path("noAnnotationParam/text") + @POST + @Override + public void noAnnotationParam(String text) { + + } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/AnotherUserRestService.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/AnotherUserRestService.java new file mode 100644 index 0000000000..7afb0fc37a --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/AnotherUserRestService.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.api; + +import org.apache.dubbo.metadata.rest.User; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("u") +@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) +@Produces({MediaType.APPLICATION_JSON}) +public interface AnotherUserRestService { + + @GET + @Path("{id : \\d+}") + User getUser(@PathParam("id") Long id); + + @POST + @Path("register") + String registerUser(User user); + + @GET + @Path("context") + String getContext(); +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestService.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestService.java new file mode 100644 index 0000000000..ec25773e71 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestService.java @@ -0,0 +1,65 @@ +/* + * 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.metadata.rest.api; + +import org.apache.dubbo.metadata.rest.User; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; + +public interface JaxrsRestService { + + @Path("/param") + @Consumes(MediaType.TEXT_PLAIN) + @Produces(MediaType.TEXT_PLAIN) + @GET + String param(@QueryParam("param") String param); + + @Path("/header") + @Consumes(MediaType.TEXT_PLAIN) + @Produces(MediaType.TEXT_PLAIN) + @GET + String header(@HeaderParam("header") String header); + + @Path("/body") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @POST + User body(User user); + + @Path("/multiValue") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.APPLICATION_FORM_URLENCODED) + @POST + MultivaluedMap multiValue(MultivaluedMap map); + + @Path("/pathVariable/{a}") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.APPLICATION_FORM_URLENCODED) + @POST + String pathVariable(@PathParam("a") String a); + + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestServiceImpl.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestServiceImpl.java new file mode 100644 index 0000000000..b38dd83b3b --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/JaxrsRestServiceImpl.java @@ -0,0 +1,50 @@ +/* + * 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.metadata.rest.api; + +import org.apache.dubbo.metadata.rest.User; + +import javax.ws.rs.core.MultivaluedMap; + +public class JaxrsRestServiceImpl implements JaxrsRestService { + + + @Override + public String param(String param) { + return param; + } + + @Override + public String header(String header) { + return header; + } + + @Override + public User body(User user) { + return user; + } + + @Override + public MultivaluedMap multiValue(MultivaluedMap map) { + return map; + } + + @Override + public String pathVariable(String a) { + return a; + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestService.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestService.java new file mode 100644 index 0000000000..00639e8c31 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestService.java @@ -0,0 +1,52 @@ +/* + * 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.metadata.rest.api; + +import org.apache.dubbo.metadata.rest.User; +import org.springframework.http.MediaType; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.PathVariable; + + +@RestController +public interface SpringRestService { + + + @RequestMapping(value = "/param", method = RequestMethod.GET, consumes = MediaType.TEXT_PLAIN_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) + String param(@RequestParam("param") String param); + + @RequestMapping(value = "/header", method = RequestMethod.GET, consumes = MediaType.TEXT_PLAIN_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) + String header(@RequestHeader("header") String header); + + @RequestMapping(value = "/header", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + User body(@RequestBody User user); + + @RequestMapping(value = "/multiValue", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + MultiValueMap multiValue(@RequestBody MultiValueMap map); + + + @RequestMapping(value = "/pathVariable/{a}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + String pathVariable(@PathVariable String a); + + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestServiceImpl.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestServiceImpl.java new file mode 100644 index 0000000000..8262d4fe66 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/api/SpringRestServiceImpl.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.api; + +import org.apache.dubbo.metadata.rest.User; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +public class SpringRestServiceImpl implements SpringRestService { + + + @Override + public String param(String param) { + return param; + } + + @Override + public String header(String header) { + return header; + } + + @Override + public User body(User user) { + return user; + } + + @Override + public MultiValueMap multiValue(MultiValueMap map) { + return map; + } + + @Override + public String pathVariable(String a) { + return a; + } + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java index fe18bbb5c4..98713cfd06 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java @@ -17,16 +17,27 @@ package org.apache.dubbo.metadata.rest.jaxrs; import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.common.utils.JsonUtils; import org.apache.dubbo.metadata.rest.ClassPathServiceRestMetadataReader; import org.apache.dubbo.metadata.rest.DefaultRestService; +import org.apache.dubbo.metadata.rest.PathUtil; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; import org.apache.dubbo.metadata.rest.RestService; import org.apache.dubbo.metadata.rest.ServiceRestMetadata; -import org.apache.dubbo.metadata.rest.SpringRestService; import org.apache.dubbo.metadata.rest.StandardRestService; +import org.apache.dubbo.metadata.rest.api.AnotherUserRestService; +import org.apache.dubbo.metadata.rest.api.JaxrsRestService; +import org.apache.dubbo.metadata.rest.api.JaxrsRestServiceImpl; +import org.apache.dubbo.metadata.rest.api.SpringRestService; import org.apache.dubbo.rpc.model.ApplicationModel; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -42,6 +53,7 @@ class JAXRSServiceRestMetadataResolverTest { private JAXRSServiceRestMetadataResolver instance = new JAXRSServiceRestMetadataResolver(ApplicationModel.defaultModel()); + @Test void testSupports() { // JAX-RS RestService class @@ -57,6 +69,7 @@ class JAXRSServiceRestMetadataResolverTest { } @Test + @Disabled void testResolve() { // Generated by "dubbo-metadata-processor" ClassPathServiceRestMetadataReader reader = new ClassPathServiceRestMetadataReader("META-INF/dubbo/jax-rs-service-rest-metadata.json"); @@ -70,4 +83,75 @@ class JAXRSServiceRestMetadataResolverTest { assertEquals(expectedServiceRestMetadata, serviceRestMetadata); } + + @Test + void testResolves() { + testResolve(JaxrsRestService.class); + testResolve(JaxrsRestServiceImpl.class); + } + + + void testResolve(Class service) { + // Generated by "dubbo-metadata-processor" + + List jsons = Arrays.asList( + + "{\"argInfos\":[{\"annotationNameAttribute\":\"a\",\"defaultValue\":\"{0}\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"javax.ws.rs.PathParam\",\"paramName\":\"a\",\"paramType\":\"java.lang.String\",\"urlSplitIndex\":2}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.jaxrs.JAXRSServiceRestMetadataResolver\",\"indexToName\":{0:[\"a\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"application/x-www-form-urlencoded\"],\"headerNames\":[],\"headers\":{},\"method\":\"POST\",\"paramNames\":[],\"params\":{},\"path\":\"/pathVariable/{a}\",\"produces\":[\"application/x-www-form-urlencoded\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"map\",\"formContentType\":true,\"index\":0,\"paramAnnotationType\":\"org.springframework.web.bind.annotation.RequestBody\",\"paramName\":\"map\",\"paramType\":\"javax.ws.rs.core.MultivaluedMap\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.jaxrs.JAXRSServiceRestMetadataResolver\",\"indexToName\":{0:[\"map\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"application/x-www-form-urlencoded\"],\"headerNames\":[],\"headers\":{},\"method\":\"POST\",\"paramNames\":[],\"params\":{},\"path\":\"/multiValue\",\"produces\":[\"application/x-www-form-urlencoded\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"user\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"org.springframework.web.bind.annotation.RequestBody\",\"paramName\":\"user\",\"paramType\":\"org.apache.dubbo.metadata.rest.User\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.jaxrs.JAXRSServiceRestMetadataResolver\",\"indexToName\":{0:[\"user\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"application/json\"],\"headerNames\":[],\"headers\":{},\"method\":\"POST\",\"paramNames\":[],\"params\":{},\"path\":\"/body\",\"produces\":[\"application/json\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"param\",\"defaultValue\":\"{0}\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"javax.ws.rs.QueryParam\",\"paramName\":\"param\",\"paramType\":\"java.lang.String\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.jaxrs.JAXRSServiceRestMetadataResolver\",\"indexToName\":{0:[\"param\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"text/plain\"],\"headerNames\":[],\"headers\":{},\"method\":\"GET\",\"paramNames\":[\"param\"],\"params\":{\"param\":[\"{0}\"]},\"path\":\"/param\",\"produces\":[\"text/plain\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"header\",\"defaultValue\":\"{0}\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"javax.ws.rs.HeaderParam\",\"paramName\":\"header\",\"paramType\":\"java.lang.String\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.jaxrs.JAXRSServiceRestMetadataResolver\",\"indexToName\":{0:[\"header\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"text/plain\"],\"headerNames\":[\"header\"],\"headers\":{\"header\":[\"{0}\"]},\"method\":\"GET\",\"paramNames\":[],\"params\":{},\"path\":\"/header\",\"produces\":[\"text/plain\"]}}" + + + ); + + ServiceRestMetadata jaxrsRestMetadata = new ServiceRestMetadata(); + jaxrsRestMetadata.setServiceInterface(service.getName()); + ServiceRestMetadata jaxrsMetadata = instance.resolve(service, jaxrsRestMetadata); + + + List jsonsTmp = new ArrayList<>(); + for (RestMethodMetadata restMethodMetadata : jaxrsMetadata.getMeta()) { + restMethodMetadata.setServiceRestMetadata(null); + restMethodMetadata.setReflectMethod(null); + restMethodMetadata.setMethod(null); + jsonsTmp.add(JsonUtils.getJson().toJson(restMethodMetadata)); + } + + Comparator comparator = new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.length() - o2.length(); + } + }; + jsons.sort(comparator); + jsonsTmp.sort(comparator); + + + for (int i = 0; i < jsons.size(); i++) { + assertEquals(jsons.get(i), jsonsTmp.get(i)); + } + + } + + + @Test + public void testJaxrsPathPattern() { + Class service = AnotherUserRestService.class; + ServiceRestMetadata jaxrsRestMetadata = new ServiceRestMetadata(); + jaxrsRestMetadata.setServiceInterface(service.getName()); + ServiceRestMetadata jaxrsMetadata = instance.resolve(service, jaxrsRestMetadata); + + RestMethodMetadata[] objects = jaxrsMetadata.getMeta().toArray(new RestMethodMetadata[0]); + RestMethodMetadata object = null; + for (RestMethodMetadata obj : objects) { + if ("getUser".equals(obj.getReflectMethod().getName())) { + object = obj; + } + } + + + Assertions.assertEquals("/u/1", PathUtil.resolvePathVariable("u/{id : \\d+}", object.getArgInfos(), Arrays.asList(1))); + + } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java index 388030d4d9..b48c77ad1a 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java @@ -17,16 +17,23 @@ package org.apache.dubbo.metadata.rest.springmvc; import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.common.utils.JsonUtils; import org.apache.dubbo.metadata.rest.ClassPathServiceRestMetadataReader; import org.apache.dubbo.metadata.rest.DefaultRestService; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; import org.apache.dubbo.metadata.rest.RestService; import org.apache.dubbo.metadata.rest.ServiceRestMetadata; -import org.apache.dubbo.metadata.rest.SpringRestService; import org.apache.dubbo.metadata.rest.StandardRestService; +import org.apache.dubbo.metadata.rest.api.SpringRestService; +import org.apache.dubbo.metadata.rest.api.SpringRestServiceImpl; import org.apache.dubbo.rpc.model.ApplicationModel; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -45,18 +52,19 @@ class SpringMvcServiceRestMetadataResolverTest { @Test void testSupports() { // Spring MVC RestService class - assertTrue(instance.supports(SpringRestService.class)); + assertTrue(instance.supports(SpringRestService.class, true)); // JAX-RS RestService class - assertFalse(instance.supports(StandardRestService.class)); + assertFalse(instance.supports(StandardRestService.class, true)); // Default RestService class - assertFalse(instance.supports(DefaultRestService.class)); + assertFalse(instance.supports(DefaultRestService.class, true)); // No annotated RestService class - assertFalse(instance.supports(RestService.class)); + assertFalse(instance.supports(RestService.class, true)); // null - assertFalse(instance.supports(null)); + assertFalse(instance.supports(null, true)); } @Test + @Disabled void testResolve() { // Generated by "dubbo-metadata-processor" ClassPathServiceRestMetadataReader reader = new ClassPathServiceRestMetadataReader("META-INF/dubbo/spring-mvc-service-rest-metadata.json"); @@ -70,4 +78,51 @@ class SpringMvcServiceRestMetadataResolverTest { assertEquals(expectedServiceRestMetadata, serviceRestMetadata); } + + @Test + void testResolves() { + testResolve(SpringRestService.class); + testResolve(SpringRestServiceImpl.class); + } + + void testResolve(Class service) { + List jsons = Arrays.asList( + + "{\"argInfos\":[{\"annotationNameAttribute\":\"\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"org.springframework.web.bind.annotation.PathVariable\",\"paramName\":\"a\",\"paramType\":\"java.lang.String\",\"urlSplitIndex\":2}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.springmvc.SpringMvcServiceRestMetadataResolver\",\"indexToName\":{0:[\"a\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"application/x-www-form-urlencoded\"],\"headerNames\":[],\"headers\":{},\"method\":\"POST\",\"paramNames\":[],\"params\":{},\"path\":\"/pathVariable/{a}\",\"produces\":[\"application/x-www-form-urlencoded\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"user\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"org.springframework.web.bind.annotation.RequestBody\",\"paramName\":\"user\",\"paramType\":\"org.apache.dubbo.metadata.rest.User\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.springmvc.SpringMvcServiceRestMetadataResolver\",\"indexToName\":{0:[\"user\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"application/json\"],\"headerNames\":[],\"headers\":{},\"method\":\"POST\",\"paramNames\":[],\"params\":{},\"path\":\"/header\",\"produces\":[\"application/json\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"param\",\"defaultValue\":\"{0}\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"org.springframework.web.bind.annotation.RequestParam\",\"paramName\":\"param\",\"paramType\":\"java.lang.String\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.springmvc.SpringMvcServiceRestMetadataResolver\",\"indexToName\":{0:[\"param\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"text/plain\"],\"headerNames\":[],\"headers\":{},\"method\":\"GET\",\"paramNames\":[\"param\"],\"params\":{\"param\":[\"{0}\"]},\"path\":\"/param\",\"produces\":[\"text/plain\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"map\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"org.springframework.web.bind.annotation.RequestBody\",\"paramName\":\"map\",\"paramType\":\"org.springframework.util.MultiValueMap\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.springmvc.SpringMvcServiceRestMetadataResolver\",\"indexToName\":{0:[\"map\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"application/x-www-form-urlencoded\"],\"headerNames\":[],\"headers\":{},\"method\":\"POST\",\"paramNames\":[],\"params\":{},\"path\":\"/multiValue\",\"produces\":[\"application/x-www-form-urlencoded\"]}}", + "{\"argInfos\":[{\"annotationNameAttribute\":\"header\",\"defaultValue\":\"{0}\",\"formContentType\":false,\"index\":0,\"paramAnnotationType\":\"org.springframework.web.bind.annotation.RequestHeader\",\"paramName\":\"header\",\"paramType\":\"java.lang.String\",\"urlSplitIndex\":0}],\"codeStyle\":\"org.apache.dubbo.metadata.rest.springmvc.SpringMvcServiceRestMetadataResolver\",\"indexToName\":{0:[\"header\"]},\"method\":{\"annotations\":[],\"parameters\":[]},\"request\":{\"consumes\":[\"text/plain\"],\"headerNames\":[\"header\"],\"headers\":{\"header\":[\"{0}\"]},\"method\":\"GET\",\"paramNames\":[],\"params\":{},\"path\":\"/header\",\"produces\":[\"text/plain\"]}}" + + + ); + + ServiceRestMetadata springRestMetadata = new ServiceRestMetadata(); + springRestMetadata.setServiceInterface(service.getName()); + ServiceRestMetadata springMetadata = instance.resolve(service, springRestMetadata); + + + List jsonsTmp = new ArrayList<>(); + for (RestMethodMetadata restMethodMetadata : springMetadata.getMeta()) { + restMethodMetadata.setServiceRestMetadata(null); + restMethodMetadata.setReflectMethod(null); + restMethodMetadata.setMethod(null); + jsonsTmp.add(JsonUtils.getJson().toJson(restMethodMetadata)); + } + + Comparator comparator = new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.length() - o2.length(); + } + }; + jsons.sort(comparator); + jsonsTmp.sort(comparator); + + + for (int i = 0; i < jsons.size(); i++) { + assertEquals(jsons.get(i), jsonsTmp.get(i)); + } + + } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java index ea67b53677..f18115607f 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java @@ -17,12 +17,6 @@ package org.apache.dubbo.metrics.filter; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; @@ -31,13 +25,25 @@ import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; -import org.apache.dubbo.rpc.*; +import org.apache.dubbo.rpc.AppResponse; +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.model.ApplicationModel; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE; import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_PARAMETER_DESC; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java index 4f0dab159b..08186127ec 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java @@ -17,7 +17,6 @@ package org.apache.dubbo.metrics.prometheus; -import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.MetricsConfig; import org.apache.dubbo.config.nested.PrometheusConfig; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java index 90e0cacd3e..7fd82f63ca 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java @@ -18,11 +18,9 @@ package org.apache.dubbo.qos.command; import org.apache.dubbo.qos.command.exception.NoSuchCommandException; -import org.apache.dubbo.qos.command.exception.PermissionDenyException; import org.apache.dubbo.qos.common.QosConfiguration; import org.apache.dubbo.qos.permission.PermissionLevel; import org.apache.dubbo.rpc.model.FrameworkModel; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java index b34928fb41..03adb56fbc 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java @@ -31,9 +31,7 @@ import org.apache.dubbo.config.context.ConfigManager; import org.apache.dubbo.metadata.report.MetadataReport; import org.apache.dubbo.metadata.report.MetadataReportInstance; import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.rpc.model.FrameworkModel; -import org.checkerframework.checker.units.qual.A; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java index d6cd9f6e12..df8e5dcb45 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java @@ -110,9 +110,9 @@ public interface Constants { int DEFAULT_IO_THREADS = Math.min(Runtime.getRuntime().availableProcessors() + 1, 32); - String EVENT_LOOP_BOSS_POOL_NAME = "NettyServerBoss"; + String EVENT_LOOP_BOSS_POOL_NAME = "NettyServerBoss"; - String EVENT_LOOP_WORKER_POOL_NAME = "NettyServerWorker"; + String EVENT_LOOP_WORKER_POOL_NAME = "NettyServerWorker"; String NETTY_EPOLL_ENABLE_KEY = "netty.epoll.enable"; @@ -148,4 +148,14 @@ public interface Constants { String CONNECTIONS_KEY = "connections"; int DEFAULT_BACKLOG = 1024; + + String CONNECTION = "Connection"; + + String KEEP_ALIVE = "keep-alive"; + + String KEEP_ALIVE_HEADER = "Keep-Alive"; + + String OK_HTTP = "ok-http"; + String URL_CONNECTION = "url-connection"; + String APACHE_HTTP_CLIENT = "apache-http-client"; } diff --git a/dubbo-remoting/dubbo-remoting-http/pom.xml b/dubbo-remoting/dubbo-remoting-http/pom.xml index d613bd93be..b2ef9653a4 100644 --- a/dubbo-remoting/dubbo-remoting-http/pom.xml +++ b/dubbo-remoting/dubbo-remoting-http/pom.xml @@ -59,5 +59,23 @@ 4.5.14 test + + + com.squareup.okhttp3 + okhttp + + + + org.apache.dubbo + dubbo-rpc-api + ${project.parent.version} + + + + org.apache.httpcomponents + httpclient + + + - \ No newline at end of file + diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/BaseRestClient.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/BaseRestClient.java new file mode 100644 index 0000000000..d644daf7dd --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/BaseRestClient.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.remoting.http; + + +import org.apache.dubbo.remoting.http.config.HttpClientConfig; + +public abstract class BaseRestClient implements RestClient { + + protected CLIENT client; + + protected HttpClientConfig clientConfig; + + public BaseRestClient(HttpClientConfig clientConfig) { + this.clientConfig = clientConfig; + client = createHttpClient(clientConfig); + } + + protected abstract CLIENT createHttpClient(HttpClientConfig clientConfig); + + + public HttpClientConfig getClientConfig() { + return clientConfig; + } + + public CLIENT getClient() { + return client; + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RequestTemplate.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RequestTemplate.java new file mode 100644 index 0000000000..e5d644c90b --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RequestTemplate.java @@ -0,0 +1,303 @@ +/* + * 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.remoting.http; + + +import org.apache.dubbo.remoting.Constants; +import org.apache.dubbo.rpc.Invocation; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + + +public class RequestTemplate implements Serializable { + private static final long serialVersionUID = 1L; + public static final String CONTENT_ENCODING = "Content-Encoding"; + private static final String CONTENT_LENGTH = "Content-Length"; + public static final String ENCODING_GZIP = "gzip"; + public static final String ENCODING_DEFLATE = "deflate"; + private static final List EMPTY_ARRAYLIST = new ArrayList<>(); + + private final Map> queries = new LinkedHashMap>(); + private final Map> headers = new LinkedHashMap>(); + private String httpMethod; + private String path; + private String address; + private Object body; + private byte[] byteBody = new byte[0]; + private String protocol = "http://"; + private final Invocation invocation; + private String contextPath = ""; + + + public RequestTemplate(Invocation invocation, String httpMethod, String address) { + this(invocation, httpMethod, address, ""); + } + + public RequestTemplate(Invocation invocation, String httpMethod, String address, String contextPath) { + this.httpMethod = httpMethod; + this.address = address; + this.invocation = invocation; + this.contextPath = contextPath; + } + + public String getURL() { + StringBuilder stringBuilder = new StringBuilder(getProtocol() + address); + + stringBuilder.append(getUri()); + return stringBuilder.toString(); + } + + public String getUri() { + StringBuilder stringBuilder = new StringBuilder(getContextPath() + path); + return stringBuilder.append(getQueryString()).toString(); + } + + public String getQueryString() { + + if (queries.isEmpty()) { + return ""; + } + + StringBuilder queryBuilder = new StringBuilder("?"); + for (String field : queries.keySet()) { + + Collection queryValues = queries.get(field); + + if (queryValues == null || queryValues.isEmpty()) { + continue; + } + + for (String value : queryValues) { + queryBuilder.append('&'); + queryBuilder.append(field); + if (value == null) { + continue; + } + + queryBuilder.append('='); + queryBuilder.append(value); + } + } + + return queryBuilder.toString(); + + } + + + public RequestTemplate path(String path) { + this.path = path; + return this; + } + + public String getHttpMethod() { + return httpMethod; + } + + public RequestTemplate httpMethod(String httpMethod) { + this.httpMethod = httpMethod; + return this; + } + + public byte[] getSerializedBody() { + return byteBody; + } + + public void serializeBody(byte[] body) { + addHeader(CONTENT_LENGTH, body.length); // must header + this.byteBody = body; + } + + public boolean isBodyEmpty() { + return getUnSerializedBody() == null; + } + + public RequestTemplate body(Object body) { + this.body = body; + return this; + } + + public Object getUnSerializedBody() { + return body; + } + + public Map> getAllHeaders() { + return headers; + } + + public Collection getHeaders(String name) { + return headers.get(name); + } + + public String getHeader(String name) { + if (headers.containsKey(name)) { + + Collection headers = getHeaders(name); + + if (headers.isEmpty()) { + return null; + } + String[] strings = headers.toArray(new String[0]); + return strings[0]; + + } else { + return null; + } + } + + public Collection getEncodingValues() { + if (headers.containsKey(CONTENT_ENCODING)) { + return headers.get(CONTENT_ENCODING); + } + return EMPTY_ARRAYLIST; + } + + public boolean isGzipEncodedRequest() { + return getEncodingValues().contains(ENCODING_GZIP); + } + + public boolean isDeflateEncodedRequest() { + return getEncodingValues().contains(ENCODING_DEFLATE); + } + + public void addHeader(String key, String value) { + addValueByKey(key, value, this.headers); + } + + public void addHeader(String key, Object value) { + addValueByKey(key, String.valueOf(value), this.headers); + } + + public void addKeepAliveHeader(int time) { + addHeader(Constants.KEEP_ALIVE_HEADER, time); + addHeader(Constants.CONNECTION, Constants.KEEP_ALIVE); + } + + public void addHeaders(String key, Collection values) { + Collection header = getHeaders(key); + + if (header == null) { + header = new HashSet<>(); + this.headers.put(key, header); + } + header.addAll(values); + } + + + public void addParam(String key, String value) { + addValueByKey(key, value, this.queries); + } + + public void addParam(String key, Object value) { + addParam(key, String.valueOf(value)); + } + + public Map> getQueries() { + return queries; + } + + public Collection getParam(String key) { + return getQueries().get(key); + } + + public void addParams(String key, Collection values) { + Collection params = getParam(key); + + if (params == null) { + params = new HashSet<>(); + this.headers.put(key, params); + } + params.addAll(values); + } + + + public void addValueByKey(String key, String value, Map> maps) { + + if (value == null) { + return; + } + + Collection values = null; + if (!maps.containsKey(key)) { + values = new HashSet<>(); + maps.put(key, values); + } + values = maps.get(key); + + + values.add(value); + + } + + + public Integer getContentLength() { + + if (!getAllHeaders().containsKey(CONTENT_LENGTH)) { + return null; + } + + HashSet strings = (HashSet) getAllHeaders().get(CONTENT_LENGTH); + + return Integer.parseInt(new ArrayList<>(strings).get(0)); + + } + + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + addHeader("Host", address);// must header + this.address = address; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public Invocation getInvocation() { + return invocation; + } + + public String getContextPath() { + if (contextPath == null || contextPath.length() == 0) { + return ""; + } + + if (contextPath.startsWith("/")) { + return contextPath; + } else { + return "/" + contextPath; + } + + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestClient.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestClient.java new file mode 100644 index 0000000000..f8827dd2d4 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestClient.java @@ -0,0 +1,50 @@ +/* + * 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.remoting.http; + +import org.apache.dubbo.remoting.RemotingException; + +import java.util.concurrent.CompletableFuture; + + +public interface RestClient { + /** + * send message. + * + * @param message + * @throws RemotingException + */ + CompletableFuture send(RequestTemplate message); + + /** + * close the channel. + */ + void close(); + + /** + * Graceful close the channel. + */ + void close(int timeout); + + /** + * is closed. + * + * @return closed + */ + boolean isClosed(); + +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestResult.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestResult.java new file mode 100644 index 0000000000..1cca829291 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/RestResult.java @@ -0,0 +1,35 @@ +/* + * 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.remoting.http; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public interface RestResult { + String getContentType(); + + byte[] getBody() throws IOException; + + Map> headers(); + + byte[] getErrorResponse() throws IOException; + + int getResponseCode() throws IOException; + + String getMessage() throws IOException; +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/config/HttpClientConfig.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/config/HttpClientConfig.java new file mode 100644 index 0000000000..6e7e49e660 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/config/HttpClientConfig.java @@ -0,0 +1,62 @@ +/* + * 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.remoting.http.config; + +public class HttpClientConfig { + private int readTimeout = 6 * 1000; + private int writeTimeout = 6 * 1000; + private int connectTimeout = 6 * 1000; + private int chunkLength = 8196; + + private int HTTP_CLIENT_CONNECTION_MANAGER_MAX_PER_ROUTE = 20; + private int HTTP_CLIENT_CONNECTION_MANAGER_MAX_TOTAL = 20; + private int HTTPCLIENT_KEEP_ALIVE_DURATION = 30 * 1000; + private int HTTP_CLIENT_CONNECTION_MANAGER_CLOSE_WAIT_TIME_MS = 1000; + private int HTTP_CLIENT_CONNECTION_MANAGER_CLOSE_IDLE_TIME_S = 30; + + + public HttpClientConfig() { + } + + public int getReadTimeout() { + return readTimeout; + } + + public void setReadTimeout(int readTimeout) { + this.readTimeout = readTimeout; + } + + public int getWriteTimeout() { + return writeTimeout; + } + + public void setWriteTimeout(int writeTimeout) { + this.writeTimeout = writeTimeout; + } + + public int getConnectTimeout() { + return connectTimeout; + } + + public void setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public int getChunkLength() { + return chunkLength; + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/AbstractHttpClientFactory.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/AbstractHttpClientFactory.java new file mode 100644 index 0000000000..44936b0d37 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/AbstractHttpClientFactory.java @@ -0,0 +1,87 @@ +/* + * 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. + */ +/* + * 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.remoting.http.factory; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.config.HttpClientConfig; +import org.apache.dubbo.rpc.RpcException; + +/** + * AbstractHttpClientFactory + */ +public abstract class AbstractHttpClientFactory implements RestClientFactory { + + protected final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass()); + + + // TODO load config + protected HttpClientConfig httpClientConfig = new HttpClientConfig(); + + //////////////////////////////////////// implements start /////////////////////////////////////////////// + @Override + public RestClient createRestClient(URL url) throws RpcException { + + beforeCreated(url); + + // create a raw client + RestClient restClient = doCreateRestClient(url); + + // postprocessor + afterCreated(restClient); + + return restClient; + } + + //////////////////////////////////////// implements end /////////////////////////////////////////////// + + + //////////////////////////////////////// inner methods /////////////////////////////////////////////// + + protected void beforeCreated(URL url) { + } + + protected abstract RestClient doCreateRestClient(URL url) throws RpcException; + + protected void afterCreated(RestClient client) { + } + + //////////////////////////////////////// inner methods /////////////////////////////////////////////// + + + + + +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/RestClientFactory.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/RestClientFactory.java new file mode 100644 index 0000000000..ca82b052e5 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/RestClientFactory.java @@ -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.remoting.http.factory; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Adaptive; +import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.remoting.Constants; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.rpc.RpcException; + +/** + * RestClientFactory. (API/SPI, Singleton, ThreadSafe) + */ +@SPI(value = Constants.OK_HTTP, scope = ExtensionScope.FRAMEWORK) +public interface RestClientFactory { + + + @Adaptive({Constants.CLIENT_KEY}) + RestClient createRestClient(URL url) throws RpcException; + + +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/ApacheHttpClientFactory.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/ApacheHttpClientFactory.java new file mode 100644 index 0000000000..08fef6f4ea --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/ApacheHttpClientFactory.java @@ -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.remoting.http.factory.impl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.remoting.Constants; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.factory.AbstractHttpClientFactory; +import org.apache.dubbo.remoting.http.restclient.HttpClientRestClient; +import org.apache.dubbo.rpc.RpcException; + +@Activate(Constants.APACHE_HTTP_CLIENT) +public class ApacheHttpClientFactory extends AbstractHttpClientFactory { + + + @Override + protected RestClient doCreateRestClient(URL url) throws RpcException { + + + return new HttpClientRestClient(httpClientConfig); + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/OkHttpClientFactory.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/OkHttpClientFactory.java new file mode 100644 index 0000000000..87e154c76a --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/OkHttpClientFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.remoting.http.factory.impl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.remoting.Constants; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.factory.AbstractHttpClientFactory; +import org.apache.dubbo.remoting.http.restclient.OKHttpRestClient; +import org.apache.dubbo.rpc.RpcException; + +@Activate(Constants.OK_HTTP) +public class OkHttpClientFactory extends AbstractHttpClientFactory { + + + @Override + protected RestClient doCreateRestClient(URL url) throws RpcException { + + return new OKHttpRestClient(httpClientConfig); + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/URLConnectionClientFactory.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/URLConnectionClientFactory.java new file mode 100644 index 0000000000..94676a091d --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/factory/impl/URLConnectionClientFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.remoting.http.factory.impl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.remoting.Constants; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.factory.AbstractHttpClientFactory; +import org.apache.dubbo.remoting.http.restclient.URLConnectionRestClient; +import org.apache.dubbo.rpc.RpcException; + +@Activate(Constants.URL_CONNECTION) +public class URLConnectionClientFactory extends AbstractHttpClientFactory { + + + @Override + protected RestClient doCreateRestClient(URL url) throws RpcException { + + return new URLConnectionRestClient(httpClientConfig); + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/HttpClientRestClient.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/HttpClientRestClient.java new file mode 100644 index 0000000000..9895eab46a --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/HttpClientRestClient.java @@ -0,0 +1,153 @@ +/* + * 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.remoting.http.restclient; + +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.RestResult; +import org.apache.dubbo.remoting.http.config.HttpClientConfig; + +import org.apache.commons.io.IOUtils; +import org.apache.http.Header; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + + +public class HttpClientRestClient implements RestClient { + private final CloseableHttpClient closeableHttpClient; + private final HttpClientConfig httpClientConfig; + + public HttpClientRestClient(HttpClientConfig clientConfig) { + closeableHttpClient = createHttpClient(); + httpClientConfig = clientConfig; + } + + @Override + public CompletableFuture send(RequestTemplate requestTemplate) { + + HttpRequestBase httpRequest = null; + String httpMethod = requestTemplate.getHttpMethod(); + + if ("GET".equals(httpMethod)) { + httpRequest = new HttpGet(requestTemplate.getURL()); + } else if ("POST".equals(httpMethod)) { + HttpPost httpPost = new HttpPost(requestTemplate.getURL()); + httpPost.setEntity(new ByteArrayEntity(requestTemplate.getSerializedBody())); + httpRequest = httpPost; + } + + Map> allHeaders = requestTemplate.getAllHeaders(); + + allHeaders.remove("Content-Length"); + // header + for (String headerName : allHeaders.keySet()) { + Collection headerValues = allHeaders.get(headerName); + + for (String headerValue : headerValues) { + httpRequest.addHeader(headerName, headerValue); + } + } + + httpRequest.setConfig(getRequestConfig(httpClientConfig)); + + CompletableFuture future = new CompletableFuture<>(); + try { + CloseableHttpResponse response = closeableHttpClient.execute(httpRequest); + future.complete(new RestResult() { + @Override + public String getContentType() { + return response.getFirstHeader("Content-Type").getValue(); + } + + @Override + public byte[] getBody() throws IOException { + return IOUtils.toByteArray(response.getEntity().getContent()); + } + + @Override + public Map> headers() { + return Arrays.stream(response.getAllHeaders()).collect(Collectors.toMap(Header::getName, h -> Collections.singletonList(h.getValue()))); + } + + @Override + public byte[] getErrorResponse() throws IOException { + return getBody(); + } + + @Override + public int getResponseCode() { + return response.getStatusLine().getStatusCode(); + } + + @Override + public String getMessage() throws IOException { + return response.getStatusLine().getReasonPhrase(); + } + }); + } catch (IOException e) { + future.completeExceptionally(e); + } + return future; + } + + private RequestConfig getRequestConfig(HttpClientConfig clientConfig) { + + // TODO config + return RequestConfig.custom().build(); + } + + @Override + public void close() { + try { + closeableHttpClient.close(); + } catch (IOException e) { + + } + } + + @Override + public void close(int timeout) { + + } + + @Override + public boolean isClosed() { + // TODO close judge + return true; + } + + public CloseableHttpClient createHttpClient() { + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); + return HttpClients.custom().setConnectionManager(connectionManager).build(); + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/OKHttpRestClient.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/OKHttpRestClient.java new file mode 100644 index 0000000000..bb98aa32ec --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/OKHttpRestClient.java @@ -0,0 +1,144 @@ +/* + * 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.remoting.http.restclient; + +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.RestResult; +import org.apache.dubbo.remoting.http.config.HttpClientConfig; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.internal.http.HttpMethod; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + + +public class OKHttpRestClient implements RestClient { + private final OkHttpClient okHttpClient; + private final HttpClientConfig httpClientConfig; + + public OKHttpRestClient(HttpClientConfig clientConfig) { + this.okHttpClient = createHttpClient(clientConfig); + this.httpClientConfig = clientConfig; + } + + @Override + public CompletableFuture send(RequestTemplate requestTemplate) { + + Request.Builder builder = new Request.Builder(); + // url + builder.url(requestTemplate.getURL()); + + Map> allHeaders = requestTemplate.getAllHeaders(); + + // header + for (String headerName : allHeaders.keySet()) { + Collection headerValues = allHeaders.get(headerName); + + for (String headerValue : headerValues) { + builder.addHeader(headerName, headerValue); + } + } + RequestBody requestBody = null; + if (HttpMethod.permitsRequestBody(requestTemplate.getHttpMethod())) { + requestBody = RequestBody.create(null, requestTemplate.getSerializedBody()); + } + builder.method(requestTemplate.getHttpMethod(), requestBody); + + CompletableFuture future = new CompletableFuture<>(); + + okHttpClient.newCall(builder.build()).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + future.completeExceptionally(e); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + future.complete(new RestResult() { + @Override + public String getContentType() { + return response.header("Content-Type"); + } + + @Override + public byte[] getBody() throws IOException { + ResponseBody body = response.body(); + return body == null ? null : body.bytes(); + } + + @Override + public Map> headers() { + return response.headers().toMultimap(); + } + + @Override + public byte[] getErrorResponse() throws IOException { + return getBody(); + } + + @Override + public int getResponseCode() throws IOException { + return response.code(); + } + + @Override + public String getMessage() throws IOException { + return response.message(); + } + }); + } + }); + + return future; + } + + @Override + public void close() { + okHttpClient.connectionPool().evictAll(); + } + + @Override + public void close(int timeout) { + + } + + @Override + public boolean isClosed() { + return okHttpClient.retryOnConnectionFailure(); + } + + public OkHttpClient createHttpClient(HttpClientConfig httpClientConfig) { + OkHttpClient client = new OkHttpClient.Builder(). + readTimeout(httpClientConfig.getReadTimeout(), TimeUnit.SECONDS). + writeTimeout(httpClientConfig.getWriteTimeout(), TimeUnit.SECONDS). + connectTimeout(httpClientConfig.getConnectTimeout(), TimeUnit.SECONDS). + build(); + return client; + } +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/URLConnectionRestClient.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/URLConnectionRestClient.java new file mode 100644 index 0000000000..b067228c44 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/org/apache/dubbo/remoting/http/restclient/URLConnectionRestClient.java @@ -0,0 +1,181 @@ +/* + * 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.remoting.http.restclient; + +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.RestResult; +import org.apache.dubbo.remoting.http.config.HttpClientConfig; + +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.GZIPOutputStream; + + +public class URLConnectionRestClient implements RestClient { + private final HttpClientConfig clientConfig; + + public URLConnectionRestClient(HttpClientConfig clientConfig) { + this.clientConfig = clientConfig; + } + + @Override + public CompletableFuture send(RequestTemplate requestTemplate) { + + CompletableFuture future = new CompletableFuture<>(); + + try { + HttpURLConnection connection = (HttpURLConnection) new URL(requestTemplate.getURL()).openConnection(); + connection.setConnectTimeout(clientConfig.getConnectTimeout()); + connection.setReadTimeout(clientConfig.getReadTimeout()); + connection.setAllowUserInteraction(false); + connection.setInstanceFollowRedirects(true); + connection.setRequestMethod(requestTemplate.getHttpMethod()); + + // writeHeaders + + for (String field : requestTemplate.getAllHeaders().keySet()) { + for (String value : requestTemplate.getHeaders(field)) { + connection.addRequestProperty(field, value); + } + } + + + // writeBody + + boolean gzipEncodedRequest = requestTemplate.isGzipEncodedRequest(); + boolean deflateEncodedRequest = requestTemplate.isDeflateEncodedRequest(); + if (requestTemplate.isBodyEmpty()) { + future.complete(new RestResult() { + @Override + public String getContentType() { + return connection.getContentType(); + } + + @Override + public byte[] getBody() throws IOException { + return IOUtils.toByteArray(connection.getInputStream()); + } + + @Override + public Map> headers() { + return connection.getHeaderFields(); + } + + @Override + public byte[] getErrorResponse() throws IOException { + return IOUtils.toByteArray(connection.getErrorStream()); + } + + @Override + public int getResponseCode() throws IOException { + return connection.getResponseCode(); + } + + @Override + public String getMessage() throws IOException { + return connection.getResponseMessage(); + } + }); + return future; + } + Integer contentLength = requestTemplate.getContentLength(); + + if (contentLength != null) { + connection.setFixedLengthStreamingMode(contentLength); + } else { + connection.setChunkedStreamingMode(clientConfig.getChunkLength()); + } + connection.setDoOutput(true); + + OutputStream out = connection.getOutputStream(); + if (gzipEncodedRequest) { + out = new GZIPOutputStream(out); + } else if (deflateEncodedRequest) { + out = new DeflaterOutputStream(out); + } + try { + out.write(requestTemplate.getSerializedBody()); + } finally { + try { + out.close(); + } catch (IOException suppressed) { + } + } + + future.complete(new RestResult() { + @Override + public String getContentType() { + return connection.getContentType(); + } + + @Override + public byte[] getBody() throws IOException { + return IOUtils.toByteArray(connection.getInputStream()); + } + + @Override + public Map> headers() { + return connection.getHeaderFields(); + } + + @Override + public byte[] getErrorResponse() throws IOException { + return IOUtils.toByteArray(connection.getErrorStream()); + } + + @Override + public int getResponseCode() throws IOException { + return connection.getResponseCode(); + } + + @Override + public String getMessage() throws IOException { + return connection.getResponseMessage(); + } + }); + } catch (Exception e) { + future.completeExceptionally(e); + } + + return future; + } + + @Override + public void close() { + + } + + @Override + public void close(int timeout) { + + } + + @Override + public boolean isClosed() { + return true; + } + +} diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory b/dubbo-remoting/dubbo-remoting-http/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory new file mode 100644 index 0000000000..95dd12e072 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-http/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory @@ -0,0 +1,4 @@ +ok-http=org.apache.dubbo.remoting.http.factory.impl.OkHttpClientFactory +url-connection=org.apache.dubbo.remoting.http.factory.impl.URLConnectionClientFactory +apache-http-client=org.apache.dubbo.remoting.http.factory.impl.ApacheHttpClientFactory + diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/api/MultiplexProtocolConnectionManagerTest.java b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/api/MultiplexProtocolConnectionManagerTest.java index 0e31a128fe..634c4a72c1 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/api/MultiplexProtocolConnectionManagerTest.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/api/MultiplexProtocolConnectionManagerTest.java @@ -29,7 +29,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.opentest4j.AssertionFailedError; import java.lang.reflect.Field; import java.util.Map; diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java index 9328598081..360e629c72 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java @@ -45,19 +45,14 @@ import java.util.concurrent.CopyOnWriteArrayList; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE; -import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNSUPPORTED; -import static org.apache.dubbo.rpc.Constants.TOKEN_KEY; /** * AbstractProxyProtocol */ public abstract class AbstractProxyProtocol extends AbstractProtocol { - private final List> rpcExceptions = new CopyOnWriteArrayList>(); + protected final List> rpcExceptions = new CopyOnWriteArrayList>(); protected ProxyFactory proxyFactory; @@ -139,48 +134,6 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol { return exporter; } - @Override - protected Invoker protocolBindingRefer(final Class type, final URL url) throws RpcException { - final Invoker target = proxyFactory.getInvoker(doRefer(type, url), type, url); - Invoker invoker = new AbstractInvoker(type, url, new String[]{INTERFACE_KEY, GROUP_KEY, TOKEN_KEY}) { - @Override - protected Result doInvoke(Invocation invocation) { - try { - invocation.setAttachment(PATH_KEY, getUrl().getPath()); - invocation.setAttachment(VERSION_KEY, version); - Result result = target.invoke(invocation); - // FIXME result is an AsyncRpcResult instance. - Throwable e = result.getException(); - if (e != null) { - for (Class rpcException : rpcExceptions) { - if (rpcException.isAssignableFrom(e.getClass())) { - throw getRpcException(type, url, invocation, e); - } - } - } - return result; - } catch (RpcException e) { - if (e.getCode() == RpcException.UNKNOWN_EXCEPTION) { - e.setCode(getErrorCode(e.getCause())); - } - throw e; - } catch (Throwable e) { - throw getRpcException(type, url, invocation, e); - } - } - - @Override - public void destroy() { - super.destroy(); - target.destroy(); - invokers.remove(this); - AbstractProxyProtocol.this.destroyInternal(url); - } - }; - invokers.add(invoker); - return invoker; - } - // used to destroy unused clients and other resource protected void destroyInternal(URL url) { // subclass override @@ -207,8 +160,6 @@ public abstract class AbstractProxyProtocol extends AbstractProtocol { protected abstract Runnable doExport(T impl, Class type, URL url) throws RpcException; - protected abstract T doRefer(Class type, URL url) throws RpcException; - protected class ProxyProtocolServer implements ProtocolServer { private RemotingServer server; diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java index b6ceac8342..e6d26ff8fe 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java @@ -18,11 +18,9 @@ package org.apache.dubbo.rpc; import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.url.component.URLParam; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.io.InputStream; import java.util.Collection; import java.util.HashMap; import java.util.Map; diff --git a/dubbo-rpc/dubbo-rpc-rest/pom.xml b/dubbo-rpc/dubbo-rpc-rest/pom.xml index 8f94d12c65..dc5855b88a 100644 --- a/dubbo-rpc/dubbo-rpc-rest/pom.xml +++ b/dubbo-rpc/dubbo-rpc-rest/pom.xml @@ -16,7 +16,7 @@ --> 4.0.0 - + org.apache.dubbo dubbo-rpc ${revision} @@ -112,10 +112,48 @@ test + + + org.apache.dubbo + dubbo-metadata-api + ${project.parent.version} + + + + javax.servlet + javax.servlet-api + provided + + + + jakarta.servlet + jakarta.servlet-api + provided + + + + io.netty + netty-codec-http + provided + + io.netty netty-transport compile + + + + org.springframework + spring-web + test + + + + org.springframework + spring-context + test + diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java index 918f10afda..b066c79f43 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java @@ -16,16 +16,16 @@ */ package org.apache.dubbo.rpc.protocol.rest; -import io.netty.channel.ChannelOption; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.NetUtils; + +import io.netty.channel.ChannelOption; import org.jboss.resteasy.plugins.server.netty.NettyJaxrsServer; import org.jboss.resteasy.spi.ResteasyDeployment; import java.util.HashMap; import java.util.Map; - import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_THREADS; import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY; import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY; diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java index 393a6d6c34..fc8d4664c8 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java @@ -19,32 +19,31 @@ package org.apache.dubbo.rpc.protocol.rest; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.reference.ReferenceCountedResource; - -import org.jboss.resteasy.client.jaxrs.ResteasyClient; +import org.apache.dubbo.remoting.http.RestClient; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_CLOSE_CLIENT; -public class ReferenceCountedClient extends ReferenceCountedResource { +public class ReferenceCountedClient extends ReferenceCountedResource { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ReferenceCountedClient.class); - private final ResteasyClient resteasyClient; + private T client; - public ReferenceCountedClient(ResteasyClient resteasyClient) { - this.resteasyClient = resteasyClient; + public ReferenceCountedClient(T client) { + this.client = client; } - public ResteasyClient getClient() { - return resteasyClient; + public T getClient() { + return client; } public boolean isDestroyed() { - return resteasyClient.isClosed(); + return client.isClosed(); } @Override protected void destroy() { try { - resteasyClient.close(); + client.close(); } catch (Exception e) { logger.error(PROTOCOL_ERROR_CLOSE_CLIENT, "", "", "Close resteasy client error", e); } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java index 1966e7f0ec..90e254be71 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java @@ -19,72 +19,73 @@ package org.apache.dubbo.rpc.protocol.rest; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.remoting.http.HttpBinder; +import org.apache.dubbo.metadata.ParameterTypesComparator; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.RestResult; +import org.apache.dubbo.remoting.http.factory.RestClientFactory; import org.apache.dubbo.remoting.http.servlet.BootstrapListener; import org.apache.dubbo.remoting.http.servlet.ServletManager; +import org.apache.dubbo.rpc.AppResponse; +import org.apache.dubbo.rpc.AsyncRpcResult; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.ProtocolServer; +import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.protocol.AbstractInvoker; import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionConfig; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionCreateContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept; +import org.apache.dubbo.rpc.protocol.rest.annotation.metadata.MetadataResolver; +import org.apache.dubbo.rpc.protocol.rest.exception.HttpClientException; +import org.apache.dubbo.rpc.protocol.rest.exception.RemoteServerInternalException; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodecManager; +import org.apache.dubbo.rpc.protocol.rest.util.MediaTypeUtil; -import org.apache.http.HeaderElement; -import org.apache.http.HeaderElementIterator; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.config.SocketConfig; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.message.BasicHeaderElementIterator; -import org.apache.http.protocol.HTTP; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; import org.jboss.resteasy.util.GetRestful; import javax.servlet.ServletContext; import javax.ws.rs.ProcessingException; import javax.ws.rs.WebApplicationException; import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; -import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN; -import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; +import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_CLOSE_CLIENT; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_CLOSE_SERVER; -import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY; -import static org.apache.dubbo.remoting.Constants.CONNECT_TIMEOUT_KEY; -import static org.apache.dubbo.remoting.Constants.DEFAULT_CONNECT_TIMEOUT; import static org.apache.dubbo.remoting.Constants.SERVER_KEY; -import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY; +import static org.apache.dubbo.rpc.Constants.TOKEN_KEY; public class RestProtocol extends AbstractProxyProtocol { private static final int DEFAULT_PORT = 80; private static final String DEFAULT_SERVER = "jetty"; - - private static final int HTTPCLIENTCONNECTIONMANAGER_MAXPERROUTE = 20; - private static final int HTTPCLIENTCONNECTIONMANAGER_MAXTOTAL = 20; - private static final int HTTPCLIENT_KEEPALIVEDURATION = 30 * 1000; - private static final int HTTPCLIENTCONNECTIONMANAGER_CLOSEWAITTIME_MS = 1000; - private static final int HTTPCLIENTCONNECTIONMANAGER_CLOSEIDLETIME_S = 30; + private static final String DEFAULT_CLIENT = org.apache.dubbo.remoting.Constants.OK_HTTP; private final RestServerFactory serverFactory = new RestServerFactory(); - private final ConcurrentMap clients = new ConcurrentHashMap<>(); + private final ConcurrentMap> clients = new ConcurrentHashMap<>(); - private volatile ConnectionMonitor connectionMonitor; + private final RestClientFactory clientFactory; - public RestProtocol() { + private final Set httpConnectionPreBuildIntercepts; + + public RestProtocol(FrameworkModel frameworkModel) { super(WebApplicationException.class, ProcessingException.class); + this.clientFactory = frameworkModel.getExtensionLoader(RestClientFactory.class).getAdaptiveExtension(); + this.httpConnectionPreBuildIntercepts = frameworkModel.getExtensionLoader(HttpConnectionPreBuildIntercept.class).getSupportedExtensionInstances(); } - public void setHttpBinder(HttpBinder httpBinder) { - serverFactory.setHttpBinder(httpBinder); - } @Override public int getDefaultPort() { @@ -135,79 +136,100 @@ public class RestProtocol extends AbstractProxyProtocol { }; } + @Override - protected T doRefer(Class serviceType, URL url) throws RpcException { - ReferenceCountedClient referenceCountedClient = ConcurrentHashMapUtils.computeIfAbsent(clients, url.getAddress(), _key -> { - // TODO more configs to add - return createReferenceCountedClient(url); - }); + protected Invoker protocolBindingRefer(final Class type, final URL url) throws RpcException { - if (referenceCountedClient.isDestroyed()) { - referenceCountedClient = createReferenceCountedClient(url); - clients.put(url.getAddress(), referenceCountedClient); - } - referenceCountedClient.retain(); + ReferenceCountedClient refClient = + clients.computeIfAbsent(url.getAddress(), key -> createReferenceCountedClient(url)); - ResteasyClient resteasyClient = referenceCountedClient.getClient(); - for (String clazz : COMMA_SPLIT_PATTERN.split(url.getParameter(EXTENSION_KEY, ""))) { - if (!StringUtils.isEmpty(clazz)) { + refClient.retain(); + + // resolve metadata + Map> metadataMap = MetadataResolver.resolveConsumerServiceMetadata(type, url); + + Invoker invoker = new AbstractInvoker(type, url, new String[]{INTERFACE_KEY, GROUP_KEY, TOKEN_KEY}) { + @Override + protected Result doInvoke(Invocation invocation) { try { - resteasyClient.register(Thread.currentThread().getContextClassLoader().loadClass(clazz.trim())); - } catch (ClassNotFoundException e) { - throw new RpcException("Error loading JAX-RS extension class: " + clazz.trim(), e); + RestMethodMetadata restMethodMetadata = metadataMap.get(invocation.getMethodName()).get(ParameterTypesComparator.getInstance(invocation.getParameterTypes())); + + RequestTemplate requestTemplate = new RequestTemplate(invocation, restMethodMetadata.getRequest().getMethod(), url.getAddress(), getContextPath(url)); + + HttpConnectionCreateContext httpConnectionCreateContext = new HttpConnectionCreateContext(); + // TODO dynamic load config + httpConnectionCreateContext.setConnectionConfig(new HttpConnectionConfig()); + httpConnectionCreateContext.setRequestTemplate(requestTemplate); + httpConnectionCreateContext.setRestMethodMetadata(restMethodMetadata); + httpConnectionCreateContext.setInvocation(invocation); + httpConnectionCreateContext.setUrl(url); + + for (HttpConnectionPreBuildIntercept intercept : httpConnectionPreBuildIntercepts) { + intercept.intercept(httpConnectionCreateContext); + } + + CompletableFuture future = refClient.getClient().send(requestTemplate); + CompletableFuture responseFuture = new CompletableFuture<>(); + AsyncRpcResult asyncRpcResult = new AsyncRpcResult(responseFuture, invocation); + future.whenComplete((r, t) -> { + if (t != null) { + responseFuture.completeExceptionally(t); + } else { + AppResponse appResponse = new AppResponse(); + try { + int responseCode = r.getResponseCode(); + MediaType mediaType = MediaType.TEXT_PLAIN; + + if (400 < responseCode && responseCode < 500) { + throw new HttpClientException(r.getMessage()); + } else if (responseCode >= 500) { + throw new RemoteServerInternalException(r.getMessage()); + } else if (responseCode < 400) { + mediaType = MediaTypeUtil.convertMediaType(r.getContentType()); + } + + + Object value = HttpMessageCodecManager.httpMessageDecode(r.getBody(), + restMethodMetadata.getReflectMethod().getReturnType(), mediaType); + appResponse.setValue(value); + Map headers = r.headers() + .entrySet() + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0))); + appResponse.setAttachments(headers); + responseFuture.complete(appResponse); + } catch (Exception e) { + responseFuture.completeExceptionally(e); + } + } + }); + return asyncRpcResult; + } catch (RpcException e) { + if (e.getCode() == RpcException.UNKNOWN_EXCEPTION) { + e.setCode(getErrorCode(e.getCause())); + } + throw e; } } - } - // TODO protocol - ResteasyWebTarget target = resteasyClient.target("http://" + url.getAddress() + "/" + getContextPath(url)); - return target.proxy(serviceType); + @Override + public void destroy() { + super.destroy(); + invokers.remove(this); + destroyInternal(url); + } + }; + invokers.add(invoker); + return invoker; } - private ReferenceCountedClient createReferenceCountedClient(URL url) { - PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); - // 20 is the default maxTotal of current PoolingClientConnectionManager - connectionManager.setMaxTotal(url.getParameter(CONNECTIONS_KEY, HTTPCLIENTCONNECTIONMANAGER_MAXTOTAL)); - connectionManager.setDefaultMaxPerRoute(url.getParameter(CONNECTIONS_KEY, HTTPCLIENTCONNECTIONMANAGER_MAXPERROUTE)); - if (connectionMonitor == null) { - connectionMonitor = new ConnectionMonitor(); - connectionMonitor.start(); - } - connectionMonitor.addConnectionManager(url.getAddress(), connectionManager); - RequestConfig requestConfig = RequestConfig.custom() - .setConnectTimeout(url.getParameter(CONNECT_TIMEOUT_KEY, DEFAULT_CONNECT_TIMEOUT)) - .setSocketTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT)) - .build(); + private ReferenceCountedClient createReferenceCountedClient(URL url) throws RpcException { - SocketConfig socketConfig = SocketConfig.custom() - .setSoKeepAlive(true) - .setTcpNoDelay(true) - .build(); + // url -> RestClient + RestClient restClient = clientFactory.createRestClient(url); - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setConnectionManager(connectionManager) - .setKeepAliveStrategy((response, context) -> { - HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE)); - while (it.hasNext()) { - HeaderElement he = it.nextElement(); - String param = he.getName(); - String value = he.getValue(); - if (value != null && param.equalsIgnoreCase(TIMEOUT_KEY)) { - return Long.parseLong(value) * 1000; - } - } - return HTTPCLIENT_KEEPALIVEDURATION; - }) - .setDefaultRequestConfig(requestConfig) - .setDefaultSocketConfig(socketConfig) - .build(); - - ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient/*, localContext*/); - - ResteasyClient resteasyClient = new ResteasyClientBuilder().httpEngine(engine).build(); - resteasyClient.register(RpcContextFilter.class); - return new ReferenceCountedClient(resteasyClient); + return new ReferenceCountedClient<>(restClient); } @Override @@ -223,10 +245,6 @@ public class RestProtocol extends AbstractProxyProtocol { } super.destroy(); - if (connectionMonitor != null) { - connectionMonitor.shutdown(); - } - for (Map.Entry entry : serverMap.entrySet()) { try { if (logger.isInfoEnabled()) { @@ -281,55 +299,9 @@ public class RestProtocol extends AbstractProxyProtocol { ReferenceCountedClient referenceCountedClient = clients.get(url.getAddress()); if (referenceCountedClient != null && referenceCountedClient.release()) { clients.remove(url.getAddress()); - connectionMonitor.destroyManager(url); } } catch (Exception e) { logger.warn(PROTOCOL_ERROR_CLOSE_CLIENT, "", "", "Failed to close unused resources in rest protocol. interfaceName [" + url.getServiceInterface() + "]", e); } } - - protected class ConnectionMonitor extends Thread { - private volatile boolean shutdown; - /** - * The lifecycle of {@code PoolingHttpClientConnectionManager} instance is bond with ReferenceCountedClient - */ - private final Map connectionManagers = new ConcurrentHashMap<>(); - - public void addConnectionManager(String address, PoolingHttpClientConnectionManager connectionManager) { - connectionManagers.putIfAbsent(address, connectionManager); - } - - @Override - public void run() { - try { - while (!shutdown) { - synchronized (this) { - wait(HTTPCLIENTCONNECTIONMANAGER_CLOSEWAITTIME_MS); - for (PoolingHttpClientConnectionManager connectionManager : connectionManagers.values()) { - connectionManager.closeExpiredConnections(); - connectionManager.closeIdleConnections(HTTPCLIENTCONNECTIONMANAGER_CLOSEIDLETIME_S, TimeUnit.SECONDS); - } - } - } - } catch (InterruptedException ex) { - shutdown(); - } - } - - public void shutdown() { - shutdown = true; - connectionManagers.clear(); - synchronized (this) { - notifyAll(); - } - } - - // destroy the connection manager of a specific address when ReferenceCountedClient is destroyed. - private void destroyManager(URL url) { - PoolingHttpClientConnectionManager connectionManager = connectionManagers.remove(url.getAddress()); - if (connectionManager != null) { - connectionManager.close(); - } - } - } } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java index 6fcf7f6f08..265987241e 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java @@ -17,19 +17,15 @@ package org.apache.dubbo.rpc.protocol.rest; import org.apache.dubbo.remoting.http.HttpBinder; +import org.apache.dubbo.rpc.model.FrameworkModel; /** * Only the server that implements servlet container * could support something like @Context injection of servlet objects. - * */ public class RestServerFactory { - private HttpBinder httpBinder; - - public void setHttpBinder(HttpBinder httpBinder) { - this.httpBinder = httpBinder; - } + private static final HttpBinder httpBinder = FrameworkModel.defaultModel().getAdaptiveExtension(HttpBinder.class); public RestProtocolServer createServer(String name) { // TODO move names to Constants diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/BaseParseContext.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/BaseParseContext.java new file mode 100644 index 0000000000..e2fdc252ef --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/BaseParseContext.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.annotation; + + +import org.apache.dubbo.metadata.rest.ArgInfo; + +import java.util.List; + +public class BaseParseContext { + + + protected List args; + + protected List argInfos; + + + public List getArgs() { + return args; + } + + public void setArgs(List args) { + this.args = args; + } + + public List getArgInfos() { + return argInfos; + } + + public void setArgInfos(List argInfos) { + this.argInfos = argInfos; + } + + public ArgInfo getArgInfoByIndex(int index) { + return getArgInfos().get(index); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParser.java new file mode 100644 index 0000000000..e8af563d3e --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParser.java @@ -0,0 +1,24 @@ +/* + * 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.protocol.rest.annotation; + +import org.apache.dubbo.metadata.rest.ArgInfo; + + +public interface ParamParser { + void parse(T parseContext, ArgInfo argInfo); +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java new file mode 100644 index 0000000000..476f7aaed0 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java @@ -0,0 +1,61 @@ +/* + * 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.protocol.rest.annotation; + + +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser; +import org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.ConsumerParseContext; + +import java.util.List; +import java.util.Set; + +public class ParamParserManager { + + + private static final Set consumerParamParsers = + FrameworkModel.defaultModel().getExtensionLoader(BaseConsumerParamParser.class).getSupportedExtensionInstances(); + + /** + * provider Design Description: + *

+ * Object[] args=new Object[0]; + * List argsList=new ArrayList<>; + *

+ * setValueByIndex(int index,Object value); + *

+ * args=toArray(new Object[0]); + */ + public void consumerParamParse(ConsumerParseContext parseContext) { + + List args = parseContext.getArgs(); + + for (int i = 0; i < args.size(); i++) { + for (BaseConsumerParamParser paramParser : consumerParamParsers) { + ArgInfo argInfoByIndex = parseContext.getArgInfoByIndex(i); + + if (!paramParser.paramTypeMatch(argInfoByIndex)) { + continue; + } + + paramParser.parse(parseContext, argInfoByIndex); + } + } + + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionConfig.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionConfig.java new file mode 100644 index 0000000000..e9a9931c46 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionConfig.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.annotation.consumer; + + +import org.apache.dubbo.common.serialize.Constants; + +public class HttpConnectionConfig { + + + private int connectTimeout; + private int readTimeout; + private int chunkLength = 8196; + private byte serialization = Constants.FASTJSON2_SERIALIZATION_ID; + private int keepAlive = 60; + + + public int getConnectTimeout() { + return connectTimeout; + } + + public int getReadTimeout() { + return readTimeout; + } + + public int getChunkLength() { + return chunkLength; + } + + public byte getSerialization() { + return serialization; + } + + public int getKeepAlive() { + return keepAlive; + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionCreateContext.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionCreateContext.java new file mode 100644 index 0000000000..73e0635cc4 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionCreateContext.java @@ -0,0 +1,81 @@ +/* + * 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.protocol.rest.annotation.consumer; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.metadata.rest.ServiceRestMetadata; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.Invocation; + +public class HttpConnectionCreateContext { + + private RequestTemplate requestTemplate; + private HttpConnectionConfig connectionConfig; + private RestMethodMetadata restMethodMetadata; + private Invocation invocation; + private URL url; + + public HttpConnectionCreateContext() { + } + + + public void setRequestTemplate(RequestTemplate requestTemplate) { + this.requestTemplate = requestTemplate; + } + + public void setConnectionConfig(HttpConnectionConfig connectionConfig) { + this.connectionConfig = connectionConfig; + } + + + public RequestTemplate getRequestTemplate() { + return requestTemplate; + } + + public HttpConnectionConfig getConnectionConfig() { + return connectionConfig; + } + + public ServiceRestMetadata getServiceRestMetadata() { + return restMethodMetadata.getServiceRestMetadata(); + } + + public RestMethodMetadata getRestMethodMetadata() { + return restMethodMetadata; + } + + public void setRestMethodMetadata(RestMethodMetadata restMethodMetadata) { + this.restMethodMetadata = restMethodMetadata; + } + + public Invocation getInvocation() { + return invocation; + } + + public void setInvocation(Invocation invocation) { + this.invocation = invocation; + } + + public URL getUrl() { + return url; + } + + public void setUrl(URL url) { + this.url = url; + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionPreBuildIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionPreBuildIntercept.java new file mode 100644 index 0000000000..3862e18314 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/HttpConnectionPreBuildIntercept.java @@ -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.rpc.protocol.rest.annotation.consumer; + +import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.extension.SPI; + +@SPI(scope = ExtensionScope.FRAMEWORK) +public interface HttpConnectionPreBuildIntercept { + void intercept(HttpConnectionCreateContext connectionCreateContext); +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AddMustAttachmentIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AddMustAttachmentIntercept.java new file mode 100644 index 0000000000..446cd4e6f3 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AddMustAttachmentIntercept.java @@ -0,0 +1,48 @@ +/* + * 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.protocol.rest.annotation.consumer.inercept; + + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.ServiceRestMetadata; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionConfig; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionCreateContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept; +import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant; + +@Activate(value = RestConstant.ADD_MUST_ATTTACHMENT,order = 1) +public class AddMustAttachmentIntercept implements HttpConnectionPreBuildIntercept { + + @Override + public void intercept(HttpConnectionCreateContext connectionCreateContext) { + + RequestTemplate requestTemplate = connectionCreateContext.getRequestTemplate(); + ServiceRestMetadata serviceRestMetadata = connectionCreateContext.getServiceRestMetadata(); + HttpConnectionConfig connectionConfig = connectionCreateContext.getConnectionConfig(); + + + requestTemplate.addHeader(RestConstant.GROUP, serviceRestMetadata.getGroup()); + requestTemplate.addHeader(RestConstant.VERSION, serviceRestMetadata.getVersion()); + requestTemplate.addHeader(RestConstant.PATH, serviceRestMetadata.getServiceInterface()); + requestTemplate.addKeepAliveHeader(connectionConfig.getKeepAlive()); + + + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AttachmentIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AttachmentIntercept.java new file mode 100644 index 0000000000..3903aa654c --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/AttachmentIntercept.java @@ -0,0 +1,70 @@ +/* + * 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.protocol.rest.annotation.consumer.inercept; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionCreateContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept; +import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant; + +import java.nio.charset.StandardCharsets; +import java.util.Map; +@Activate(value = RestConstant.RPCCONTEXT_INTERCEPT,order = 3) +public class AttachmentIntercept implements HttpConnectionPreBuildIntercept { + + @Override + public void intercept(HttpConnectionCreateContext connectionCreateContext) { + + RequestTemplate requestTemplate = connectionCreateContext.getRequestTemplate(); + int size = 0; + for (Map.Entry entry : connectionCreateContext.getInvocation().getObjectAttachments().entrySet()) { + String key = entry.getKey(); + String value = String.valueOf(entry.getValue()); + if (illegalHttpHeaderKey(key) || illegalHttpHeaderValue(value)) { + throw new IllegalArgumentException("The attachments of " + RpcContext.class.getSimpleName() + " must not contain ',' or '=' when using rest protocol"); + } + + // TODO for now we don't consider the differences of encoding and server limit + if (value != null) { + size += value.getBytes(StandardCharsets.UTF_8).length; + } + if (size > RestConstant.MAX_HEADER_SIZE) { + throw new IllegalArgumentException("The attachments of " + RpcContext.class.getSimpleName() + " is too big"); + } + + String attachments = key + "=" + value; + requestTemplate.addHeader(RestConstant.DUBBO_ATTACHMENT_HEADER, attachments); + } + } + + private boolean illegalHttpHeaderKey(String key) { + if (StringUtils.isNotEmpty(key)) { + return key.contains(",") || key.contains("="); + } + return false; + } + + private boolean illegalHttpHeaderValue(String value) { + if (StringUtils.isNotEmpty(value)) { + return value.contains(","); + } + return false; + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/ParamParseIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/ParamParseIntercept.java new file mode 100644 index 0000000000..9babb8c605 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/ParamParseIntercept.java @@ -0,0 +1,39 @@ +/* + * 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.protocol.rest.annotation.consumer.inercept; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.protocol.rest.annotation.ParamParserManager; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionCreateContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept; +import org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.ConsumerParseContext; + +import java.util.Arrays; + +@Activate(value = "paramparse",order = 5) +public class ParamParseIntercept implements HttpConnectionPreBuildIntercept { + private static final ParamParserManager paramParser = new ParamParserManager(); + + @Override + public void intercept(HttpConnectionCreateContext connectionCreateContext) { + + ConsumerParseContext consumerParseContext = new ConsumerParseContext(connectionCreateContext.getRequestTemplate()); + consumerParseContext.setArgInfos(connectionCreateContext.getRestMethodMetadata().getArgInfos()); + consumerParseContext.setArgs(Arrays.asList(connectionCreateContext.getInvocation().getArguments())); + paramParser.consumerParamParse(consumerParseContext); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/PathVariableIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/PathVariableIntercept.java new file mode 100644 index 0000000000..8329b086ad --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/PathVariableIntercept.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.annotation.consumer.inercept; + + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.metadata.rest.PathUtil; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionCreateContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept; +import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant; + +import java.util.Arrays; +import java.util.List; + +@Activate(value = RestConstant.PATH_INTERCEPT,order = 4) +public class PathVariableIntercept implements HttpConnectionPreBuildIntercept { + + @Override + public void intercept(HttpConnectionCreateContext connectionCreateContext) { + + RestMethodMetadata restMethodMetadata = connectionCreateContext.getRestMethodMetadata(); + RequestTemplate requestTemplate = connectionCreateContext.getRequestTemplate(); + + List argInfos = restMethodMetadata.getArgInfos(); + + // path variable parse + String path = PathUtil.resolvePathVariable(restMethodMetadata.getRequest().getPath(), argInfos, Arrays.asList(connectionCreateContext.getInvocation().getArguments())); + requestTemplate.path(path); + + + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java new file mode 100644 index 0000000000..e9ee687118 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java @@ -0,0 +1,54 @@ +/* + * 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.protocol.rest.annotation.consumer.inercept; + + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionCreateContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept; +import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant; + +import java.util.Collection; +import java.util.Set; + +@Activate(value = RestConstant.REQUEST_HEADER_INTERCEPT,order = 2) +public class RequestHeaderIntercept implements HttpConnectionPreBuildIntercept { + + @Override + public void intercept(HttpConnectionCreateContext connectionCreateContext) { + + RestMethodMetadata restMethodMetadata = connectionCreateContext.getRestMethodMetadata(); + RequestTemplate requestTemplate = connectionCreateContext.getRequestTemplate(); + + + + Set consumes = restMethodMetadata.getRequest().getConsumes(); + + requestTemplate.addHeaders(RestConstant.CONTENT_TYPE, consumes); + + Collection headers = requestTemplate.getHeaders(RestConstant.ACCEPT); + if (headers == null || headers.isEmpty()) { + requestTemplate.addHeader(RestConstant.ACCEPT, RestConstant.DEFAULT_ACCEPT); + } + + + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/SerializeBodyIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/SerializeBodyIntercept.java new file mode 100644 index 0000000000..6902cb987b --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/SerializeBodyIntercept.java @@ -0,0 +1,66 @@ +/* + * 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.protocol.rest.annotation.consumer.inercept; + + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.LoggerCodeConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionCreateContext; +import org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept; +import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodecManager; +import org.apache.dubbo.rpc.protocol.rest.util.MediaTypeUtil; + +import java.io.ByteArrayOutputStream; +import java.util.Collection; + +@Activate(value = RestConstant.SERIALIZE_INTERCEPT, order = Integer.MAX_VALUE) +public class SerializeBodyIntercept implements HttpConnectionPreBuildIntercept { + + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(SerializeBodyIntercept.class); + + @Override + public void intercept(HttpConnectionCreateContext connectionCreateContext) { + RequestTemplate requestTemplate = connectionCreateContext.getRequestTemplate(); + + if (requestTemplate.isBodyEmpty()) { + return; + } + + + try { + Object unSerializedBody = requestTemplate.getUnSerializedBody(); + URL url = connectionCreateContext.getUrl(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Collection headers = requestTemplate.getHeaders(RestConstant.CONTENT_TYPE); + MediaType mediaType = MediaTypeUtil.convertMediaType(headers.toArray(new String[0])); + HttpMessageCodecManager.httpMessageEncode(outputStream, unSerializedBody, url, mediaType); + requestTemplate.serializeBody(outputStream.toByteArray()); + } catch (Exception e) { + logger.error(LoggerCodeConstants.PROTOCOL_ERROR_DESERIALIZE, "", "", "Rest SerializeBodyIntercept serialize error: {}", e); + } + + + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/metadata/MetadataResolver.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/metadata/MetadataResolver.java new file mode 100644 index 0000000000..69715715a1 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/metadata/MetadataResolver.java @@ -0,0 +1,57 @@ +/* + * 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.protocol.rest.annotation.metadata; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.metadata.ParameterTypesComparator; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; +import org.apache.dubbo.metadata.rest.ServiceRestMetadata; +import org.apache.dubbo.metadata.rest.ServiceRestMetadataResolver; +import org.apache.dubbo.rpc.protocol.rest.exception.CodeStyleNotSupportException; + +import java.util.Map; + +public class MetadataResolver { + private MetadataResolver() { + } + + /** + * for consumer + * + * @param targetClass target service class + * @param url consumer url + * @return rest metadata + * @throws CodeStyleNotSupportException not support type + */ + public static Map> resolveConsumerServiceMetadata(Class targetClass, URL url) { + ExtensionLoader extensionLoader = url.getOrDefaultApplicationModel().getExtensionLoader(ServiceRestMetadataResolver.class); + + for (ServiceRestMetadataResolver serviceRestMetadataResolver : extensionLoader.getSupportedExtensionInstances()) { + if (serviceRestMetadataResolver.supports(targetClass, true)) { + ServiceRestMetadata serviceRestMetadata = new ServiceRestMetadata(url.getServiceInterface(), url.getVersion(), url.getGroup(), true); + ServiceRestMetadata resolve = serviceRestMetadataResolver.resolve(targetClass, serviceRestMetadata); + return resolve.getMethodToServiceMap(); + } + } + + // TODO support Dubbo style service + throw new CodeStyleNotSupportException("service is: " + targetClass + ", only support " + extensionLoader.getSupportedExtensions() + " annotation"); + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BaseConsumerParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BaseConsumerParamParser.java new file mode 100644 index 0000000000..74c2ca1521 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BaseConsumerParamParser.java @@ -0,0 +1,29 @@ +/* + * 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.protocol.rest.annotation.param.parse.consumer; + + +import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.rpc.protocol.rest.annotation.ParamParser; + +@SPI(scope = ExtensionScope.FRAMEWORK) +public interface BaseConsumerParamParser extends ParamParser { + + boolean paramTypeMatch(ArgInfo argInfo); +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BodyConsumerParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BodyConsumerParamParser.java new file mode 100644 index 0000000000..0e9e02a9af --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/BodyConsumerParamParser.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.metadata.rest.ParamType; +import org.apache.dubbo.remoting.http.RequestTemplate; + +import java.util.List; + +@Activate("consumer-body") +public class BodyConsumerParamParser implements BaseConsumerParamParser { + @Override + public void parse(ConsumerParseContext parseContext, ArgInfo argInfo) { + + + List args = parseContext.getArgs(); + + RequestTemplate requestTemplate = parseContext.getRequestTemplate(); + + requestTemplate.body(args.get(argInfo.getIndex())); + + + } + + @Override + public boolean paramTypeMatch(ArgInfo argInfo) { + return ParamType.BODY.supportAnno(argInfo.getParamAnnotationType()); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ConsumerParseContext.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ConsumerParseContext.java new file mode 100644 index 0000000000..672b30e4de --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ConsumerParseContext.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer; + + +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.protocol.rest.annotation.BaseParseContext; + +public class ConsumerParseContext extends BaseParseContext { + private RequestTemplate requestTemplate; + + public ConsumerParseContext(RequestTemplate requestTemplate) { + this.requestTemplate = requestTemplate; + } + + public RequestTemplate getRequestTemplate() { + return requestTemplate; + } + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/FormConsumerParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/FormConsumerParamParser.java new file mode 100644 index 0000000000..dba932b8de --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/FormConsumerParamParser.java @@ -0,0 +1,54 @@ +/* + * 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.protocol.rest.annotation.param.parse.consumer; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.metadata.rest.ParamType; +import org.apache.dubbo.remoting.http.RequestTemplate; +import org.apache.dubbo.rpc.protocol.rest.util.MultiValueCreator; + +import java.util.List; + +@Activate("consumer-form") +public class FormConsumerParamParser implements BaseConsumerParamParser { + @Override + public void parse(ConsumerParseContext parseContext, ArgInfo argInfo) { + + + List args = parseContext.getArgs(); + + RequestTemplate requestTemplate = parseContext.getRequestTemplate(); + Object value = args.get(argInfo.getIndex()); + + Object unSerializedBody = requestTemplate.getUnSerializedBody(); + if (unSerializedBody == null) { + unSerializedBody = MultiValueCreator.createMultiValueMap(); + } + + MultiValueCreator.add(unSerializedBody, argInfo.getAnnotationNameAttribute(), String.valueOf(value)); + + requestTemplate.body(unSerializedBody); + + + } + + @Override + public boolean paramTypeMatch(ArgInfo argInfo) { + return ParamType.FORM.supportAnno(argInfo.getParamAnnotationType()); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/HeaderConsumerParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/HeaderConsumerParamParser.java new file mode 100644 index 0000000000..b53591e491 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/HeaderConsumerParamParser.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.metadata.rest.ParamType; +import org.apache.dubbo.remoting.http.RequestTemplate; + +import java.util.List; + +@Activate("consumer-header") +public class HeaderConsumerParamParser implements BaseConsumerParamParser { + @Override + public void parse(ConsumerParseContext parseContext, ArgInfo argInfo) { + List args = parseContext.getArgs(); + + RequestTemplate requestTemplate = parseContext.getRequestTemplate(); + + requestTemplate.addHeader(argInfo.getParamName(), args.get(argInfo.getIndex())); + } + + @Override + public boolean paramTypeMatch(ArgInfo argInfo) { + return ParamType.HEADER.supportAnno(argInfo.getParamAnnotationType()); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ParameterConsumerParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ParameterConsumerParamParser.java new file mode 100644 index 0000000000..eb2746f1bb --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/consumer/ParameterConsumerParamParser.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.ArgInfo; +import org.apache.dubbo.metadata.rest.ParamType; +import org.apache.dubbo.remoting.http.RequestTemplate; + +import java.util.List; + +@Activate("consumer-parameter") +public class ParameterConsumerParamParser implements BaseConsumerParamParser{ + @Override + public void parse(ConsumerParseContext parseContext, ArgInfo argInfo) { + List args = parseContext.getArgs(); + + RequestTemplate requestTemplate = parseContext.getRequestTemplate(); + + requestTemplate.addParam(argInfo.getParamName(), args.get(argInfo.getIndex())); + } + + @Override + public boolean paramTypeMatch(ArgInfo argInfo) { + return ParamType.PARAM.supportAnno(argInfo.getParamAnnotationType()); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java new file mode 100644 index 0000000000..8fe65f03a1 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/constans/RestConstant.java @@ -0,0 +1,60 @@ +/* + * 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.protocol.rest.constans; + +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.remoting.Constants; + +public interface RestConstant { + String INTERFACE = CommonConstants.INTERFACE_KEY; + String METHOD = CommonConstants.METHOD_KEY; + String PARAMETER_TYPES_DESC = CommonConstants.GENERIC_PARAMETER_DESC; + String VERSION = CommonConstants.VERSION_KEY; + String GROUP = CommonConstants.GROUP_KEY; + String PATH = CommonConstants.PATH_KEY; + String HOST = CommonConstants.HOST_KEY; + String LOCAL_ADDR = "LOCAL_ADDR"; + String REMOTE_ADDR = "REMOTE_ADDR"; + String LOCAL_PORT = "LOCAL_PORT"; + String REMOTE_PORT = "REMOTE_PORT"; + String SERIALIZATION_KEY = Constants.SERIALIZATION_KEY; + String PROVIDER_BODY_PARSE = "body"; + String PROVIDER_PARAM_PARSE = "param"; + String PROVIDER_HEADER_PARSE = "header"; + String PROVIDER_PATH_PARSE = "path"; + String PROVIDER_REQUEST_PARSE = "reuqest"; + String DUBBO_ATTACHMENT_HEADER = "Dubbo-Attachments"; + int MAX_HEADER_SIZE = 8 * 1024; + + String ADD_MUST_ATTTACHMENT = "must-intercept"; + String RPCCONTEXT_INTERCEPT = "rpc-context"; + String SERIALIZE_INTERCEPT = "serialize"; + String CONTENT_TYPE_INTERCEPT = "content-type"; + String PATH_SEPARATOR = "/"; + String REQUEST_PARAM_INTERCEPT = "param"; + String REQUEST_HEADER_INTERCEPT = "header"; + String PATH_INTERCEPT = "path"; + String KEEP_ALIVE_HEADER = "Keep-Alive"; + String CONNECTION = "Connection"; + String KEEP_ALIVE = "keep-alive"; + String CONTENT_TYPE = "Content-Type"; + String APPLICATION_JSON_VALUE = "application/json"; + String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded"; + String TEXT_PLAIN = "text/plain"; + String ACCEPT = "Accept"; + String DEFAULT_ACCEPT = "*/*"; +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/CodeStyleNotSupportException.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/CodeStyleNotSupportException.java new file mode 100644 index 0000000000..db68cf1ac7 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/CodeStyleNotSupportException.java @@ -0,0 +1,24 @@ +/* + * 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.protocol.rest.exception; + +public class CodeStyleNotSupportException extends RuntimeException{ + + public CodeStyleNotSupportException(String message) { + super(message); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/HttpClientException.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/HttpClientException.java new file mode 100644 index 0000000000..709e12af1f --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/HttpClientException.java @@ -0,0 +1,24 @@ +/* + * 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.protocol.rest.exception; + +public class HttpClientException extends RuntimeException { + + public HttpClientException(String message) { + super("dubbo http rest protocol param error :"+message); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/RemoteServerInternalException.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/RemoteServerInternalException.java new file mode 100644 index 0000000000..1d1219fdbf --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/RemoteServerInternalException.java @@ -0,0 +1,24 @@ +/* + * 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.protocol.rest.exception; + +public class RemoteServerInternalException extends RuntimeException { + + public RemoteServerInternalException(String message) { + super("dubbo http rest protocol remote error :"+message); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/UnSupportContentTypeException.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/UnSupportContentTypeException.java new file mode 100644 index 0000000000..f895f6ec44 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/exception/UnSupportContentTypeException.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.exception; + +import org.apache.dubbo.metadata.rest.media.MediaType; + +public class UnSupportContentTypeException extends RuntimeException { + + public UnSupportContentTypeException(String message) { + + super("Current Support content type: " + MediaType.getAllContentType() + "; Do not support content type" + message); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodec.java new file mode 100644 index 0000000000..1b6666b8f2 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodec.java @@ -0,0 +1,30 @@ +/* + * 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.protocol.rest.message; + + +import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.metadata.rest.media.MediaType; + +@SPI(scope = ExtensionScope.FRAMEWORK) +public interface HttpMessageCodec extends HttpMessageDecode, HttpMessageEncode { + + + boolean contentTypeSupport(MediaType mediaType, Class targetType); + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java new file mode 100644 index 0000000000..019927ca36 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.message; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.protocol.rest.exception.UnSupportContentTypeException; + +import java.io.OutputStream; +import java.util.Set; + +public class HttpMessageCodecManager { + private static final Set httpMessageCodecs = + FrameworkModel.defaultModel().getExtensionLoader(HttpMessageCodec.class).getSupportedExtensionInstances(); + + + public static Object httpMessageDecode(byte[] body, Class type, MediaType mediaType) throws Exception { + for (HttpMessageCodec httpMessageCodec : httpMessageCodecs) { + if (httpMessageCodec.contentTypeSupport(mediaType, type)) { + return httpMessageCodec.decode(body, type); + } + } + throw new UnSupportContentTypeException("UnSupport content-type :" + mediaType.value); + } + + public static void httpMessageEncode(OutputStream outputStream, Object unSerializedBody, URL url, MediaType mediaType) throws Exception { + for (HttpMessageCodec httpMessageCodec : httpMessageCodecs) { + if (httpMessageCodec.contentTypeSupport(mediaType, unSerializedBody.getClass())) { + httpMessageCodec.encode(outputStream, unSerializedBody, url); + return; + } + } + throw new UnSupportContentTypeException("UnSupport content-type :" + mediaType.value); + } + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java new file mode 100644 index 0000000000..12ae381685 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java @@ -0,0 +1,24 @@ +/* + * 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.protocol.rest.message; + + +public interface HttpMessageDecode{ + + Object decode(InputStream body, Class targetType) throws Exception; + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageEncode.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageEncode.java new file mode 100644 index 0000000000..6d35d9c43e --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageEncode.java @@ -0,0 +1,28 @@ +/* + * 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.protocol.rest.message; + + +import org.apache.dubbo.common.URL; + + + +public interface HttpMessageEncode { + + void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception; + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/MediaTypeMatcher.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/MediaTypeMatcher.java new file mode 100644 index 0000000000..2863f25893 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/MediaTypeMatcher.java @@ -0,0 +1,64 @@ +/* + * 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.protocol.rest.message; + +import org.apache.dubbo.metadata.rest.media.MediaType; + +import java.util.ArrayList; +import java.util.List; + +public enum MediaTypeMatcher { + + + MULTI_VALUE(createMediaList(MediaType.APPLICATION_FORM_URLENCODED_VALUE)), + APPLICATION_JSON(createMediaList(MediaType.APPLICATION_JSON_VALUE)), + TEXT_PLAIN(createMediaList(MediaType.TEXT_PLAIN, MediaType.OCTET_STREAM)), + TEXT_XML(createMediaList(MediaType.TEXT_XML)), + + ; + + private List mediaTypes; + + + MediaTypeMatcher(List mediaTypes) { + this.mediaTypes = mediaTypes; + } + + + private static List createMediaList(MediaType... mediaTypes) { + List mediaTypeList = getDefaultList(); + + for (MediaType mediaType : mediaTypes) { + + mediaTypeList.add(mediaType); + } + return mediaTypeList; + } + + private static List getDefaultList() { + + List defaultList = new ArrayList<>(); + defaultList.add(MediaType.ALL_VALUE); + return defaultList; + } + + public boolean mediaSupport(MediaType mediaType) { + return mediaTypes.contains(mediaType); + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java new file mode 100644 index 0000000000..4210e23569 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.message.codec; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec; + +import java.io.OutputStream; + +@Activate("byteArray") +public class ByteArrayCodec implements HttpMessageCodec { + + + @Override + public Object decode(byte[] body, Class targetType) throws Exception { + return body; + } + + @Override + public boolean contentTypeSupport(MediaType mediaType, Class targetType) { + return byte[].class.equals(targetType); + } + + + @Override + public void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception { + outputStream.write((byte[]) unSerializedBody); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java new file mode 100644 index 0000000000..095c33bdda --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java @@ -0,0 +1,57 @@ +/* + * 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.protocol.rest.message.codec; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.utils.JsonUtils; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec; +import org.apache.dubbo.rpc.protocol.rest.message.MediaTypeMatcher; +import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils; + +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Set; + +@Activate("json") +public class JsonCodec implements HttpMessageCodec { + private static final Set unSupportClasses = new HashSet<>(); + + static { + + unSupportClasses.add(byte[].class); + unSupportClasses.add(String.class); + } + + @Override + public Object decode(byte[] body, Class targetType) throws Exception { + return DataParseUtils.jsonConvert(targetType, body); + } + + @Override + public boolean contentTypeSupport(MediaType mediaType, Class targetType) { + return MediaTypeMatcher.APPLICATION_JSON.mediaSupport(mediaType) && !unSupportClasses.contains(targetType); + } + + + @Override + public void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception { + outputStream.write(JsonUtils.getJson().toJson(unSerializedBody).getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java new file mode 100644 index 0000000000..97fbb5bedb --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java @@ -0,0 +1,48 @@ +/* + * 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.protocol.rest.message.codec; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec; +import org.apache.dubbo.rpc.protocol.rest.message.MediaTypeMatcher; +import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils; + +import java.io.OutputStream; +import java.util.Map; + +@Activate("multiValue") +public class MultiValueCodec implements HttpMessageCodec { + + + @Override + public Object decode(byte[] body, Class targetType) throws Exception { + // TODO java bean get set convert + return DataParseUtils.multipartFormConvert(body); + } + + @Override + public boolean contentTypeSupport(MediaType mediaType,Class targetType) { + return MediaTypeMatcher.MULTI_VALUE.mediaSupport(mediaType); + } + + @Override + public void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception { + DataParseUtils.writeFormContent((Map) unSerializedBody, outputStream); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java new file mode 100644 index 0000000000..0deffe32b1 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.message.codec; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec; + +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +@Activate("string") +public class StringCodec implements HttpMessageCodec { + + + @Override + public Object decode(byte[] body, Class targetType) throws Exception { + return new String(body); + } + + @Override + public boolean contentTypeSupport(MediaType mediaType,Class targetType) { + return String.class.equals(targetType); + } + + + @Override + public void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception { + outputStream.write(((String) unSerializedBody).getBytes(StandardCharsets.UTF_8)); + } + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java new file mode 100644 index 0000000000..c4722d01b3 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.message.codec; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec; +import org.apache.dubbo.rpc.protocol.rest.message.MediaTypeMatcher; +import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils; + +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +@Activate("text") +public class TextCodec implements HttpMessageCodec { + + @Override + public Object decode(byte[] body, Class targetType) throws Exception { + return DataParseUtils.stringTypeConvert(targetType, new String(body, StandardCharsets.UTF_8)); + } + + + @Override + public boolean contentTypeSupport(MediaType mediaType, Class targetType) { + return MediaTypeMatcher.TEXT_PLAIN.mediaSupport(mediaType); + } + + @Override + public void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception { + DataParseUtils.writeTextContent(unSerializedBody, outputStream); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java new file mode 100644 index 0000000000..766ea8064b --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java @@ -0,0 +1,72 @@ +/* + * 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.protocol.rest.message.codec; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec; +import org.apache.dubbo.rpc.protocol.rest.message.MediaTypeMatcher; + +import org.xml.sax.InputSource; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; +import java.io.OutputStream; +import java.io.StringReader; + +@Activate("xml") +public class XMLCodec implements HttpMessageCodec { + + + @Override + public Object decode(byte[] body, Class targetType) throws Exception { + + + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature("http://xml.org/sax/features/external-general-entities", false); + spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + + // Do unmarshall operation + Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(new StringReader(new String(body)))); + + JAXBContext context = JAXBContext.newInstance(targetType); + Unmarshaller unmarshaller = context.createUnmarshaller(); + return unmarshaller.unmarshal(xmlSource); + + } + + @Override + public boolean contentTypeSupport(MediaType mediaType, Class targetType) { + return MediaTypeMatcher.TEXT_XML.mediaSupport(mediaType); + } + + + @Override + public void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception { + Marshaller marshaller = JAXBContext.newInstance(unSerializedBody.getClass()).createMarshaller(); + marshaller.marshal(unSerializedBody, outputStream); + outputStream.write((byte[]) unSerializedBody); + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java new file mode 100644 index 0000000000..d5e587cd93 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java @@ -0,0 +1,215 @@ +/* + * 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.protocol.rest.util; + +import org.apache.dubbo.common.utils.JsonUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +public class DataParseUtils { + + public static Object stringTypeConvert(Class targetType, String value) { + + + if (targetType == Boolean.class) { + return Boolean.valueOf(value); + } + + if (targetType == String.class) { + return value; + } + + if (Number.class.isAssignableFrom(targetType)) { + return NumberUtils.parseNumber(value, targetType); + } + + return value; + + } + + + /** + * content-type text + * + * @param object + * @param outputStream + * @throws IOException + */ + public static void writeTextContent(Object object, OutputStream outputStream) throws IOException { + outputStream.write(objectTextConvertToByteArray(object)); + } + + /** + * content-type json + * + * @param object + * @param outputStream + * @throws Exception + */ + public static void writeJsonContent(Object object, OutputStream outputStream) throws Exception { + outputStream.write(JsonUtils.getJson().toJson(object).getBytes(StandardCharsets.UTF_8)); + } + + /** + * content-type form + * + * @param formData + * @param outputStream + * @throws Exception + */ + public static void writeFormContent(Map formData, OutputStream outputStream) throws Exception { + outputStream.write(serializeForm(formData, Charset.defaultCharset()).getBytes()); + } + + // TODO file multipart + + public static String serializeForm(Map formData, Charset charset) { + StringBuilder builder = new StringBuilder(); + formData.forEach((name, values) -> { + if (name == null) { + + return; + } + ((List) values).forEach(value -> { + try { + if (builder.length() != 0) { + builder.append('&'); + } + builder.append(URLEncoder.encode((String) name, charset.name())); + if (value != null) { + builder.append('='); + builder.append(URLEncoder.encode(String.valueOf(value), charset.name())); + } + } catch (UnsupportedEncodingException ex) { + throw new IllegalStateException(ex); + } + }); + }); + + return builder.toString(); + } + + public static byte[] objectTextConvertToByteArray(Object object) { + Class objectClass = object.getClass(); + + if (objectClass == Boolean.class) { + return object.toString().getBytes(); + } + + if (objectClass == String.class) { + return ((String) object).getBytes(); + } + + if (objectClass.isAssignableFrom(Number.class)) { + return (byte[]) NumberUtils.numberToBytes((Number) object); + } + + return object.toString().getBytes(); + + } + + public static byte[] objectJsonConvertToByteArray(Object object) { + Class objectClass = object.getClass(); + + if (objectClass == Boolean.class) { + return object.toString().getBytes(); + } + + if (objectClass == String.class) { + return ((String) object).getBytes(); + } + + if (objectClass.isAssignableFrom(Number.class)) { + return (byte[]) NumberUtils.numberToBytes((Number) object); + } + + return object.toString().getBytes(); + + } + + public static Object jsonConvert(Class targetType, byte[] body) throws Exception { + return JsonUtils.getJson().toJavaObject(new String(body, StandardCharsets.UTF_8), targetType); + } + + + public static Object multipartFormConvert(byte[] body, Charset charset) throws Exception { + String[] pairs = tokenizeToStringArray(new String(body, StandardCharsets.UTF_8), "&"); + Object result = MultiValueCreator.createMultiValueMap(); + for (String pair : pairs) { + int idx = pair.indexOf('='); + if (idx == -1) { + MultiValueCreator.add(result, URLDecoder.decode(pair, charset.name()), null); + } else { + String name = URLDecoder.decode(pair.substring(0, idx), charset.name()); + String value = URLDecoder.decode(pair.substring(idx + 1), charset.name()); + MultiValueCreator.add(result, name, value); + } + } + + return result; + } + + public static Object multipartFormConvert(byte[] body) throws Exception { + return multipartFormConvert(body, Charset.defaultCharset()); + } + + + public static String[] tokenizeToStringArray(String str, String delimiters) { + return tokenizeToStringArray(str, delimiters, true, true); + } + + public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, + boolean ignoreEmptyTokens) { + if (str == null) { + return null; + } else { + StringTokenizer st = new StringTokenizer(str, delimiters); + ArrayList tokens = new ArrayList(); + + while (true) { + String token; + do { + if (!st.hasMoreTokens()) { + return toStringArray(tokens); + } + + token = st.nextToken(); + if (trimTokens) { + token = token.trim(); + } + } while (ignoreEmptyTokens && token.length() <= 0); + + tokens.add(token); + } + } + } + + public static String[] toStringArray(Collection collection) { + return collection == null ? null : collection.toArray(new String[collection.size()]); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MediaTypeUtil.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MediaTypeUtil.java new file mode 100644 index 0000000000..4a16ea5861 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MediaTypeUtil.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.util; + +import org.apache.dubbo.metadata.rest.media.MediaType; +import org.apache.dubbo.rpc.protocol.rest.exception.UnSupportContentTypeException; + +import java.util.Arrays; +import java.util.List; + +public class MediaTypeUtil { + private static final List mediaTypes = Arrays.asList(MediaType.values()); + + public static MediaType convertMediaType(String... contentTypes) { + + for (String contentType : contentTypes) { + for (MediaType mediaType : mediaTypes) { + + if (contentType != null && contentType.contains(mediaType.value)) { + return mediaType; + } + } + } + + throw new UnSupportContentTypeException(Arrays.toString(contentTypes)); + + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java new file mode 100644 index 0000000000..5c6bf2ac9e --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java @@ -0,0 +1,55 @@ +/* + * 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.protocol.rest.util; + + +import java.lang.reflect.Method; + + +public class MultiValueCreator { + private final static String SPRING_MultiValueMap = "org.springframework.util.LinkedMultiValueMap"; + private final static String JAVAX_MultiValueMap = "org.jboss.resteasy.specimpl.MultivaluedMapImpl"; + + private static Class multiValueMapClass = null; + private static Method multiValueMapAdd = null; + + static { + multiValueMapClass = ReflectUtils.findClassTryException(SPRING_MultiValueMap, JAVAX_MultiValueMap); + multiValueMapAdd = ReflectUtils.getMethodAndTryCatch(multiValueMapClass, "add", new Class[]{Object.class, Object.class}); + } + + + public static Object createMultiValueMap() { + try { + return multiValueMapClass.newInstance(); + } catch (Exception e) { + + } + + return null; + } + + public static void add(Object multiValueMap, String key, String value) { + try { + ReflectUtils.invokeAndTryCatch(multiValueMap, multiValueMapAdd, new String[]{key, value}); + } catch (Exception e) { + + } + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NumberUtils.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NumberUtils.java new file mode 100644 index 0000000000..47aa746bbb --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NumberUtils.java @@ -0,0 +1,149 @@ +/* + * 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.protocol.rest.util; + +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.common.utils.StringUtils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class NumberUtils { + + + public static final Set> STANDARD_NUMBER_TYPES; + + static { + Set> numberTypes = new HashSet<>(8); + numberTypes.add(Byte.class); + numberTypes.add(Short.class); + numberTypes.add(Integer.class); + numberTypes.add(Long.class); + numberTypes.add(BigInteger.class); + numberTypes.add(Float.class); + numberTypes.add(Double.class); + numberTypes.add(BigDecimal.class); + STANDARD_NUMBER_TYPES = Collections.unmodifiableSet(numberTypes); + } + + + public static T parseNumber(String text, Class targetClass) { + Assert.notNull(text, "Text must not be null"); + Assert.notNull(targetClass, "Target class must not be null"); + String trimmed = trimAllWhitespace(text); + + if (Byte.class == targetClass) { + return (T) (isHexNumber(trimmed) ? Byte.decode(trimmed) : Byte.valueOf(trimmed)); + } else if (Short.class == targetClass) { + return (T) (isHexNumber(trimmed) ? Short.decode(trimmed) : Short.valueOf(trimmed)); + } else if (Integer.class == targetClass) { + return (T) (isHexNumber(trimmed) ? Integer.decode(trimmed) : Integer.valueOf(trimmed)); + } else if (Long.class == targetClass) { + return (T) (isHexNumber(trimmed) ? Long.decode(trimmed) : Long.valueOf(trimmed)); + } else if (BigInteger.class == targetClass) { + return (T) (isHexNumber(trimmed) ? decodeBigInteger(trimmed) : new BigInteger(trimmed)); + } else if (Float.class == targetClass) { + return (T) Float.valueOf(trimmed); + } else if (Double.class == targetClass) { + return (T) Double.valueOf(trimmed); + } else if (BigDecimal.class == targetClass || Number.class == targetClass) { + return (T) new BigDecimal(trimmed); + } else { + throw new IllegalArgumentException( + "Cannot convert String [" + text + "] to target class [" + targetClass.getName() + "]"); + } + } + + + private static boolean isHexNumber(String value) { + int index = (value.startsWith("-") ? 1 : 0); + return (value.startsWith("0x", index) || value.startsWith("0X", index) || value.startsWith("#", index)); + } + + + private static BigInteger decodeBigInteger(String value) { + int radix = 10; + int index = 0; + boolean negative = false; + + // Handle minus sign, if present. + if (value.startsWith("-")) { + negative = true; + index++; + } + + // Handle radix specifier, if present. + if (value.startsWith("0x", index) || value.startsWith("0X", index)) { + index += 2; + radix = 16; + } else if (value.startsWith("#", index)) { + index++; + radix = 16; + } else if (value.startsWith("0", index) && value.length() > 1 + index) { + index++; + radix = 8; + } + + BigInteger result = new BigInteger(value.substring(index), radix); + return (negative ? result.negate() : result); + } + + public static String trimAllWhitespace(String str) { + if (StringUtils.isEmpty(str)) { + return str; + } + + int len = str.length(); + StringBuilder sb = new StringBuilder(str.length()); + for (int i = 0; i < len; i++) { + char c = str.charAt(i); + if (!Character.isWhitespace(c)) { + sb.append(c); + } + } + return sb.toString(); + } + + + public static Object numberToBytes(Number number) { + + if (number instanceof Byte) { + // Use default encoding. + return Byte.toString(number.byteValue()).getBytes(); + } else if (number instanceof Double) { + return Double.toString(number.doubleValue()).getBytes(); + } else if (number instanceof Float) { + return Float.toString(number.floatValue()).getBytes(); + } else if (number instanceof Integer) { + return Float.toString(number.intValue()).getBytes(); + } else if (number instanceof Long) { + return Long.toString(number.longValue()).getBytes(); + } else if (number instanceof Short) { + return Short.toString(number.shortValue()).getBytes(); + } else if (number instanceof BigDecimal) { + return BigDecimal.class.cast(number).toString().getBytes(); + } + + return number; + + + } + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/ReflectUtils.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/ReflectUtils.java new file mode 100644 index 0000000000..23b71540e7 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/ReflectUtils.java @@ -0,0 +1,269 @@ +/* + * 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.protocol.rest.util; + + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +public class ReflectUtils { + private final static Class[] EMPTY_CLASS_ARRAY = new Class[0]; + private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + + public static Field getField(Class clazz, String field) throws IllegalAccessException { + Field[] fields = clazz.getDeclaredFields(); + + for (Field field1 : fields) { + if (field1.getName().equals(field)) { + return setModifiersUnFinal(field1); + } + } + + fields = clazz.getFields(); + + for (Field field1 : fields) { + if (field1.getName().equals(field)) { + return setModifiersUnFinal(field1); + } + } + + return null; + } + + + public static Method getMethod(Class clazz, String method, Class[] paramTypes) throws NoSuchMethodException { + Method declaredMethod = clazz.getDeclaredMethod(method, paramTypes); + declaredMethod.setAccessible(true); + return declaredMethod; + } + + private static Field setModifiersUnFinal(Field field) throws IllegalAccessException { + // public +// MODIFIERS.set(field, 1); + field.setAccessible(true); + return field; + } + + public static Class findClass(String name) throws ClassNotFoundException { + + return findClass(Thread.currentThread().getContextClassLoader(), name); + + } + + public static Class findClass(String name, ClassLoader classLoader) throws ClassNotFoundException { + + return classLoader.loadClass(name); + + } + + public static Class findClassAndTryCatch(String name, ClassLoader classLoader) { + + try { + return findClass(name, classLoader); + } catch (Throwable e) { + + } + return null; + + } + + public static Class findClass(String... name) throws ClassNotFoundException { + + return findClass(Thread.currentThread().getContextClassLoader(), name); + } + + + public static Class findClass(ClassLoader classLoader, String... name) throws ClassNotFoundException { + + String[] names = name; + + Class tmp; + for (String s : names) { + tmp = findClassAndTryCatch(s, classLoader); + if (tmp == null) { + continue; + } else { + return tmp; + } + } + throw new ClassNotFoundException(); + } + + + public static Class findClassTryException(ClassLoader classLoader, String... name) { + + try { + return findClass(classLoader, name); + } catch (Exception e) { + + } + return null; + + } + + public static Class findClassTryException(String... name) { + return findClassTryException(Thread.currentThread().getContextClassLoader(), name); + } + + + public static Object getArrayElement(Object obj, int index) { + return Array.get(obj, index); + } + + public static List getArrayElements(Object obj) { + + List objects = new ArrayList(); + int length = Array.getLength(obj); + + if (length == 0) { + return objects; + } + + for (int i = 0; i < length; i++) { + objects.add(Array.get(obj, i)); + } + + return objects; + } + + + public static Field getFieldAndTryCatch(Class clazz, String field) { + + try { + return getField(clazz, field); + } catch (Exception e) { + + } + return null; + } + + public static Method getMethod(Class clazz, String method) throws NoSuchMethodException { + Method declaredMethod = clazz.getDeclaredMethod(method, new Class[]{}); + declaredMethod.setAccessible(true); + return declaredMethod; + } + + public static Method getMethodAndTry(Class clazz, String method) { + Method declaredMethod = null; + try { + declaredMethod = clazz.getDeclaredMethod(method, EMPTY_CLASS_ARRAY); + declaredMethod.setAccessible(true); + } catch (Exception e) { + + } + + if (declaredMethod == null) { + try { + declaredMethod = getMethodByName(clazz, method); + } catch (Exception e) { + + } + } + + return declaredMethod; + } + + public static Object invoke(Object object, Method method) { + try { + return method.invoke(object, EMPTY_OBJECT_ARRAY); + } catch (Exception e) { + return null; + } + } + + public static Object invoke(Object object, Method method, Object[] params) throws InvocationTargetException, IllegalAccessException { + return method.invoke(object, params); + + } + + public static Object invokeAndTryCatch(Object object, Method method, Object[] params) { + try { + return invoke(object, method, params); + } catch (Exception e) { + + } + + return null; + } + + public static Class findClassAndTry(String name) { + + try { + return findClass(name); + } catch (Exception e) { + return null; + } + + } + + public static Method getMethodByName(Class clazz, String name) { + Method[] declaredMethods = clazz.getMethods(); + + for (Method declaredMethod : declaredMethods) { + if (name.equals(declaredMethod.getName())) { + + return declaredMethod; + } + } + + return null; + + } + + + public static Object getValueByFields(Object obj, Field... fields) { + for (Field field : fields) { + + try { + Object o = field.get(obj); + if (o != null) { + return o; + } + } catch (Exception e) { + + } + + } + + return null; + } + + public static Method getMethodAndTryCatch(Class clazz, String method, Class[] paramTypes) { + try { + return getMethod(clazz, method, paramTypes); + } catch (Throwable e) { + + } + return null; + + } + + + public static Object getFieldValueAndTryCatch(Object obj, String field) { + try { + return ReflectUtils.getValueByFields(obj, ReflectUtils.getFieldAndTryCatch(obj.getClass(), field)); + } catch (Exception e) { + return null; + } + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/StreamUtils.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/StreamUtils.java new file mode 100644 index 0000000000..5b597c1724 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/StreamUtils.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; + +public class StreamUtils { + public static String copyToString(InputStream in, Charset charset) throws IOException { + if (in == null) { + return ""; + } else { + StringBuilder out = new StringBuilder(); + InputStreamReader reader = new InputStreamReader(in, charset); + char[] buffer = new char[4096]; + + int bytesRead; + while ((bytesRead = reader.read(buffer)) != -1) { + out.append(buffer, 0, bytesRead); + } + + return out.toString(); + } + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/TypeUtil.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/TypeUtil.java new file mode 100644 index 0000000000..9d768affc2 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/TypeUtil.java @@ -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.protocol.rest.util; + +public class TypeUtil { + + public static boolean isNumber(Class clazz) { + return Number.class.isAssignableFrom(clazz); + } + + public static boolean isPrimitive(Class clazz) { + return clazz.isPrimitive(); + } + + public static boolean isString(Class clazz) { + return clazz == String.class; + } + + public static boolean isNumberType(Class clazz) { + return clazz.isPrimitive() || isNumber(clazz); + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept b/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept new file mode 100644 index 0000000000..e277b45107 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept @@ -0,0 +1,6 @@ +must-intercept=org.apache.dubbo.rpc.protocol.rest.annotation.consumer.inercept.AddMustAttachmentIntercept +attachment=org.apache.dubbo.rpc.protocol.rest.annotation.consumer.inercept.AttachmentIntercept +serialize=org.apache.dubbo.rpc.protocol.rest.annotation.consumer.inercept.SerializeBodyIntercept +path=org.apache.dubbo.rpc.protocol.rest.annotation.consumer.inercept.PathVariableIntercept +header=org.apache.dubbo.rpc.protocol.rest.annotation.consumer.inercept.RequestHeaderIntercept +paramparse=org.apache.dubbo.rpc.protocol.rest.annotation.consumer.inercept.ParamParseIntercept diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser b/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser new file mode 100644 index 0000000000..44bcfc15c3 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser @@ -0,0 +1,5 @@ +consumer-body=org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BodyConsumerParamParser +consumer-header=org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.HeaderConsumerParamParser +consumer-req=org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.ReqOrResConsumerParamParser +consumer-parameter=org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.ParameterConsumerParamParser +consumer-form=org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.FormConsumerParamParser diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec b/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec new file mode 100644 index 0000000000..11a7b32539 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec @@ -0,0 +1,6 @@ +multiValue=org.apache.dubbo.rpc.protocol.rest.message.codec.MultiValueCodec +text=org.apache.dubbo.rpc.protocol.rest.message.codec.TextCodec +json=org.apache.dubbo.rpc.protocol.rest.message.codec.JsonCodec +string=org.apache.dubbo.rpc.protocol.rest.message.codec.StringCodec +byteArray=org.apache.dubbo.rpc.protocol.rest.message.codec.ByteArrayCodec +xml=org.apache.dubbo.rpc.protocol.rest.message.codec.XMLCodec diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java index bb9e4a8f1f..265c6ce382 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java @@ -16,26 +16,23 @@ */ package org.apache.dubbo.rpc.protocol.rest; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; -@Path("/demoService") +@RestController() +@RequestMapping("/demoService") public interface DemoService { - @GET - @Path("/hello") - Integer hello(@QueryParam("a") Integer a, @QueryParam("b") Integer b); + @RequestMapping(value = "/hello", method = RequestMethod.GET) + Integer hello(@RequestParam Integer a, @RequestParam Integer b); - @GET - @Path("/error") + @RequestMapping(value = "/error", method = RequestMethod.GET) String error(); - @POST - @Path("/say") - @Consumes({MediaType.TEXT_PLAIN}) - String sayHello(String name); + @RequestMapping(value = "/say", method = RequestMethod.POST, consumes = MediaType.TEXT_PLAIN_VALUE) + String sayHello(@RequestBody String name); } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java index 3cf9622740..a71fb9f45b 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java @@ -19,12 +19,22 @@ package org.apache.dubbo.rpc.protocol.rest; import org.apache.dubbo.rpc.RpcContext; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; import java.util.Map; - +@Path("/demoService") public class DemoServiceImpl implements DemoService { private static Map context; private boolean called; + @POST + @Path("/say") + @Consumes({MediaType.TEXT_PLAIN}) + @Override public String sayHello(String name) { called = true; return "Hello, " + name; @@ -35,12 +45,17 @@ public class DemoServiceImpl implements DemoService { return called; } + @GET + @Path("/hello") @Override - public Integer hello(Integer a, Integer b) { + public Integer hello(@QueryParam("a") Integer a, @QueryParam("b") Integer b) { context = RpcContext.getServerAttachment().getObjectAttachments(); return a + b; } + + @GET + @Path("/error") @Override public String error() { throw new RuntimeException(); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java similarity index 85% rename from dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java rename to dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java index 758c7fb900..3c4510056b 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java @@ -33,11 +33,14 @@ import org.apache.dubbo.rpc.model.ModuleServiceRepository; import org.apache.dubbo.rpc.model.ProviderModel; import org.apache.dubbo.rpc.model.ServiceDescriptor; +import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestService; +import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestServiceImpl; import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.Arrays; import java.util.Map; import static org.apache.dubbo.remoting.Constants.SERVER_KEY; @@ -47,7 +50,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; -class RestProtocolTest { +class JaxrsRestProtocolTest { private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest"); private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); private final int availablePort = NetUtils.getAvailablePort(); @@ -62,7 +65,8 @@ class RestProtocolTest { @Test void testRestProtocol() { - URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/rest/say?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); + URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); + DemoServiceImpl server = new DemoServiceImpl(); url = this.registerProvider(url, server, DemoService.class); @@ -79,6 +83,38 @@ class RestProtocolTest { exporter.unexport(); } + + @Test + void testAnotherUserRestProtocol() { + URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestService"); + + AnotherUserRestServiceImpl server = new AnotherUserRestServiceImpl(); + + url = this.registerProvider(url, server, DemoService.class); + + Exporter exporter = protocol.export(proxy.getInvoker(server, AnotherUserRestService.class, url)); + Invoker invoker = protocol.refer(AnotherUserRestService.class, url); + + + AnotherUserRestService client = proxy.getProxy(invoker); + User result = client.getUser(123l); + + Assertions.assertEquals(123l, result.getId()); + + result.setName("dubbo"); + Assertions.assertEquals(123l, client.registerUser(result).getId()); + + Assertions.assertEquals("context", client.getContext()); + + byte[] bytes = {1, 2, 3, 4}; + Assertions.assertTrue(Arrays.equals(bytes, client.bytes(bytes))); + + Assertions.assertEquals(1l, client.number(1l)); + + invoker.destroy(); + exporter.unexport(); + } + @Test void testRestProtocolWithContextPath() { DemoServiceImpl server = new DemoServiceImpl(); @@ -184,7 +220,7 @@ class RestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); URL nettyUrl = url.addParameter(SERVER_KEY, "netty") - .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); + .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); @@ -204,7 +240,7 @@ class RestProtocolTest { // use RpcContextFilter URL nettyUrl = url.addParameter(SERVER_KEY, "netty") - .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.RpcContextFilter"); + .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.RpcContextFilter"); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/SpringMvcRestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/SpringMvcRestProtocolTest.java new file mode 100644 index 0000000000..fb63dea8db --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/SpringMvcRestProtocolTest.java @@ -0,0 +1,278 @@ +/* + * 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.protocol.rest; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Protocol; +import org.apache.dubbo.rpc.ProxyFactory; +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.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.model.ModuleServiceRepository; +import org.apache.dubbo.rpc.model.ProviderModel; +import org.apache.dubbo.rpc.model.ServiceDescriptor; +import org.apache.dubbo.rpc.protocol.rest.rest.RestDemoService; +import org.apache.dubbo.rpc.protocol.rest.rest.RestDemoServiceImpl; + +import org.hamcrest.CoreMatchers; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.apache.dubbo.remoting.Constants.SERVER_KEY; +import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +public class SpringMvcRestProtocolTest { + private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest"); + private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); + private final int availablePort = NetUtils.getAvailablePort(); + private final URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); + private final ModuleServiceRepository repository = ApplicationModel.defaultModel().getDefaultModule().getServiceRepository(); + + @AfterEach + public void tearDown() { + protocol.destroy(); + FrameworkModel.destroyAll(); + } + + public RestDemoService getServerImpl() { + return new RestDemoServiceImpl(); + } + + + public Class getServerClass() { + return RestDemoService.class; + } + + public Exporter getExport(URL url, RestDemoService server) { + return protocol.export(proxy.getInvoker(server, getServerClass(), url)); + } + + + @Test + void testRestProtocol() { + URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); + + RestDemoService server = getServerImpl(); + + url = this.registerProvider(url, server, getServerClass()); + + Exporter exporter = getExport(url, server); + Invoker invoker = protocol.refer(DemoService.class, url); + Assertions.assertFalse(server.isCalled()); + + DemoService client = proxy.getProxy(invoker); + String result = client.sayHello("haha"); + Assertions.assertTrue(server.isCalled()); + Assertions.assertEquals("Hello, haha", result); + invoker.destroy(); + exporter.unexport(); + } + + @Test + void testRestProtocolWithContextPath() { + RestDemoService server = getServerImpl(); + Assertions.assertFalse(server.isCalled()); + int port = NetUtils.getAvailablePort(); + URL url = URL.valueOf("rest://127.0.0.1:" + port + "/a/b/c?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); + + url = this.registerProvider(url, server, DemoService.class); + + Exporter exporter = getExport(url, server); + + url = URL.valueOf("rest://127.0.0.1:" + port + "/a/b/c/?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); + Invoker invoker = protocol.refer(DemoService.class, url); + DemoService client = proxy.getProxy(invoker); + String result = client.sayHello("haha"); + Assertions.assertTrue(server.isCalled()); + Assertions.assertEquals("Hello, haha", result); + invoker.destroy(); + exporter.unexport(); + } + + @Test + void testExport() { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + RpcContext.getClientAttachment().setAttachment("timeout", "200"); + Exporter exporter = getExport(url, server); + + DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, url)); + + Integer echoString = demoService.hello(1, 2); + assertThat(echoString, is(3)); + + exporter.unexport(); + } + + @Test + void testNettyServer() { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL nettyUrl = url.addParameter(SERVER_KEY, "netty"); + + Exporter exporter = protocol.export(proxy.getInvoker(server, RestDemoService.class, nettyUrl)); + + DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); + + Integer echoString = demoService.hello(10, 10); + assertThat(echoString, is(20)); + + exporter.unexport(); + } + + @Test + void testServletWithoutWebConfig() { + Assertions.assertThrows(RpcException.class, () -> { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL servletUrl = url.addParameter(SERVER_KEY, "servlet"); + + protocol.export(proxy.getInvoker(server, getServerClass(), servletUrl)); + }); + } + + @Test + void testErrorHandler() { + Assertions.assertThrows(RpcException.class, () -> { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL nettyUrl = url.addParameter(SERVER_KEY, "netty"); + Exporter exporter = getExport(nettyUrl, server); + + DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); + + demoService.error(); + }); + } + + @Test + void testInvoke() { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + Exporter exporter = getExport(url, server); + + RpcInvocation rpcInvocation = new RpcInvocation("hello", DemoService.class.getName(), "", new Class[]{Integer.class, Integer.class}, new Integer[]{2, 3}); + + Result result = exporter.getInvoker().invoke(rpcInvocation); + assertThat(result.getValue(), CoreMatchers.is(5)); + } + + @Test + void testFilter() { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL nettyUrl = url.addParameter(SERVER_KEY, "netty") + .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); + Exporter exporter = getExport(nettyUrl, server); + + DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); + + Integer result = demoService.hello(1, 2); + + assertThat(result, is(3)); + + exporter.unexport(); + } + + @Test + void testRpcContextFilter() { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + // use RpcContextFilter + URL nettyUrl = url.addParameter(SERVER_KEY, "netty") + .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.RpcContextFilter"); + Exporter exporter = protocol.export(proxy.getInvoker(server, RestDemoService.class, nettyUrl)); + + DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); + + // make sure null and base64 encoded string can work + RpcContext.getClientAttachment().setAttachment("key1", null); + RpcContext.getClientAttachment().setAttachment("key2", "value"); + RpcContext.getClientAttachment().setAttachment("key3", "=value"); + RpcContext.getClientAttachment().setAttachment("key4", "YWJjZGVmCg=="); + RpcContext.getClientAttachment().setAttachment("key5", "val=ue"); + Integer result = demoService.hello(1, 2); + + assertThat(result, is(3)); + + Map attachment = RestDemoServiceImpl.getAttachments(); + assertThat(attachment.get("key1"), nullValue()); + assertThat(attachment.get("key2"), equalTo("value")); + assertThat(attachment.get("key3"), equalTo("=value")); + assertThat(attachment.get("key4"), equalTo("YWJjZGVmCg==")); + assertThat(attachment.get("key5"), equalTo("val=ue")); + + exporter.unexport(); + } + + @Test + void testRegFail() { + Assertions.assertThrows(RuntimeException.class, () -> { + RestDemoService server = getServerImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL nettyUrl = url.addParameter(EXTENSION_KEY, "com.not.existing.Filter"); + Exporter exporter = getExport(nettyUrl, server); + }); + } + + @Test + void testDefaultPort() { + assertThat(protocol.getDefaultPort(), is(80)); + } + + private URL registerProvider(URL url, Object impl, Class interfaceClass) { + ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass); + ProviderModel providerModel = new ProviderModel( + url.getServiceKey(), + impl, + serviceDescriptor, + null, + null); + repository.registerProvider(providerModel); + return url.setServiceModel(providerModel); + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java new file mode 100644 index 0000000000..668d8fcafd --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java @@ -0,0 +1,62 @@ +/* + * 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.protocol.rest; + +import java.io.Serializable; + +/** + * User Entity + * + * @since 2.7.6 + */ +public class User implements Serializable { + + private Long id; + + private String name; + + private Integer age; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + @Override + public String toString() { + return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/DemoService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/DemoService.java new file mode 100644 index 0000000000..346ae90184 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/DemoService.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.mvc; + + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController("/demoService") +public interface DemoService { + @RequestMapping(value = "/hello", method = RequestMethod.GET) + Integer hello(@RequestParam Integer a, @RequestParam Integer b); + + @RequestMapping(value = "/error", method = RequestMethod.GET) + String error(); + + @RequestMapping(value = "/sayHello", method = RequestMethod.POST, consumes = MediaType.TEXT_PLAIN_VALUE) + String sayHello(String name); +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/SpringDemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/SpringDemoServiceImpl.java new file mode 100644 index 0000000000..72bf284cf0 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/mvc/SpringDemoServiceImpl.java @@ -0,0 +1,55 @@ +/* + * 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.protocol.rest.mvc; + + +import org.apache.dubbo.rpc.RpcContext; + +import java.util.Map; + +public class SpringDemoServiceImpl implements DemoService { + private static Map context; + private boolean called; + + + @Override + public String sayHello(String name) { + called = true; + return "Hello, " + name; + } + + + public boolean isCalled() { + return called; + } + + @Override + public Integer hello(Integer a, Integer b) { + context = RpcContext.getServerAttachment().getObjectAttachments(); + return a + b; + } + + + @Override + public String error() { + throw new RuntimeException(); + } + + public static Map getAttachments() { + return context; + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestService.java new file mode 100644 index 0000000000..837fdf27c8 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestService.java @@ -0,0 +1,57 @@ +/* + * 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.protocol.rest.rest; + +import org.apache.dubbo.rpc.protocol.rest.User; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("u") +@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML}) +public interface AnotherUserRestService { + + @GET + @Path("{id : \\d+}") + @Produces({MediaType.APPLICATION_JSON}) + User getUser(@PathParam("id") Long id); + + @POST + @Path("register") + @Produces("text/xml; charset=UTF-8") + RegistrationResult registerUser(User user); + + @GET + @Path("context") + @Produces({MediaType.APPLICATION_JSON}) + String getContext(); + + @POST + @Path("bytes") + @Produces({MediaType.APPLICATION_JSON}) + byte[] bytes(byte[] bytes); + + @POST + @Path("number") + @Produces({MediaType.APPLICATION_JSON}) + Long number(Long number); +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestServiceImpl.java new file mode 100644 index 0000000000..42223ebdda --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/AnotherUserRestServiceImpl.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.rest; + +import org.apache.dubbo.rpc.protocol.rest.User; + + +public class AnotherUserRestServiceImpl implements AnotherUserRestService { + + + @Override + public User getUser(Long id) { + + User user = new User(); + user.setId(id); + return user; + } + + @Override + public RegistrationResult registerUser(User user) { + return new RegistrationResult(user.getId()); + } + + @Override + public String getContext() { + + return "context"; + } + + @Override + public byte[] bytes(byte[] bytes) { + return bytes; + } + + @Override + public Long number(Long number) { + return number; + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RegistrationResult.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RegistrationResult.java new file mode 100644 index 0000000000..7f48b95c71 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RegistrationResult.java @@ -0,0 +1,44 @@ +/* + * 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.protocol.rest.rest; + +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; + +/** + * DTO to customize the returned message + */ +@XmlRootElement +public class RegistrationResult implements Serializable { + + private Long id; + + public RegistrationResult() { + } + + public RegistrationResult(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoService.java new file mode 100644 index 0000000000..56384d0725 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoService.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.rest.rest; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + + +@Path("/demoService") +public interface RestDemoService { + @GET + @Path("/hello") + Integer hello(@QueryParam("a")Integer a,@QueryParam("b") Integer b); + + @GET + @Path("/error") + String error(); + + @POST + @Path("/say") + @Consumes({MediaType.TEXT_PLAIN}) + String sayHello(String name); + + boolean isCalled(); +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoServiceImpl.java new file mode 100644 index 0000000000..e9819e5db6 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/rest/RestDemoServiceImpl.java @@ -0,0 +1,55 @@ +/* + * 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.protocol.rest.rest; + +import org.apache.dubbo.rpc.RpcContext; + +import java.util.Map; + + +public class RestDemoServiceImpl implements RestDemoService { + private static Map context; + private boolean called; + + + @Override + public String sayHello(String name) { + called = true; + return "Hello, " + name; + } + + + public boolean isCalled() { + return called; + } + + @Override + public Integer hello(Integer a, Integer b) { + context = RpcContext.getServerAttachment().getObjectAttachments(); + return a + b; + } + + + @Override + public String error() { + throw new RuntimeException(); + } + + public static Map getAttachments() { + return context; + } +} diff --git a/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/SpringmvcDemoService.java b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/SpringmvcDemoService.java new file mode 100644 index 0000000000..18726a05d1 --- /dev/null +++ b/dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/api/SpringmvcDemoService.java @@ -0,0 +1,21 @@ +/* + * 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.test.common.api; + + +public interface SpringmvcDemoService { +} From 6a8ae5c61e631f12eb20323936a0fa7587a30721 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:53:34 +0800 Subject: [PATCH 007/144] Bump micrometer-tracing-bom from 1.0.1 to 1.0.2 (#11607) Bumps [micrometer-tracing-bom](https://github.com/micrometer-metrics/tracing) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/micrometer-metrics/tracing/releases) - [Commits](https://github.com/micrometer-metrics/tracing/compare/v1.0.1...v1.0.2) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-tracing-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index cc437deab3..5b70f4ce3d 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -135,7 +135,7 @@ 1.8.0 0.1.35 1.10.3 - 1.0.1 + 1.0.2 3.3 0.16.0 1.0.4 From 067cb8d79b25fd4e4318cb32df0e26fe7b62553e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:53:50 +0800 Subject: [PATCH 008/144] Bump maven-javadoc-plugin from 3.4.1 to 3.5.0 (#11608) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.4.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.4.1...maven-javadoc-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dfec4c3efb..8336757dd6 100644 --- a/pom.xml +++ b/pom.xml @@ -118,7 +118,7 @@ 2.8.2 3.10.1 3.2.1 - 3.4.1 + 3.5.0 9.4.50.v20221201 3.2.1 0.8.8 From 3214940eb7abff07ea8da1b09f2fa4c44a8c2526 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:54:10 +0800 Subject: [PATCH 009/144] Bump byte-buddy from 1.13.0 to 1.14.0 (#11609) Bumps [byte-buddy](https://github.com/raphw/byte-buddy) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.13.0...byte-buddy-1.14.0) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 5b70f4ce3d..b3615577ea 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -94,7 +94,7 @@ 5.3.25 5.8.1 3.29.2-GA - 1.13.0 + 1.14.0 3.2.10.Final 4.1.87.Final 2.2.1 From 17258a996de283bd3931df473e4a6115ceb8be29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:54:20 +0800 Subject: [PATCH 010/144] Bump reactor-core from 3.5.2 to 3.5.3 (#11610) Bumps [reactor-core](https://github.com/reactor/reactor-core) from 3.5.2 to 3.5.3. - [Release notes](https://github.com/reactor/reactor-core/releases) - [Commits](https://github.com/reactor/reactor-core/compare/v3.5.2...v3.5.3) --- updated-dependencies: - dependency-name: io.projectreactor:reactor-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- dubbo-rpc/dubbo-rpc-triple/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index b3615577ea..77a7a24d9f 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -139,7 +139,7 @@ 3.3 0.16.0 1.0.4 - 3.5.2 + 3.5.3 4.10.0 2.1.1 diff --git a/dubbo-rpc/dubbo-rpc-triple/pom.xml b/dubbo-rpc/dubbo-rpc-triple/pom.xml index d6e08e5611..7e6cf1cfdc 100644 --- a/dubbo-rpc/dubbo-rpc-triple/pom.xml +++ b/dubbo-rpc/dubbo-rpc-triple/pom.xml @@ -31,7 +31,7 @@ false 0.0.4.1-SNAPSHOT 1.0.4 - 3.5.2 + 3.5.3 3.21.12 From 77724f3b7d86d3712abdcf34fdb6182c7b539976 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:54:35 +0800 Subject: [PATCH 011/144] Bump maven-failsafe-plugin from 3.0.0-M8 to 3.0.0-M9 (#11612) Bumps [maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.0.0-M8 to 3.0.0-M9. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.0.0-M8...surefire-3.0.0-M9) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8336757dd6..047e0eff64 100644 --- a/pom.xml +++ b/pom.xml @@ -114,7 +114,7 @@ 3.3.0 3.0.0-M8 - 3.0.0-M8 + 3.0.0-M9 2.8.2 3.10.1 3.2.1 From 77a4e16ec37e083fce024b1bf33a919cd05c3635 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:54:49 +0800 Subject: [PATCH 012/144] Bump libthrift from 0.17.0 to 0.18.0 (#11614) Bumps [libthrift](https://github.com/apache/thrift) from 0.17.0 to 0.18.0. - [Release notes](https://github.com/apache/thrift/releases) - [Changelog](https://github.com/apache/thrift/blob/master/CHANGES.md) - [Commits](https://github.com/apache/thrift/compare/v0.17.0...v0.18.0) --- updated-dependencies: - dependency-name: org.apache.thrift:libthrift dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 77a7a24d9f..db9034f794 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -112,7 +112,7 @@ 1.5.3 1.4.3 3.5.5 - 0.17.0 + 0.18.0 4.0.66 3.19.6 1.3.2 From 57ab2819a35fcabe6c44d366e08843231443a8aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 20:09:31 +0800 Subject: [PATCH 013/144] Bump micrometer-bom from 1.10.3 to 1.10.4 (#11611) Bumps [micrometer-bom](https://github.com/micrometer-metrics/micrometer) from 1.10.3 to 1.10.4. - [Release notes](https://github.com/micrometer-metrics/micrometer/releases) - [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.10.3...v1.10.4) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index db9034f794..d470ea02e3 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -134,7 +134,7 @@ 3.12.0 1.8.0 0.1.35 - 1.10.3 + 1.10.4 1.0.2 3.3 0.16.0 From b2353ad9ff8d9faa92cbd7748c5df7242b5516a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 20:09:42 +0800 Subject: [PATCH 014/144] Bump maven-surefire-plugin from 3.0.0-M8 to 3.0.0-M9 (#11613) Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.0.0-M8 to 3.0.0-M9. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.0.0-M8...surefire-3.0.0-M9) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 047e0eff64..be793127bb 100644 --- a/pom.xml +++ b/pom.xml @@ -113,7 +113,7 @@ UTF-8 3.3.0 - 3.0.0-M8 + 3.0.0-M9 3.0.0-M9 2.8.2 3.10.1 From b62883c17792c60656c5959e9804438557b5dd31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 20:09:55 +0800 Subject: [PATCH 015/144] Bump protobuf-java from 3.21.12 to 3.22.0 (#11615) Bumps [protobuf-java](https://github.com/protocolbuffers/protobuf) from 3.21.12 to 3.22.0. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.21.12...v3.22.0) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-demo/dubbo-demo-triple/pom.xml | 2 +- dubbo-rpc/dubbo-rpc-triple/pom.xml | 2 +- dubbo-xds/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dubbo-demo/dubbo-demo-triple/pom.xml b/dubbo-demo/dubbo-demo-triple/pom.xml index 2ae860a5bd..f420d80d6b 100644 --- a/dubbo-demo/dubbo-demo-triple/pom.xml +++ b/dubbo-demo/dubbo-demo-triple/pom.xml @@ -34,7 +34,7 @@ true 1.8 1.8 - 3.21.12 + 3.22.0 3.10.1 diff --git a/dubbo-rpc/dubbo-rpc-triple/pom.xml b/dubbo-rpc/dubbo-rpc-triple/pom.xml index 7e6cf1cfdc..4862700ff3 100644 --- a/dubbo-rpc/dubbo-rpc-triple/pom.xml +++ b/dubbo-rpc/dubbo-rpc-triple/pom.xml @@ -32,7 +32,7 @@ 0.0.4.1-SNAPSHOT 1.0.4 3.5.3 - 3.21.12 + 3.22.0 diff --git a/dubbo-xds/pom.xml b/dubbo-xds/pom.xml index 6279ea2294..e96257feff 100644 --- a/dubbo-xds/pom.xml +++ b/dubbo-xds/pom.xml @@ -31,7 +31,7 @@ The xDS Integration false - 3.21.12 + 3.22.0 1.41.0 From 2897c856741ed7d642de170e6fca782eea92dc5e Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Wed, 22 Feb 2023 20:26:39 +0800 Subject: [PATCH 016/144] Enhance the way to get dubbo version (#11574) * Enhance the way to get dubbo version * Catch Throwable * Reimplemented using antrun * Enable failOnError --- dubbo-common/pom.xml | 34 +++++++++++++++++-- .../java/org/apache/dubbo/common/Version.java | 28 +++++++++++++-- .../src/main/resources/META-INF/version | 1 + .../dubbo/common/version/VersionTest.java | 12 ++++++- .../src/test/resources/META-INF/version | 3 ++ pom.xml | 6 ++++ 6 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 dubbo-common/src/main/resources/META-INF/version create mode 100644 dubbo-common/src/test/resources/META-INF/version diff --git a/dubbo-common/pom.xml b/dubbo-common/pom.xml index 3205760a5d..335eee3002 100644 --- a/dubbo-common/pom.xml +++ b/dubbo-common/pom.xml @@ -100,8 +100,38 @@ javax.annotation javax.annotation-api - - + + + + org.apache.maven.plugins + maven-antrun-plugin + + + get-version-infos + compile + + true + + + + + + + + + + + + + run + + + + + + diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/Version.java b/dubbo-common/src/main/java/org/apache/dubbo/common/Version.java index 9f9a1d1e11..6b5bb4f279 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/Version.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/Version.java @@ -19,15 +19,19 @@ package org.apache.dubbo.common; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.ClassUtils; +import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.StringUtils; import java.io.IOException; import java.net.URL; import java.security.CodeSource; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Optional; +import java.util.Properties; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -46,8 +50,9 @@ public final class Version { public static final String DEFAULT_DUBBO_PROTOCOL_VERSION = "2.0.2"; // version 1.0.0 represents Dubbo rpc protocol before v2.6.2 public static final int LEGACY_DUBBO_PROTOCOL_VERSION = 10000; // 1.0.0 - // Dubbo implementation version, usually is jar version. - private static final String VERSION = getVersion(Version.class, ""); + // Dubbo implementation version. + private static String VERSION; + private static String LATEST_COMMIT_ID; /** * For protocol compatibility purpose. @@ -61,6 +66,21 @@ public final class Version { static { // check if there's duplicated jar Version.checkDuplicate(Version.class); + + // get dubbo version and last commit id + try { + Properties properties = + ConfigUtils.loadProperties(Collections.emptySet(), "META-INF/version"); + + VERSION = Optional.ofNullable(properties.getProperty("revision")) + .filter(StringUtils::isNotBlank) + .orElseGet(() -> getVersion(Version.class, "")); + LATEST_COMMIT_ID = Optional.ofNullable(properties.getProperty("git.commit.id")).orElse(""); + } catch (Throwable e) { + logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", "continue the old logic, ignore exception " + e.getMessage(), e); + VERSION = getVersion(Version.class, ""); + LATEST_COMMIT_ID = ""; + } } private Version() { @@ -74,6 +94,10 @@ public final class Version { return VERSION; } + public static String getLastCommitId() { + return LATEST_COMMIT_ID; + } + /** * Compare versions * diff --git a/dubbo-common/src/main/resources/META-INF/version b/dubbo-common/src/main/resources/META-INF/version new file mode 100644 index 0000000000..c53621b1ab --- /dev/null +++ b/dubbo-common/src/main/resources/META-INF/version @@ -0,0 +1 @@ +# This is a placeholder file, the real file will be output when the project compiles diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/version/VersionTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/version/VersionTest.java index 39093a8d55..0c6604e74d 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/version/VersionTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/version/VersionTest.java @@ -91,4 +91,14 @@ class VersionTest { Assertions.assertTrue(Version.isRelease263OrHigher("2.6.3")); Assertions.assertTrue(Version.isRelease263OrHigher("2.6.3.0")); } -} \ No newline at end of file + + @Test + void testGetVersion() { + Assertions.assertEquals("1.0.0", Version.getVersion()); + } + + @Test + void testGetLastCommitId() { + Assertions.assertEquals("82a29fcd674216fe9bea10b6efef3196929dd7ca", Version.getLastCommitId()); + } +} diff --git a/dubbo-common/src/test/resources/META-INF/version b/dubbo-common/src/test/resources/META-INF/version new file mode 100644 index 0000000000..2fc6840bf0 --- /dev/null +++ b/dubbo-common/src/test/resources/META-INF/version @@ -0,0 +1,3 @@ +# This is a test file +revision=1.0.0 +git.commit.id=82a29fcd674216fe9bea10b6efef3196929dd7ca diff --git a/pom.xml b/pom.xml index be793127bb..9323273df3 100644 --- a/pom.xml +++ b/pom.xml @@ -124,6 +124,7 @@ 0.8.8 1.3.0 3.2.1 + 3.1.0 true true @@ -801,6 +802,11 @@ jetty-maven-plugin ${maven_jetty_version} + + org.apache.maven.plugins + maven-antrun-plugin + ${maven_antrun_version} + From 671e0f8bb9b7ebb447314660eea062869283888f Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Wed, 22 Feb 2023 20:44:58 +0800 Subject: [PATCH 017/144] Observability task: metadata center (#11593) * init metadata * add pom * add licence * add licence * remove unuse pom * remove unuse pom * remove unuse pom * fix test * fix test * fix test * fix pom * use applicationModel * remove unuse * add test * add push testcase * add test case * add test case * add testcase * rename * opt * debug * fix testcase * add pom --------- Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../apache/dubbo/config/MetricsConfig.java | 19 +- dubbo-config/dubbo-config-api/pom.xml | 6 + .../deploy/DefaultApplicationDeployer.java | 2 +- dubbo-distribution/dubbo-all/pom.xml | 8 + dubbo-distribution/dubbo-bom/pom.xml | 5 + .../ApplicationMetricsCollector.java | 8 +- .../metrics/collector/MetricsCollector.java | 9 +- .../event/GlobalMetricsEventMulticaster.java | 12 +- .../metrics/listener/MetricsLifeListener.java | 6 +- .../metrics/listener/MetricsListener.java | 3 +- .../dubbo/metrics/model/MetricsKey.java | 26 ++- .../metrics/model/MetricsKeyWrapper.java | 4 +- .../SimpleMetricsEventMulticasterTest.java | 8 +- .../metrics/MetricsScopeModelInitializer.java | 2 +- dubbo-metrics/dubbo-metrics-metadata/pom.xml | 40 ++++ .../collector/MetadataMetricsCollector.java | 111 +++++++++ .../collector/stat/MetadataStatComposite.java | 212 ++++++++++++++++++ .../metrics/metadata/event/MetadataEvent.java | 109 +++++++++ .../MetadataMetricsEventMulticaster.java | 31 +++ .../metadata/event/MetricsPushListener.java | 49 ++++ .../event/MetricsSubscribeListener.java | 49 ++++ ...e.dubbo.metrics.collector.MetricsCollector | 1 + .../MetadataMetricsCollectorTest.java | 168 ++++++++++++++ dubbo-metrics/pom.xml | 1 + .../META-INF/native-image/reflect-config.json | 12 +- dubbo-registry/dubbo-registry-api/pom.xml | 18 ++ .../client/AbstractServiceDiscovery.java | 39 +++- dubbo-test/dubbo-dependencies-all/pom.xml | 4 + 28 files changed, 919 insertions(+), 43 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-metadata/pom.xml create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsPushListener.java create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsSubscribeListener.java create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java index 8811d5d612..1b8340138b 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java @@ -16,9 +16,6 @@ */ package org.apache.dubbo.config; -import java.util.HashMap; -import java.util.Map; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.UrlUtils; import org.apache.dubbo.config.nested.AggregationConfig; @@ -26,6 +23,9 @@ import org.apache.dubbo.config.nested.PrometheusConfig; import org.apache.dubbo.config.support.Nested; import org.apache.dubbo.rpc.model.ApplicationModel; +import java.util.HashMap; +import java.util.Map; + /** * MetricsConfig */ @@ -40,6 +40,11 @@ public class MetricsConfig extends AbstractConfig { */ private Boolean enableJvmMetrics; + /** + * Enable jvm metrics when collecting. + */ + private Boolean enableMetadataMetrics; + /** * @deprecated After metrics config is refactored. * This parameter should no longer use and will be deleted in the future. @@ -137,5 +142,13 @@ public class MetricsConfig extends AbstractConfig { public void setExportServicePort(Integer exportServicePort) { this.exportServicePort = exportServicePort; } + + public Boolean getEnableMetadataMetrics() { + return enableMetadataMetrics; + } + + public void setEnableMetadataMetrics(Boolean enableMetadataMetrics) { + this.enableMetadataMetrics = enableMetadataMetrics; + } } diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml index c863389111..2ba42d26a3 100644 --- a/dubbo-config/dubbo-config-api/pom.xml +++ b/dubbo-config/dubbo-config-api/pom.xml @@ -48,6 +48,12 @@ ${project.parent.version} + + org.apache.dubbo + dubbo-metrics-metadata + ${project.parent.version} + + org.apache.dubbo dubbo-monitor-api diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index e5853a9f4c..c526864ab4 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -359,7 +359,7 @@ public class DefaultApplicationDeployer extends AbstractDeployercompile true + + org.apache.dubbo + dubbo-metrics-metadata + ${project.version} + compile + true + @@ -495,6 +502,7 @@ org.apache.dubbo:dubbo-metadata-report-zookeeper org.apache.dubbo:dubbo-metrics-api org.apache.dubbo:dubbo-metrics-default + org.apache.dubbo:dubbo-metrics-metadata org.apache.dubbo:dubbo-metrics-prometheus org.apache.dubbo:dubbo-monitor-api org.apache.dubbo:dubbo-monitor-default diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml index 4b22ec55f9..42b26038cd 100644 --- a/dubbo-distribution/dubbo-bom/pom.xml +++ b/dubbo-distribution/dubbo-bom/pom.xml @@ -240,6 +240,11 @@ dubbo-metrics-prometheus ${project.version} + + org.apache.dubbo + dubbo-metrics-metadata + ${project.version} + diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java index b437561a7b..c1dc63e5b2 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/ApplicationMetricsCollector.java @@ -17,18 +17,18 @@ package org.apache.dubbo.metrics.collector; +import org.apache.dubbo.metrics.event.MetricsEvent; + /** * Application-level collector. * registration center, configuration center and other scenarios * * @Params metrics type */ -public interface ApplicationMetricsCollector extends MetricsCollector { +public interface ApplicationMetricsCollector extends MetricsCollector { void increment(String applicationName, T type); - void decrease(String applicationName, T type); - - void addRT(String applicationName, Long responseTime); + void addRT(String applicationName, String registryOpType, Long responseTime); } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java index d722f77547..3436d4f829 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/collector/MetricsCollector.java @@ -19,7 +19,7 @@ package org.apache.dubbo.metrics.collector; import org.apache.dubbo.common.extension.SPI; import org.apache.dubbo.metrics.event.MetricsEvent; -import org.apache.dubbo.metrics.listener.MetricsListener; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; import org.apache.dubbo.metrics.model.sample.MetricSample; import java.util.List; @@ -29,11 +29,12 @@ import java.util.List; * An interface of collector to collect framework internal metrics. */ @SPI -public interface MetricsCollector extends MetricsListener { +public interface MetricsCollector extends MetricsLifeListener { default boolean isCollectEnabled() { return false; } + /** * Collect metrics as {@link MetricSample} * @@ -41,8 +42,4 @@ public interface MetricsCollector extends MetricsListener { */ List collect(); - @Override - default void onEvent(MetricsEvent event) { - - } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java index b5d4effdfe..28f01d5c27 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/GlobalMetricsEventMulticaster.java @@ -20,15 +20,19 @@ package org.apache.dubbo.metrics.event; import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.metrics.collector.MetricsCollector; -import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.List; +/** + * Global spi event publisher + */ public class GlobalMetricsEventMulticaster extends SimpleMetricsEventMulticaster { - public GlobalMetricsEventMulticaster(FrameworkModel frameworkModel) { - ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); - ExtensionLoader extensionLoader = frameworkModel.getExtensionLoader(MetricsCollector.class); + @SuppressWarnings({"rawtypes"}) + public GlobalMetricsEventMulticaster(ApplicationModel applicationModel) { + ScopeBeanFactory beanFactory = applicationModel.getBeanFactory(); + ExtensionLoader extensionLoader = applicationModel.getExtensionLoader(MetricsCollector.class); if (extensionLoader != null) { List customizeCollectors = extensionLoader .getActivateExtensions(); diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java index 80098f67bf..bee82056be 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsLifeListener.java @@ -24,7 +24,9 @@ import org.apache.dubbo.metrics.event.MetricsEvent; */ public interface MetricsLifeListener extends MetricsListener { - void onEventFinish(E event); + default void onEventFinish(E event) { + } - void onEventError(E event); + default void onEventError(E event) { + } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java index 058f583e94..64b4796af3 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/listener/MetricsListener.java @@ -33,6 +33,7 @@ public interface MetricsListener { * * @param event BaseMetricsEvent */ - void onEvent(E event); + default void onEvent(E event) { + } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java index 7649af788a..96c879c8dd 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java @@ -30,7 +30,6 @@ public enum MetricsKey { METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Unknown Failed Requests"), METRIC_REQUESTS_TOTAL_FAILED("dubbo.%s.requests.failed.total", "Total Failed Requests"), - METRIC_REQUESTS_TOTAL_AGG("dubbo.%s.requests.total.aggregate", "Aggregated Total Requests"), METRIC_REQUESTS_SUCCEED_AGG("dubbo.%s.requests.succeed.aggregate", "Aggregated Succeed Requests"), METRIC_REQUESTS_FAILED_AGG("dubbo.%s.requests.failed.aggregate", "Aggregated Failed Requests"), @@ -60,12 +59,25 @@ public enum MetricsKey { GENERIC_METRIC_RT_P99("dubbo.%s.rt.seconds.p99", "Response Time P99"), GENERIC_METRIC_RT_P95("dubbo.%s.rt.seconds.p95", "Response Time P95"), - THREAD_POOL_CORE_SIZE("dubbo.thread.pool.core.size","Thread Pool Core Size"), - THREAD_POOL_LARGEST_SIZE("dubbo.thread.pool.largest.size","Thread Pool Largest Size"), - THREAD_POOL_MAX_SIZE("dubbo.thread.pool.max.size","Thread Pool Max Size"), - THREAD_POOL_ACTIVE_SIZE("dubbo.thread.pool.active.size","Thread Pool Active Size"), - THREAD_POOL_THREAD_COUNT("dubbo.thread.pool.thread.count","Thread Pool Thread Count"), - THREAD_POOL_QUEUE_SIZE("dubbo.thread.pool.queue.size","Thread Pool Queue Size"); + THREAD_POOL_CORE_SIZE("dubbo.thread.pool.core.size", "Thread Pool Core Size"), + THREAD_POOL_LARGEST_SIZE("dubbo.thread.pool.largest.size", "Thread Pool Largest Size"), + THREAD_POOL_MAX_SIZE("dubbo.thread.pool.max.size", "Thread Pool Max Size"), + THREAD_POOL_ACTIVE_SIZE("dubbo.thread.pool.active.size", "Thread Pool Active Size"), + THREAD_POOL_THREAD_COUNT("dubbo.thread.pool.thread.count", "Thread Pool Thread Count"), + THREAD_POOL_QUEUE_SIZE("dubbo.thread.pool.queue.size", "Thread Pool Queue Size"), + + // metadata push metrics key + METADATA_PUSH_METRIC_NUM("dubbo.metadata.push.num.total", "Total Push Num"), + METADATA_PUSH_METRIC_NUM_SUCCEED("dubbo.metadata.push.num.succeed.total", "Succeed Push Num"), + METADATA_PUSH_METRIC_NUM_FAILED("dubbo.metadata.push.num.failed.total", "Failed Push Num"), + + // metadata subscribe metrics key + METADATA_SUBSCRIBE_METRIC_NUM("dubbo.metadata.subscribe.num.total", "Total Metadata Subscribe Num"), + METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.metadata.subscribe.num.succeed.total", "Succeed Metadata Subscribe Num"), + METADATA_SUBSCRIBE_METRIC_NUM_FAILED("dubbo.metadata.subscribe.num.failed.total", "Failed Metadata Subscribe Num"), + + // consumer metrics key + ; private final String name; private final String description; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java index 0a0afc95e8..54b791e5a8 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKeyWrapper.java @@ -38,8 +38,8 @@ public class MetricsKeyWrapper { return metricsKey; } - public boolean isKey(MetricsKey metricsKey) { - return metricsKey == getMetricsKey(); + public boolean isKey(MetricsKey metricsKey, String registryOpType) { + return metricsKey == getMetricsKey() && registryOpType.equals(getType()); } public String targetKey() { diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java index de5314d803..15f6e66f23 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticasterTest.java @@ -18,6 +18,7 @@ package org.apache.dubbo.metrics.event; import org.apache.dubbo.metrics.listener.MetricsLifeListener; +import org.apache.dubbo.metrics.listener.MetricsListener; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -32,7 +33,12 @@ public class SimpleMetricsEventMulticasterTest { public void setup() { eventMulticaster = new SimpleMetricsEventMulticaster(); obj = new Object[]{new Object()}; - eventMulticaster.addListener(event -> obj[0] = new Object()); + eventMulticaster.addListener(new MetricsListener() { + @Override + public void onEvent(MetricsEvent event) { + obj[0] = new Object(); + } + }); requestEvent = new RequestEvent(obj[0], MetricsEvent.Type.TOTAL); } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java index 6f786b2c67..f8236f60d2 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/MetricsScopeModelInitializer.java @@ -34,7 +34,7 @@ public class MetricsScopeModelInitializer implements ScopeModelInitializer { @Override public void initializeApplicationModel(ApplicationModel applicationModel) { - ScopeBeanFactory beanFactory = applicationModel.getFrameworkModel().getBeanFactory(); + ScopeBeanFactory beanFactory = applicationModel.getBeanFactory(); beanFactory.registerBean(DefaultMetricsCollector.class); beanFactory.registerBean(GlobalMetricsEventMulticaster.class); } diff --git a/dubbo-metrics/dubbo-metrics-metadata/pom.xml b/dubbo-metrics/dubbo-metrics-metadata/pom.xml new file mode 100644 index 0000000000..f454e9558e --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + org.apache.dubbo + dubbo-metrics + ${revision} + ../pom.xml + + dubbo-metrics-metadata + jar + ${project.artifactId} + The metrics module of dubbo project + + false + + + + org.apache.dubbo + dubbo-metrics-api + ${project.parent.version} + + + diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java new file mode 100644 index 0000000000..c9140a288c --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java @@ -0,0 +1,111 @@ +/* + * 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.metrics.metadata.collector; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.config.context.ConfigManager; +import org.apache.dubbo.metrics.collector.ApplicationMetricsCollector; +import org.apache.dubbo.metrics.collector.MetricsCollector; +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.event.MetricsEventMulticaster; +import org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite; +import org.apache.dubbo.metrics.metadata.event.MetadataEvent; +import org.apache.dubbo.metrics.metadata.event.MetadataMetricsEventMulticaster; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + + +/** + * Registry implementation of {@link MetricsCollector} + */ +@Activate +public class MetadataMetricsCollector implements ApplicationMetricsCollector { + + private Boolean collectEnabled = null; + private final MetadataStatComposite stats; + private final MetricsEventMulticaster metadataEventMulticaster; + private final ApplicationModel applicationModel; + + public MetadataMetricsCollector(ApplicationModel applicationModel) { + this.stats = new MetadataStatComposite(); + this.metadataEventMulticaster = new MetadataMetricsEventMulticaster(); + this.applicationModel = applicationModel; + } + + public void setCollectEnabled(Boolean collectEnabled) { + if (collectEnabled != null) { + this.collectEnabled = collectEnabled; + } + } + + @Override + public boolean isCollectEnabled() { + if (collectEnabled == null) { + ConfigManager configManager = applicationModel.getApplicationConfigManager(); + configManager.getMetrics().ifPresent(metricsConfig -> setCollectEnabled(metricsConfig.getEnableMetadataMetrics())); + } + return Optional.ofNullable(collectEnabled).orElse(false); + } + + @Override + public void increment(String applicationName, MetadataEvent.Type registryType) { + this.stats.increment(registryType, applicationName); + } + + @Override + public void addRT(String applicationName, String registryOpType, Long responseTime) { + stats.calcRt(applicationName, registryOpType, responseTime); + } + + @Override + public List collect() { + List list = new ArrayList<>(); + if (!isCollectEnabled()) { + return list; + } + list.addAll(stats.exportNumMetrics()); + list.addAll(stats.exportRtMetrics()); + + return list; + } + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof MetadataEvent; + } + + @Override + public void onEvent(MetadataEvent event) { + metadataEventMulticaster.publishEvent(event); + } + + + @Override + public void onEventFinish(MetadataEvent event) { + metadataEventMulticaster.publishFinishEvent(event); + } + + @Override + public void onEventError(MetadataEvent event) { + metadataEventMulticaster.publishErrorEvent(event); + } +} diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java new file mode 100644 index 0000000000..83cdbb855c --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java @@ -0,0 +1,212 @@ +/* + * 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.metrics.metadata.collector.stat; + +import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; +import org.apache.dubbo.metrics.collector.MetricsCollector; +import org.apache.dubbo.metrics.model.ApplicationMetric; +import org.apache.dubbo.metrics.model.MetricsCategory; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.metadata.event.MetadataEvent; +import org.apache.dubbo.metrics.report.MetricsExport; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.LongAccumulator; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * As a data aggregator, use internal data containers calculates and classifies + * the registry data collected by {@link MetricsCollector MetricsCollector}, and + * provides an {@link MetricsExport MetricsExport} interface for exporting standard output formats. + */ +public class MetadataStatComposite implements MetricsExport { + + + public Map> numStats = new ConcurrentHashMap<>(); + public List> rtStats = new ArrayList<>(); + public static String OP_TYPE_PUSH = "push"; + public static String OP_TYPE_SUBSCRIBE = "subscribe"; + + public MetadataStatComposite() { + for (MetadataEvent.Type type : MetadataEvent.Type.values()) { + numStats.put(type, new ConcurrentHashMap<>()); + } + + rtStats.addAll(initStats(OP_TYPE_PUSH)); + rtStats.addAll(initStats(OP_TYPE_SUBSCRIBE)); + } + + private List> initStats(String registryOpType) { + List> singleRtStats = new ArrayList<>(); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_LAST))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MIN), new LongAccumulator(Long::min, Long.MAX_VALUE))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MAX), new LongAccumulator(Long::max, Long.MIN_VALUE))); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_SUM), (responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime))); + // AvgContainer is a special counter that stores the number of times but outputs function of sum/times + AtomicLongContainer avgContainer = new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_AVG), (k, v) -> v.incrementAndGet()); + avgContainer.setValueSupplier(applicationName -> { + LongContainer totalContainer = rtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.GENERIC_METRIC_RT_SUM, registryOpType)).findFirst().get(); + AtomicLong totalRtTimes = avgContainer.get(applicationName); + AtomicLong totalRtSum = (AtomicLong) totalContainer.get(applicationName); + return totalRtSum.get() / totalRtTimes.get(); + }); + singleRtStats.add(avgContainer); + return singleRtStats; + } + + public void increment(MetadataEvent.Type type, String applicationName) { + if (!numStats.containsKey(type)) { + return; + } + numStats.get(type).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).incrementAndGet(); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + public void calcRt(String applicationName, String registryOpType, Long responseTime) { + for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { + Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, applicationName, container.getInitFunc()); + container.getConsumerFunc().accept(responseTime, current); + } + } + + @Override + public List exportNumMetrics() { + List list = new ArrayList<>(); + for (MetadataEvent.Type type : numStats.keySet()) { + Map stringAtomicLongMap = numStats.get(type); + for (String applicationName : stringAtomicLongMap.keySet()) { + list.add(convertToSample(applicationName, type, MetricsCategory.REGISTRY, stringAtomicLongMap.get(applicationName))); + } + } + return list; + } + + @Override + public List exportRtMetrics() { + List list = new ArrayList<>(); + for (LongContainer rtContainer : rtStats) { + MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); + for (Map.Entry entry : rtContainer.entrySet()) { + list.add(new GaugeMetricSample(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, () -> rtContainer.getValueSupplier().apply(entry.getKey()))); + } + } + return list; + } + + public GaugeMetricSample convertToSample(String applicationName, MetadataEvent.Type type, MetricsCategory category, AtomicLong targetNumber) { + return new GaugeMetricSample(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber::get); + } + + + /** + * Collect Number type data + * + * @param + */ + public static class LongContainer extends ConcurrentHashMap { + + /** + * Provide the metric type name + */ + private final MetricsKeyWrapper metricsKeyWrapper; + /** + * The initial value corresponding to the key is generally 0 of different data types + */ + private final Function initFunc; + /** + * Statistical data calculation function, which can be self-increment, self-decrement, or more complex avg function + */ + private final BiConsumer consumerFunc; + /** + * Data output function required by {@link GaugeMetricSample GaugeMetricSample} + */ + private Function valueSupplier; + + + public LongContainer(MetricsKeyWrapper metricsKeyWrapper, Supplier initFunc, BiConsumer consumerFunc) { + this.metricsKeyWrapper = metricsKeyWrapper; + this.initFunc = s -> initFunc.get(); + this.consumerFunc = consumerFunc; + this.valueSupplier = k -> this.get(k).longValue(); + } + + public boolean specifyType(String type) { + return type.equals(getMetricsKeyWrapper().getType()); + } + + public MetricsKeyWrapper getMetricsKeyWrapper() { + return metricsKeyWrapper; + } + + public boolean isKeyWrapper(MetricsKey metricsKey, String registryOpType) { + return metricsKeyWrapper.isKey(metricsKey,registryOpType); + } + + public Function getInitFunc() { + return initFunc; + } + + public BiConsumer getConsumerFunc() { + return consumerFunc; + } + + public Function getValueSupplier() { + return valueSupplier; + } + + public void setValueSupplier(Function valueSupplier) { + this.valueSupplier = valueSupplier; + } + + @Override + public String toString() { + return "LongContainer{" + + "metricsKeyWrapper=" + metricsKeyWrapper + + '}'; + } + } + + public static class AtomicLongContainer extends LongContainer { + + public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper) { + super(metricsKeyWrapper, AtomicLong::new, (responseTime, longAccumulator) -> longAccumulator.set(responseTime)); + } + + public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper, BiConsumer consumerFunc) { + super(metricsKeyWrapper, AtomicLong::new, consumerFunc); + } + + } + + public static class LongAccumulatorContainer extends LongContainer { + public LongAccumulatorContainer(MetricsKeyWrapper metricsKeyWrapper, LongAccumulator accumulator) { + super(metricsKeyWrapper, () -> accumulator, (responseTime, longAccumulator) -> longAccumulator.accumulate(responseTime)); + } + } + + +} diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java new file mode 100644 index 0000000000..8d68e5a189 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataEvent.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.metrics.metadata.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.event.TimeCounter; +import org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.rpc.model.ApplicationModel; + +/** + * Registry related events + */ +public class MetadataEvent extends MetricsEvent implements TimeCounter { + private final TimePair timePair; + private final MetadataMetricsCollector collector; + private final boolean available; + + public MetadataEvent(ApplicationModel applicationModel, TimePair timePair) { + super(applicationModel); + this.timePair = timePair; + this.collector = applicationModel.getBeanFactory().getBean(MetadataMetricsCollector.class); + this.available = this.collector != null && collector.isCollectEnabled(); + } + + public ApplicationModel getSource() { + return (ApplicationModel) source; + } + + public MetadataMetricsCollector getCollector() { + return collector; + } + + public boolean isAvailable() { + return available; + } + + @Override + public TimePair getTimePair() { + return timePair; + } + + public enum Type { + P_TOTAL(MetricsKey.METADATA_PUSH_METRIC_NUM), + P_SUCCEED(MetricsKey.METADATA_PUSH_METRIC_NUM_SUCCEED), + P_FAILED(MetricsKey.METADATA_PUSH_METRIC_NUM_FAILED), + + S_TOTAL(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM), + S_SUCCEED(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED), + S_FAILED(MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM_FAILED), + + ; + + + private final MetricsKey metricsKey; + private final boolean isIncrement; + + + Type(MetricsKey metricsKey) { + this(metricsKey, true); + } + + Type(MetricsKey metricsKey, boolean isIncrement) { + this.metricsKey = metricsKey; + this.isIncrement = isIncrement; + } + + public MetricsKey getMetricsKey() { + return metricsKey; + } + + public boolean isIncrement() { + return isIncrement; + } + } + + public static class PushEvent extends MetadataEvent { + + public PushEvent(ApplicationModel applicationModel, TimePair timePair) { + super(applicationModel, timePair); + } + + } + + public static class SubscribeEvent extends MetadataEvent { + + public SubscribeEvent(ApplicationModel applicationModel, TimePair timePair) { + super(applicationModel, timePair); + } + + } + +} diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java new file mode 100644 index 0000000000..92b3c96da3 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetadataMetricsEventMulticaster.java @@ -0,0 +1,31 @@ +/* + * 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.metrics.metadata.event; + +import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster; + +public final class MetadataMetricsEventMulticaster extends SimpleMetricsEventMulticaster { + + public MetadataMetricsEventMulticaster() { + super.addListener(new MetricsPushListener()); + super.addListener(new MetricsSubscribeListener()); + + setAvailable(); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsPushListener.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsPushListener.java new file mode 100644 index 0000000000..d08ec366c8 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsPushListener.java @@ -0,0 +1,49 @@ +/* + * 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.metrics.metadata.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; + +import static org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_PUSH; + +public class MetricsPushListener implements MetricsLifeListener { + + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof MetadataEvent.PushEvent && ((MetadataEvent) event).isAvailable(); + } + + @Override + public void onEvent(MetadataEvent.PushEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), MetadataEvent.Type.P_TOTAL); + } + + @Override + public void onEventFinish(MetadataEvent.PushEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), MetadataEvent.Type.P_SUCCEED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_PUSH, event.getTimePair().calc()); + } + + @Override + public void onEventError(MetadataEvent.PushEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), MetadataEvent.Type.P_FAILED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_PUSH, event.getTimePair().calc()); + } +} diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsSubscribeListener.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsSubscribeListener.java new file mode 100644 index 0000000000..a247f539a5 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/event/MetricsSubscribeListener.java @@ -0,0 +1,49 @@ +/* + * 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.metrics.metadata.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; + +import static org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_SUBSCRIBE; + +public class MetricsSubscribeListener implements MetricsLifeListener { + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof MetadataEvent.SubscribeEvent && ((MetadataEvent) event).isAvailable(); + } + + @Override + public void onEvent(MetadataEvent.SubscribeEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), MetadataEvent.Type.S_TOTAL); + } + + @Override + public void onEventFinish(MetadataEvent.SubscribeEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), MetadataEvent.Type.S_SUCCEED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_SUBSCRIBE, event.getTimePair().calc()); + } + + @Override + public void onEventError(MetadataEvent.SubscribeEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), MetadataEvent.Type.S_FAILED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_SUBSCRIBE, event.getTimePair().calc()); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector b/dubbo-metrics/dubbo-metrics-metadata/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector new file mode 100644 index 0000000000..c90627a2d0 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector @@ -0,0 +1 @@ +metadata-collector=org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java new file mode 100644 index 0000000000..a07712bccd --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java @@ -0,0 +1,168 @@ +/* + * 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 metrics.metrics.collector; + +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector; +import org.apache.dubbo.metrics.metadata.event.MetadataEvent; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; +import static org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_PUSH; +import static org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_SUBSCRIBE; + + +class MetadataMetricsCollectorTest { + + private ApplicationModel applicationModel; + + @BeforeEach + public void setup() { + FrameworkModel frameworkModel = FrameworkModel.defaultModel(); + applicationModel = frameworkModel.newApplication(); + ApplicationConfig config = new ApplicationConfig(); + config.setName("MockMetrics"); + + applicationModel.getApplicationConfigManager().setApplication(config); + + } + + @AfterEach + public void teardown() { + applicationModel.destroy(); + } + + @Test + void testPushMetrics() throws InterruptedException { + + TimePair timePair = TimePair.start(); + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getOrRegisterBean(GlobalMetricsEventMulticaster.class); + MetadataMetricsCollector collector = applicationModel.getBeanFactory().getOrRegisterBean(MetadataMetricsCollector.class); + collector.setCollectEnabled(true); + + eventMulticaster.publishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); + List metricSamples = collector.collect(); + + // push success +1 + Assertions.assertEquals(metricSamples.size(), 1); + Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); + Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.METADATA_PUSH_METRIC_NUM.getName()); + + eventMulticaster.publishFinishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); + // push finish rt +1 + metricSamples = collector.collect(); + //num(total+success) + rt(5) = 7 + Assertions.assertEquals(metricSamples.size(), 7); + long c1 = timePair.calc(); + TimePair lastTimePair = TimePair.start(); + eventMulticaster.publishEvent(new MetadataEvent.PushEvent(applicationModel, lastTimePair)); + Thread.sleep(50); + // push error rt +1 + eventMulticaster.publishErrorEvent(new MetadataEvent.PushEvent(applicationModel, lastTimePair)); + long c2 = lastTimePair.calc(); + metricSamples = collector.collect(); + + // num(total+success+error) + rt(5) + Assertions.assertEquals(metricSamples.size(), 8); + + // calc rt + for (MetricSample sample : metricSamples) { + Map tags = sample.getTags(); + Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationModel.getApplicationName()); + } + Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { + Number number = ((GaugeMetricSample) k).getSupplier().get(); + return number.longValue(); + })); + + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc()); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), c1 + c2); + } + + @Test + void testSubscribeMetrics() throws InterruptedException { + + TimePair timePair = TimePair.start(); + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getOrRegisterBean(GlobalMetricsEventMulticaster.class); + MetadataMetricsCollector collector = applicationModel.getBeanFactory().getOrRegisterBean(MetadataMetricsCollector.class); + collector.setCollectEnabled(true); + + eventMulticaster.publishEvent(new MetadataEvent.SubscribeEvent(applicationModel, timePair)); + List metricSamples = collector.collect(); + + // push success +1 + Assertions.assertEquals(metricSamples.size(), 1); + Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); + Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM.getName()); + + eventMulticaster.publishFinishEvent(new MetadataEvent.SubscribeEvent(applicationModel, timePair)); + // push finish rt +1 + metricSamples = collector.collect(); + //num(total+success) + rt(5) = 7 + Assertions.assertEquals(metricSamples.size(), 7); + long c1 = timePair.calc(); + TimePair lastTimePair = TimePair.start(); + eventMulticaster.publishEvent(new MetadataEvent.SubscribeEvent(applicationModel, lastTimePair)); + Thread.sleep(50); + // push error rt +1 + eventMulticaster.publishErrorEvent(new MetadataEvent.SubscribeEvent(applicationModel, lastTimePair)); + long c2 = lastTimePair.calc(); + metricSamples = collector.collect(); + + // num(total+success+error) + rt(5) + Assertions.assertEquals(metricSamples.size(), 8); + + // calc rt + for (MetricSample sample : metricSamples) { + Map tags = sample.getTags(); + Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationModel.getApplicationName()); + } + Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { + Number number = ((GaugeMetricSample) k).getSupplier().get(); + return number.longValue(); + })); + + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc()); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), c1 + c2); + } + + +} diff --git a/dubbo-metrics/pom.xml b/dubbo-metrics/pom.xml index c504428498..835c2b1b44 100644 --- a/dubbo-metrics/pom.xml +++ b/dubbo-metrics/pom.xml @@ -20,6 +20,7 @@ dubbo-metrics-api dubbo-metrics-default + dubbo-metrics-metadata dubbo-metrics-prometheus diff --git a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json index 8ffe07af6c..816a1aff40 100644 --- a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json +++ b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json @@ -2110,6 +2110,16 @@ } ] }, + { + "name": "org.apache.dubbo.metrics.MetricsScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, { "name": "org.apache.dubbo.rpc.cluster.ConfiguratorFactory", "allPublicMethods": true @@ -2908,7 +2918,7 @@ "methods": [ { "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] } diff --git a/dubbo-registry/dubbo-registry-api/pom.xml b/dubbo-registry/dubbo-registry-api/pom.xml index 8cb1496544..f9c580f8c9 100644 --- a/dubbo-registry/dubbo-registry-api/pom.xml +++ b/dubbo-registry/dubbo-registry-api/pom.xml @@ -80,5 +80,23 @@ zookeeper test + + org.apache.dubbo + dubbo-metrics-api + ${project.parent.version} + compile + + + org.apache.dubbo + dubbo-metrics-default + ${project.parent.version} + compile + + + org.apache.dubbo + dubbo-metrics-metadata + ${project.parent.version} + compile + diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java index 6241fe1778..edb974da48 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java @@ -16,14 +16,6 @@ */ package org.apache.dubbo.registry.client; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -34,6 +26,9 @@ import org.apache.dubbo.metadata.MetadataInfo; import org.apache.dubbo.metadata.report.MetadataReport; import org.apache.dubbo.metadata.report.MetadataReportInstance; import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.metadata.event.MetadataEvent; +import org.apache.dubbo.metrics.model.TimePair; import org.apache.dubbo.registry.NotifyListener; import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; import org.apache.dubbo.registry.client.metadata.MetadataUtils; @@ -41,6 +36,14 @@ import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils; import org.apache.dubbo.registry.client.metadata.store.MetaCacheManager; import org.apache.dubbo.rpc.model.ApplicationModel; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_INFO_CACHE_EXPIRE; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_INFO_CACHE_SIZE; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; @@ -225,12 +228,19 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery { // try to load metadata from remote. int triedTimes = 0; while (triedTimes < 3) { + + TimePair timePair = TimePair.start(); + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); + eventMulticaster.publishEvent(new MetadataEvent.SubscribeEvent(applicationModel, timePair)); + metadata = MetadataUtils.getRemoteMetadata(revision, instances, metadataReport); if (metadata != MetadataInfo.EMPTY) {// succeeded metadata.init(); + eventMulticaster.publishFinishEvent(new MetadataEvent.SubscribeEvent(applicationModel, timePair)); break; } else {// failed + eventMulticaster.publishErrorEvent(new MetadataEvent.SubscribeEvent(applicationModel, timePair)); if (triedTimes > 0) { if (logger.isDebugEnabled()) { logger.debug("Retry the " + triedTimes + " times to get metadata for revision=" + revision); @@ -301,7 +311,7 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery { * Can be override if registry support update instance directly. *
* NOTICE: Remind to update {@link AbstractServiceDiscovery#serviceInstance}'s reference if updated - * and report metadata by {@link AbstractServiceDiscovery#reportMetadata(MetadataInfo)} + * and report metadata by {@link AbstractServiceDiscovery#reportMetadata(MetadataInfo)} * * @param oldServiceInstance origin service instance * @param newServiceInstance new service instance @@ -351,12 +361,21 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery { if (metadataInfo == null) { return; } + TimePair timePair = TimePair.start(); + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); + eventMulticaster.publishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); if (metadataReport != null) { SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.getRevision()); if ((DEFAULT_METADATA_STORAGE_TYPE.equals(metadataType) && metadataReport.shouldReportMetadata()) || REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) { - metadataReport.publishAppMetadata(identifier, metadataInfo); + try { + metadataReport.publishAppMetadata(identifier, metadataInfo); + } catch (IllegalStateException e) { + eventMulticaster.publishErrorEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); + throw e; + } } } + eventMulticaster.publishFinishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); MetadataInfo clonedMetadataInfo = metadataInfo.clone(); metadataInfos.put(metadataInfo.getRevision(), new MetadataInfoStat(clonedMetadataInfo)); } diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index f97e0a6945..66f84b58f6 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -148,6 +148,10 @@ org.apache.dubbo dubbo-metrics-default + + org.apache.dubbo + dubbo-metrics-metadata + org.apache.dubbo dubbo-metrics-prometheus From c5a03c94581e6a68443146ead2b632c34c2f6138 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 23 Feb 2023 09:40:25 +0800 Subject: [PATCH 018/144] Rest bugfix & optimization (#11617) * Modifier optimize * rawtypes problem optimize * Remove commented redundant code * Constants optimize * Fix consistency bug * Support exception mapper extension * resolve conflict --- .../protocol/rest/BaseRestProtocolServer.java | 12 +++---- .../dubbo/rpc/protocol/rest/Constants.java | 14 +++++++- .../rest/DubboHttpProtocolServer.java | 9 +++-- .../protocol/rest/DubboResourceFactory.java | 22 ++---------- .../rest/NettyRestProtocolServer.java | 3 +- .../protocol/rest/ReferenceCountedClient.java | 2 +- .../dubbo/rpc/protocol/rest/RestProtocol.java | 35 +++++++++++-------- .../rpc/protocol/rest/RestProtocolServer.java | 4 +-- .../rpc/protocol/rest/RestServerFactory.java | 5 ++- .../rpc/protocol/rest/RpcContextFilter.java | 9 ++--- .../rpc/protocol/rest/RpcExceptionMapper.java | 11 +++--- .../protocol/rest/JaxrsRestProtocolTest.java | 31 ++++++++++++++-- .../protocol/rest/RpcExceptionMapperTest.java | 4 +-- 13 files changed, 94 insertions(+), 67 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java index 95bdccb707..baa0fff9cc 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/BaseRestProtocolServer.java @@ -25,22 +25,22 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN; +import static org.apache.dubbo.rpc.protocol.rest.Constants.EXCEPTION_MAPPER_KEY; import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY; public abstract class BaseRestProtocolServer implements RestProtocolServer { private String address; - private Map attributes = new ConcurrentHashMap<>(); + private final Map attributes = new ConcurrentHashMap<>(); @Override public void start(URL url) { getDeployment().getMediaTypeMappings().put("json", "application/json"); getDeployment().getMediaTypeMappings().put("xml", "text/xml"); -// server.getDeployment().getMediaTypeMappings().put("xml", "application/xml"); getDeployment().getProviderClasses().add(RpcContextFilter.class.getName()); - // TODO users can override this mapper, but we just rely on the current priority strategy of resteasy - getDeployment().getProviderClasses().add(RpcExceptionMapper.class.getName()); + + loadProviders(url.getParameter(EXCEPTION_MAPPER_KEY, RpcExceptionMapper.class.getName())); loadProviders(url.getParameter(EXTENSION_KEY, "")); @@ -48,7 +48,7 @@ public abstract class BaseRestProtocolServer implements RestProtocolServer { } @Override - public void deploy(Class resourceDef, Object resourceInstance, String contextPath) { + public void deploy(Class resourceDef, Object resourceInstance, String contextPath) { if (StringUtils.isEmpty(contextPath)) { getDeployment().getRegistry().addResourceFactory(new DubboResourceFactory(resourceInstance, resourceDef)); } else { @@ -57,7 +57,7 @@ public abstract class BaseRestProtocolServer implements RestProtocolServer { } @Override - public void undeploy(Class resourceDef) { + public void undeploy(Class resourceDef) { getDeployment().getRegistry().removeRegistrations(resourceDef); } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java index 90747c9a3a..8966315425 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/Constants.java @@ -18,7 +18,7 @@ package org.apache.dubbo.rpc.protocol.rest; /** - * + * Constants definition. */ public interface Constants { String KEEP_ALIVE_KEY = "keepalive"; @@ -26,4 +26,16 @@ public interface Constants { boolean DEFAULT_KEEP_ALIVE = true; String EXTENSION_KEY = "extension"; + + // http server + String SERVLET = "servlet"; + + String JETTY = "jetty"; + + String TOMCAT = "tomcat"; + + String NETTY = "netty"; + + // exception mapper + String EXCEPTION_MAPPER_KEY = "exception.mapper"; } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java index 71db6b963a..475238d548 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboHttpProtocolServer.java @@ -40,9 +40,8 @@ public class DubboHttpProtocolServer extends BaseRestProtocolServer { private final HttpServletDispatcher dispatcher = new HttpServletDispatcher(); private final ResteasyDeployment deployment = new ResteasyDeployment(); - private HttpBinder httpBinder; + private final HttpBinder httpBinder; private HttpServer httpServer; -// private boolean isExternalServer; public DubboHttpProtocolServer(HttpBinder httpBinder) { this.httpBinder = httpBinder; @@ -114,15 +113,15 @@ public class DubboHttpProtocolServer extends BaseRestProtocolServer { } @Override - public Enumeration getInitParameterNames() { - return new Enumeration() { + public Enumeration getInitParameterNames() { + return new Enumeration() { @Override public boolean hasMoreElements() { return false; } @Override - public Object nextElement() { + public String nextElement() { return null; } }; diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java index 191102e2cd..ac8695ccc4 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/DubboResourceFactory.java @@ -23,24 +23,17 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory; /** * We don't support propertyInjector here since the resource impl should be singleton in dubbo - * */ public class DubboResourceFactory implements ResourceFactory { - private Object resourceInstance; - private Class scannableClass; -// private PropertyInjector propertyInjector; -// private String context = null; + private final Object resourceInstance; + private final Class scannableClass; - public DubboResourceFactory(Object resourceInstance, Class scannableClass) { + public DubboResourceFactory(Object resourceInstance, Class scannableClass) { this.resourceInstance = resourceInstance; this.scannableClass = scannableClass; } -// public PropertyInjector getPropertyInjector() { -// return propertyInjector; -// } - @Override public Object createResource(HttpRequest request, HttpResponse response, ResteasyProviderFactory factory) { @@ -54,7 +47,6 @@ public class DubboResourceFactory implements ResourceFactory { @Override public void registered(ResteasyProviderFactory factory) { -// this.propertyInjector = factory.getInjectorFactory().createPropertyInjector(getScannableClass(), factory); } @Override @@ -65,12 +57,4 @@ public class DubboResourceFactory implements ResourceFactory { @Override public void unregistered() { } - -// public void setContext(String context) { -// this.context = context; -// } -// -// public String getContext() { -// return context; -// } } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java index b066c79f43..fbb9be782e 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyRestProtocolServer.java @@ -46,13 +46,14 @@ public class NettyRestProtocolServer extends BaseRestProtocolServer { private final NettyJaxrsServer server = new NettyJaxrsServer(); @Override + @SuppressWarnings("rawtypes") protected void doStart(URL url) { String bindIp = url.getParameter(BIND_IP_KEY, url.getHost()); if (!url.isAnyHost() && NetUtils.isValidLocalHost(bindIp)) { server.setHostname(bindIp); } server.setPort(url.getParameter(BIND_PORT_KEY, url.getPort())); - Map channelOption = new HashMap(); + Map channelOption = new HashMap<>(); channelOption.put(ChannelOption.SO_KEEPALIVE, url.getParameter(KEEP_ALIVE_KEY, DEFAULT_KEEP_ALIVE)); server.setChildChannelOptions(channelOption); server.setExecutorThreadCount(url.getParameter(THREADS_KEY, DEFAULT_THREADS)); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java index fc8d4664c8..22de2147c2 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java @@ -26,7 +26,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERR public class ReferenceCountedClient extends ReferenceCountedResource { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ReferenceCountedClient.class); - private T client; + private final T client; public ReferenceCountedClient(T client) { this.client = client; diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java index 90e254be71..4cd8376263 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java @@ -65,12 +65,12 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERR import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_CLOSE_SERVER; import static org.apache.dubbo.remoting.Constants.SERVER_KEY; import static org.apache.dubbo.rpc.Constants.TOKEN_KEY; +import static org.apache.dubbo.rpc.protocol.rest.constans.RestConstant.PATH_SEPARATOR; public class RestProtocol extends AbstractProxyProtocol { private static final int DEFAULT_PORT = 80; - private static final String DEFAULT_SERVER = "jetty"; - private static final String DEFAULT_CLIENT = org.apache.dubbo.remoting.Constants.OK_HTTP; + private static final String DEFAULT_SERVER = Constants.JETTY; private final RestServerFactory serverFactory = new RestServerFactory(); @@ -95,7 +95,7 @@ public class RestProtocol extends AbstractProxyProtocol { @Override protected Runnable doExport(T impl, Class type, URL url) throws RpcException { String addr = getAddr(url); - Class implClass = url.getServiceModel().getProxyObject().getClass(); + Class implClass = url.getServiceModel().getProxyObject().getClass(); RestProtocolServer server = (RestProtocolServer) ConcurrentHashMapUtils.computeIfAbsent(serverMap, addr, restServer -> { RestProtocolServer s = serverFactory.createServer(url.getParameter(SERVER_KEY, DEFAULT_SERVER)); s.setAddress(url.getAddress()); @@ -104,7 +104,7 @@ public class RestProtocol extends AbstractProxyProtocol { }); String contextPath = getContextPath(url); - if ("servlet".equalsIgnoreCase(url.getParameter(SERVER_KEY, DEFAULT_SERVER))) { + if (Constants.SERVLET.equalsIgnoreCase(url.getParameter(SERVER_KEY, DEFAULT_SERVER))) { ServletContext servletContext = ServletManager.getInstance().getServletContext(ServletManager.EXTERNAL_SERVER_PORT); if (servletContext == null) { throw new RpcException("No servlet context found. Since you are using server='servlet', " + @@ -118,13 +118,13 @@ public class RestProtocol extends AbstractProxyProtocol { "make sure that the 'contextpath' property starts with the path of external webapp"); } contextPath = contextPath.substring(webappPath.length()); - if (contextPath.startsWith("/")) { + if (contextPath.startsWith(PATH_SEPARATOR)) { contextPath = contextPath.substring(1); } } } - final Class resourceDef = GetRestful.getRootResourceClass(implClass) != null ? implClass : type; + final Class resourceDef = GetRestful.getRootResourceClass(implClass) != null ? implClass : type; server.deploy(resourceDef, impl, contextPath); @@ -136,15 +136,22 @@ public class RestProtocol extends AbstractProxyProtocol { }; } - @Override protected Invoker protocolBindingRefer(final Class type, final URL url) throws RpcException { - ReferenceCountedClient refClient = - clients.computeIfAbsent(url.getAddress(), key -> createReferenceCountedClient(url)); - + ReferenceCountedClient refClient = clients.get(url.getAddress()); + if (refClient == null || refClient.isDestroyed()) { + synchronized (clients) { + refClient = clients.get(url.getAddress()); + if (refClient == null || refClient.isDestroyed()) { + refClient = ConcurrentHashMapUtils.computeIfAbsent(clients, url.getAddress(), _key -> createReferenceCountedClient(url)); + } + } + } refClient.retain(); + final ReferenceCountedClient glueRefClient = refClient; + // resolve metadata Map> metadataMap = MetadataResolver.resolveConsumerServiceMetadata(type, url); @@ -168,7 +175,7 @@ public class RestProtocol extends AbstractProxyProtocol { intercept.intercept(httpConnectionCreateContext); } - CompletableFuture future = refClient.getClient().send(requestTemplate); + CompletableFuture future = glueRefClient.getClient().send(requestTemplate); CompletableFuture responseFuture = new CompletableFuture<>(); AsyncRpcResult asyncRpcResult = new AsyncRpcResult(responseFuture, invocation); future.whenComplete((r, t) -> { @@ -260,7 +267,7 @@ public class RestProtocol extends AbstractProxyProtocol { if (logger.isInfoEnabled()) { logger.info("Closing rest clients"); } - for (ReferenceCountedClient client : clients.values()) { + for (ReferenceCountedClient client : clients.values()) { try { // destroy directly regardless of the current reference count. client.destroy(); @@ -287,7 +294,7 @@ public class RestProtocol extends AbstractProxyProtocol { if (contextPath.endsWith(url.getParameter(INTERFACE_KEY))) { contextPath = contextPath.substring(0, contextPath.lastIndexOf(url.getParameter(INTERFACE_KEY))); } - return contextPath.endsWith("/") ? contextPath.substring(0, contextPath.length() - 1) : contextPath; + return contextPath.endsWith(PATH_SEPARATOR) ? contextPath.substring(0, contextPath.length() - 1) : contextPath; } else { return ""; } @@ -296,7 +303,7 @@ public class RestProtocol extends AbstractProxyProtocol { @Override protected void destroyInternal(URL url) { try { - ReferenceCountedClient referenceCountedClient = clients.get(url.getAddress()); + ReferenceCountedClient referenceCountedClient = clients.get(url.getAddress()); if (referenceCountedClient != null && referenceCountedClient.release()) { clients.remove(url.getAddress()); } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java index fe16f4687f..ee03685662 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolServer.java @@ -26,8 +26,8 @@ public interface RestProtocolServer extends ProtocolServer { /** * @param resourceDef it could be either resource interface or resource impl */ - void deploy(Class resourceDef, Object resourceInstance, String contextPath); + void deploy(Class resourceDef, Object resourceInstance, String contextPath); - void undeploy(Class resourceDef); + void undeploy(Class resourceDef); } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java index 265987241e..01c0df5aed 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestServerFactory.java @@ -28,10 +28,9 @@ public class RestServerFactory { private static final HttpBinder httpBinder = FrameworkModel.defaultModel().getAdaptiveExtension(HttpBinder.class); public RestProtocolServer createServer(String name) { - // TODO move names to Constants - if ("servlet".equalsIgnoreCase(name) || "jetty".equalsIgnoreCase(name) || "tomcat".equalsIgnoreCase(name)) { + if (Constants.SERVLET.equalsIgnoreCase(name) || Constants.JETTY.equalsIgnoreCase(name) || Constants.TOMCAT.equalsIgnoreCase(name)) { return new DubboHttpProtocolServer(httpBinder); - } else if ("netty".equalsIgnoreCase(name)) { + } else if (Constants.NETTY.equalsIgnoreCase(name)) { return new NettyRestProtocolServer(); } else { throw new IllegalArgumentException("Unrecognized server name: " + name); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java index 70edad5bcc..3572ea67e3 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.rpc.protocol.rest; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.Invocation; @@ -40,7 +41,7 @@ public class RpcContextFilter implements ContainerRequestFilter, ClientRequestFi private static final String DUBBO_ATTACHMENT_HEADER = "Dubbo-Attachments"; - // currently we use a single header to hold the attachments so that the total attachment size limit is about 8k + // currently, we use a single header to hold the attachments so that the total attachment size limit is about 8k private static final int MAX_HEADER_SIZE = 8 * 1024; @Override @@ -57,7 +58,7 @@ public class RpcContextFilter implements ContainerRequestFilter, ClientRequestFi String headers = requestContext.getHeaderString(DUBBO_ATTACHMENT_HEADER); if (headers != null) { - for (String header : headers.split(",")) { + for (String header : headers.split(CommonConstants.COMMA_SEPARATOR)) { int index = header.indexOf("="); if (index > 0) { String key = header.substring(0, index); @@ -101,14 +102,14 @@ public class RpcContextFilter implements ContainerRequestFilter, ClientRequestFi private boolean illegalHttpHeaderKey(String key) { if (StringUtils.isNotEmpty(key)) { - return key.contains(",") || key.contains("="); + return key.contains(CommonConstants.COMMA_SEPARATOR) || key.contains("="); } return false; } private boolean illegalHttpHeaderValue(String value) { if (StringUtils.isNotEmpty(value)) { - return value.contains(","); + return value.contains(CommonConstants.COMMA_SEPARATOR); } return false; } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java index e0fb782607..de6d2e45a6 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapper.java @@ -28,24 +28,21 @@ public class RpcExceptionMapper implements ExceptionMapper { @Override public Response toResponse(RpcException e) { - // TODO do more sophisticated exception handling and output if (e.getCause() instanceof ConstraintViolationException) { return handleConstraintViolationException((ConstraintViolationException) e.getCause()); } // we may want to avoid exposing the dubbo exception details to certain clients - // TODO for now just do plain text output return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal server error: " + e.getMessage()).type(ContentType.TEXT_PLAIN_UTF_8).build(); } protected Response handleConstraintViolationException(ConstraintViolationException cve) { ViolationReport report = new ViolationReport(); - for (ConstraintViolation cv : cve.getConstraintViolations()) { + for (ConstraintViolation cv : cve.getConstraintViolations()) { report.addConstraintViolation(new RestConstraintViolation( - cv.getPropertyPath().toString(), - cv.getMessage(), - cv.getInvalidValue() == null ? "null" : cv.getInvalidValue().toString())); + cv.getPropertyPath().toString(), + cv.getMessage(), + cv.getInvalidValue() == null ? "null" : cv.getInvalidValue().toString())); } - // TODO for now just do xml output return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(report).type(ContentType.TEXT_XML_UTF_8).build(); } } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java index 3c4510056b..cff2d73222 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java @@ -35,15 +35,19 @@ import org.apache.dubbo.rpc.model.ServiceDescriptor; import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestService; import org.apache.dubbo.rpc.protocol.rest.rest.AnotherUserRestServiceImpl; + import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; import java.util.Arrays; import java.util.Map; import static org.apache.dubbo.remoting.Constants.SERVER_KEY; +import static org.apache.dubbo.rpc.protocol.rest.Constants.EXCEPTION_MAPPER_KEY; import static org.apache.dubbo.rpc.protocol.rest.Constants.EXTENSION_KEY; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; @@ -51,8 +55,8 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; class JaxrsRestProtocolTest { - private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest"); - private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); + private final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest"); + private final ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); private final int availablePort = NetUtils.getAvailablePort(); private final URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); private final ModuleServiceRepository repository = ApplicationModel.defaultModel().getDefaultModule().getServiceRepository(); @@ -282,6 +286,29 @@ class JaxrsRestProtocolTest { assertThat(protocol.getDefaultPort(), is(80)); } + @Test + void testExceptionMapper() { + DemoService server = new DemoServiceImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL exceptionUrl = url.addParameter(EXCEPTION_MAPPER_KEY, TestExceptionMapper.class.getName()); + + protocol.export(proxy.getInvoker(server, DemoService.class, exceptionUrl)); + + DemoService referDemoService = this.proxy.getProxy(protocol.refer(DemoService.class, exceptionUrl)); + + Assertions.assertEquals("test-exception", referDemoService.error()); + } + + public static class TestExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(RuntimeException e) { + return Response.ok("test-exception").build(); + } + } + private URL registerProvider(URL url, Object impl, Class interfaceClass) { ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass); ProviderModel providerModel = new ProviderModel( diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java index 5d4410ed7e..b8a983c055 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RpcExceptionMapperTest.java @@ -46,8 +46,8 @@ class RpcExceptionMapperTest { @Test void testConstraintViolationException() { ConstraintViolationException violationException = mock(ConstraintViolationException.class); - ConstraintViolation violation = mock(ConstraintViolation.class, Answers.RETURNS_DEEP_STUBS); - given(violationException.getConstraintViolations()).willReturn(Sets.>newSet(violation)); + ConstraintViolation violation = mock(ConstraintViolation.class, Answers.RETURNS_DEEP_STUBS); + given(violationException.getConstraintViolations()).willReturn(Sets.newSet(violation)); RpcException rpcException = new RpcException("violation", violationException); Response response = exceptionMapper.toResponse(rpcException); From e7925ceac7b58b9a739652e5011dff57b772bf96 Mon Sep 17 00:00:00 2001 From: songxiaosheng <81170548+songxiaosheng@users.noreply.github.com> Date: Thu, 23 Feb 2023 11:01:21 +0800 Subject: [PATCH 019/144] sync meter to spring boot management (#11630) --- .../apache/dubbo/metrics/DubboMetrics.java | 8 ++++- .../report/AbstractMetricsReporter.java | 33 ++++++++++++------- .../prometheus/PrometheusMetricsReporter.java | 8 +++++ 3 files changed, 37 insertions(+), 12 deletions(-) rename dubbo-metrics/{dubbo-metrics-api => dubbo-metrics-default}/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java (75%) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java similarity index 75% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java rename to dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java index 704fdb217e..00351aedcc 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/DubboMetrics.java @@ -18,15 +18,21 @@ package org.apache.dubbo.metrics; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; +import org.apache.dubbo.metrics.report.AbstractMetricsReporter; public class DubboMetrics implements MeterBinder { - public static volatile MeterRegistry globalRegistry = null; + private MeterRegistry globalRegistry = null; @Override public void bindTo(MeterRegistry registry) { globalRegistry = registry; + CompositeMeterRegistry compositeRegistry = AbstractMetricsReporter.compositeRegistry; + if (compositeRegistry != null) { + compositeRegistry.add(registry); + } } public void destroy() { diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java index f62b8b0c0d..dccc46e2cc 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java @@ -34,7 +34,7 @@ import org.apache.dubbo.common.constants.MetricsConstants; import org.apache.dubbo.common.lang.ShutdownHookCallbacks; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.metrics.DubboMetrics; +import org.apache.dubbo.common.utils.NamedThreadFactory; import org.apache.dubbo.metrics.collector.AggregateMetricsCollector; import org.apache.dubbo.metrics.collector.MetricsCollector; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; @@ -44,6 +44,9 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION; @@ -57,14 +60,17 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AbstractMetricsReporter.class); private final AtomicBoolean initialized = new AtomicBoolean(false); - private final AtomicBoolean addGlobalRegistry = new AtomicBoolean(false); protected final URL url; protected final List collectors = new ArrayList<>(); - protected final CompositeMeterRegistry compositeRegistry = new CompositeMeterRegistry(); + public static final CompositeMeterRegistry compositeRegistry = new CompositeMeterRegistry(); private final ApplicationModel applicationModel; + private ScheduledExecutorService collectorSyncJobExecutor = null; + + private static final int DEFAULT_SCHEDULE_INITIAL_DELAY = 5; + private static final int DEFAULT_SCHEDULE_PERIOD = 3; protected AbstractMetricsReporter(URL url, ApplicationModel applicationModel) { this.url = url; @@ -76,6 +82,7 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { if (initialized.compareAndSet(false, true)) { addJvmMetrics(); initCollectors(); + scheduleMetricsCollectorSyncJob(); doInit(); @@ -86,13 +93,7 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { protected void addMeterRegistry(MeterRegistry registry) { compositeRegistry.add(registry); } - private void addDubboMeterRegistry(){ - MeterRegistry globalRegistry = DubboMetrics.globalRegistry; - if(globalRegistry != null && !addGlobalRegistry.get()){ - compositeRegistry.add(globalRegistry); - addGlobalRegistry.set(true); - } - } + protected ApplicationModel getApplicationModel() { return applicationModel; @@ -126,8 +127,15 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { collectors.addAll(otherCollectors); } + private void scheduleMetricsCollectorSyncJob() { + NamedThreadFactory threadFactory = new NamedThreadFactory("metrics-collector-sync-job", true); + collectorSyncJobExecutor = Executors.newScheduledThreadPool(1, threadFactory); + collectorSyncJobExecutor.scheduleWithFixedDelay(() -> { + refreshData(); + }, DEFAULT_SCHEDULE_INITIAL_DELAY, DEFAULT_SCHEDULE_PERIOD, TimeUnit.SECONDS); + } + public void refreshData() { - addDubboMeterRegistry(); collectors.forEach(collector -> { List samples = collector.collect(); for (MetricSample sample : samples) { @@ -168,6 +176,9 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { } public void destroy() { + if (collectorSyncJobExecutor != null) { + collectorSyncJobExecutor.shutdownNow(); + } doDestroy(); } diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java index d110751fb2..8227d4d4f1 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java @@ -85,14 +85,22 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter { } try { + prometheusExporterHttpServer = HttpServer.create(new InetSocketAddress(port), 0); prometheusExporterHttpServer.createContext(path, httpExchange -> { + long begin = System.currentTimeMillis(); + if (logger.isDebugEnabled()) { + logger.debug("scrape begin"); + } refreshData(); String response = prometheusRegistry.scrape(); httpExchange.sendResponseHeaders(200, response.getBytes().length); try (OutputStream os = httpExchange.getResponseBody()) { os.write(response.getBytes()); } + if (logger.isDebugEnabled()) { + logger.debug(String.format("scrape end,Elapsed Time:%s",System.currentTimeMillis() - begin)); + } }); httpServerThread = new Thread(prometheusExporterHttpServer::start); From 638b193c2c7a6ad96b651b686196345c24c89909 Mon Sep 17 00:00:00 2001 From: jojocodeX <571943037@qq.com> Date: Thu, 23 Feb 2023 15:07:38 +0800 Subject: [PATCH 020/144] dubbo-security Jackson error (#11622) --- dubbo-distribution/dubbo-all/pom.xml | 8 ++ dubbo-plugin/dubbo-spring-security/pom.xml | 13 ++ ...thenticationExceptionTranslatorFilter.java | 4 +- ...textHolderAuthenticationPrepareFilter.java | 11 +- ...extHolderAuthenticationResolverFilter.java | 10 +- .../security/jackson/ObjectMapperCodec.java | 114 ++++++++++++++++++ .../jackson/ObjectMapperCodecCustomer.java | 27 +++++ .../model/SecurityScopeModelInitializer.java | 57 +++++++++ .../security/utils/ObjectMapperCodec.java | 66 ---------- ...ache.dubbo.rpc.model.ScopeModelInitializer | 1 + .../jackson/ObjectMapperCodecTest.java | 72 +++++++++++ .../org/apache/dubbo/rpc/RpcException.java | 5 + 12 files changed, 314 insertions(+), 74 deletions(-) create mode 100644 dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java create mode 100644 dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecCustomer.java create mode 100644 dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java delete mode 100644 dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/ObjectMapperCodec.java create mode 100644 dubbo-plugin/dubbo-spring-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer create mode 100644 dubbo-plugin/dubbo-spring-security/src/test/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecTest.java diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index 7e96659152..49a224b69f 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -1256,6 +1256,14 @@ META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector + + + + META-INF/dubbo/internal/org.apache.dubbo.spring.security.jackson.ObjectMapperCodecCustomer + + + diff --git a/dubbo-plugin/dubbo-spring-security/pom.xml b/dubbo-plugin/dubbo-spring-security/pom.xml index f372887f98..a9d0588836 100644 --- a/dubbo-plugin/dubbo-spring-security/pom.xml +++ b/dubbo-plugin/dubbo-spring-security/pom.xml @@ -57,6 +57,14 @@ org.springframework.security spring-security-core + + + org.springframework.security + spring-security-oauth2-client + true + test + + @@ -65,6 +73,11 @@ jackson-core + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + com.fasterxml.jackson.core jackson-databind diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java index b4e3ae2dde..7885250782 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java @@ -26,7 +26,7 @@ import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.AuthenticationException; -import static org.apache.dubbo.rpc.RpcException.FORBIDDEN_EXCEPTION; +import static org.apache.dubbo.rpc.RpcException.AUTHORIZATION_EXCEPTION; import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; @Activate(group = CommonConstants.PROVIDER, order =Integer.MAX_VALUE,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) @@ -43,7 +43,7 @@ public class AuthenticationExceptionTranslatorFilter implements Filter, Filter.L if (this.isTranslate(result)) { RpcException rpcException = new RpcException(result.getException().getMessage()); - rpcException.setCode(FORBIDDEN_EXCEPTION); + rpcException.setCode(AUTHORIZATION_EXCEPTION); result.setException(rpcException); } diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java index 11b783259a..5d70dc9858 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java @@ -23,7 +23,8 @@ import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.cluster.filter.ClusterFilter; -import org.apache.dubbo.spring.security.utils.ObjectMapperCodec; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec; import org.apache.dubbo.spring.security.utils.SecurityNames; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; @@ -31,9 +32,13 @@ import org.springframework.security.core.context.SecurityContextHolder; import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; @Activate(group = CommonConstants.CONSUMER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) -public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter { +public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter{ - private ObjectMapperCodec mapper = new ObjectMapperCodec(); + private final ObjectMapperCodec mapper; + + public ContextHolderAuthenticationPrepareFilter(ApplicationModel applicationModel) { + this.mapper = applicationModel.getBeanFactory().getBean(ObjectMapperCodec.class); + } @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java index e2a973e733..092cfe018f 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java @@ -24,17 +24,21 @@ import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.spring.security.utils.ObjectMapperCodec; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec; import org.apache.dubbo.spring.security.utils.SecurityNames; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; - import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; @Activate(group = CommonConstants.PROVIDER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) public class ContextHolderAuthenticationResolverFilter implements Filter { - private ObjectMapperCodec mapper = new ObjectMapperCodec(); + private final ObjectMapperCodec mapper; + + public ContextHolderAuthenticationResolverFilter(ApplicationModel applicationModel) { + this.mapper = applicationModel.getBeanFactory().getBean(ObjectMapperCodec.class); + } @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java new file mode 100644 index 0000000000..d2ddab3d38 --- /dev/null +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java @@ -0,0 +1,114 @@ +/* + * 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.spring.security.jackson; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.apache.dubbo.common.utils.ClassUtils; +import org.apache.dubbo.common.utils.StringUtils; +import org.springframework.security.jackson2.CoreJackson2Module; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class ObjectMapperCodec { + + private ObjectMapper mapper = new ObjectMapper(); + + public ObjectMapperCodec() { + registerDefaultModule(); + } + + public T deserialize(byte[] bytes, Class clazz) { + try { + + if (bytes == null || bytes.length == 0) { + return null; + } + + return mapper.readValue(bytes, clazz); + + } catch (Exception exception) { + throw new RuntimeException( + String.format("objectMapper! deserialize error %s", exception)); + } + } + + public T deserialize(String content, Class clazz) { + if (StringUtils.isBlank(content)) { + return null; + } + return deserialize(content.getBytes(), clazz); + } + + public String serialize(Object object) { + try { + + if (object == null) { + return null; + } + + return mapper.writeValueAsString(object); + + } catch (Exception ex) { + throw new RuntimeException(String.format("objectMapper! serialize error %s", ex)); + } + } + + public ObjectMapperCodec addModule(SimpleModule simpleModule) { + mapper.registerModule(simpleModule); + return this; + } + + public ObjectMapperCodec configureMapper(Consumer objectMapperConfigure) { + objectMapperConfigure.accept(this.mapper); + return this; + } + + private void registerDefaultModule() { + mapper.registerModule(new CoreJackson2Module()); + mapper.registerModule(new JavaTimeModule()); + + List jacksonModuleClassNameList = new ArrayList<>(); + jacksonModuleClassNameList.add("org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module"); + jacksonModuleClassNameList.add("org.springframework.security.oauth2.client.jackson2.OAuth2ClientJackson2Module"); + jacksonModuleClassNameList.add("org.springframework.security.web.server.jackson2.WebServerJackson2Module"); + jacksonModuleClassNameList.add("com.fasterxml.jackson.module.paramnames.ParameterNamesModule"); + jacksonModuleClassNameList.add("org.springframework.security.web.jackson2.WebServletJackson2Module"); + jacksonModuleClassNameList.add("org.springframework.security.web.jackson2.WebJackson2Module"); + jacksonModuleClassNameList.add("org.springframework.boot.jackson.JsonMixinModule"); + jacksonModuleClassNameList.add("org.springframework.security.ldap.jackson2.LdapJackson2Module"); + loadModuleIfPresent(jacksonModuleClassNameList); + + } + + private void loadModuleIfPresent(List jacksonModuleClassNameList) { + for (String moduleClassName : jacksonModuleClassNameList) { + try { + SimpleModule objectMapperModule = (SimpleModule) ClassUtils.forName(moduleClassName, + ObjectMapperCodec.class.getClassLoader()).newInstance(); + mapper.registerModule(objectMapperModule); + + } catch (Throwable ex) { + } + } + } + +} diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecCustomer.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecCustomer.java new file mode 100644 index 0000000000..2674172fe5 --- /dev/null +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecCustomer.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.spring.security.jackson; +import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.extension.SPI; + +@SPI(scope = ExtensionScope.FRAMEWORK) +public interface ObjectMapperCodecCustomer { + + void customize(ObjectMapperCodec objectMapperCodec); + +} diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java new file mode 100644 index 0000000000..9679334f6f --- /dev/null +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java @@ -0,0 +1,57 @@ +/* + * 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.spring.security.model; + +import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; +import org.apache.dubbo.common.extension.Activate; +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; +import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec; +import org.apache.dubbo.spring.security.jackson.ObjectMapperCodecCustomer; +import java.util.Set; +import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; + +@Activate(onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) +public class SecurityScopeModelInitializer implements ScopeModelInitializer { + + @Override + public void initializeFrameworkModel(FrameworkModel frameworkModel) { + ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); + + ObjectMapperCodec objectMapperCodec = beanFactory.getOrRegisterBean(ObjectMapperCodec.class); + + Set objectMapperCodecCustomerList = frameworkModel.getExtensionLoader(ObjectMapperCodecCustomer.class).getSupportedExtensionInstances(); + + for (ObjectMapperCodecCustomer objectMapperCodecCustomer : objectMapperCodecCustomerList) { + objectMapperCodecCustomer.customize(objectMapperCodec); + } + } + + @Override + public void initializeApplicationModel(ApplicationModel applicationModel) { + } + + @Override + public void initializeModuleModel(ModuleModel moduleModel) { + + + } + +} diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/ObjectMapperCodec.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/ObjectMapperCodec.java deleted file mode 100644 index 1010dde22d..0000000000 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/ObjectMapperCodec.java +++ /dev/null @@ -1,66 +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.spring.security.utils; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.dubbo.common.utils.StringUtils; -import org.springframework.security.jackson2.CoreJackson2Module; - -public class ObjectMapperCodec { - - private ObjectMapper mapper = new ObjectMapper(); - - - public ObjectMapperCodec(){ - mapper.registerModule(new CoreJackson2Module()); - } - - public T deserialize(byte [] bytes,Class clazz) { - try { - if (bytes == null || bytes.length == 0) { - return null; - } - - return mapper.readValue(bytes, clazz); - - } catch (Exception exception) { - throw new RuntimeException( - String.format("objectMapper! deserialize error %s", exception)); - } - } - - public T deserialize(String content,Class clazz) { - if (StringUtils.isBlank(content)) { - return null; - } - return deserialize(content.getBytes(), clazz); - } - public String serialize(Object object) { - try { - if (object == null) { - return null; - } - - return mapper.writeValueAsString(object); - - } catch (Exception ex) { - throw new RuntimeException(String.format("objectMapper! serialize error %s", ex)); - } - } - -} diff --git a/dubbo-plugin/dubbo-spring-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer b/dubbo-plugin/dubbo-spring-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer new file mode 100644 index 0000000000..f13f1c6f16 --- /dev/null +++ b/dubbo-plugin/dubbo-spring-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer @@ -0,0 +1 @@ +securityApplicationScopeModelInitializer = org.apache.dubbo.spring.security.model.SecurityScopeModelInitializer diff --git a/dubbo-plugin/dubbo-spring-security/src/test/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecTest.java b/dubbo-plugin/dubbo-spring-security/src/test/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecTest.java new file mode 100644 index 0000000000..67d1368a11 --- /dev/null +++ b/dubbo-plugin/dubbo-spring-security/src/test/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodecTest.java @@ -0,0 +1,72 @@ +/* + * 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.spring.security.jackson; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.core.OAuth2AccessToken; + +import java.time.Duration; +import java.time.Instant; + +public class ObjectMapperCodecTest { + + private ObjectMapperCodec mapper = new ObjectMapperCodec(); + + @Test + public void testOAuth2AuthorizedClientCodec() { + ClientRegistration clientRegistration = clientRegistration().build(); + OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(clientRegistration, "principal-name", noScopes()); + + String content = mapper.serialize(authorizedClient); + + OAuth2AuthorizedClient deserialize = mapper.deserialize(content.getBytes(), + OAuth2AuthorizedClient.class); + + Assertions.assertNotNull(deserialize); + } + + + public static ClientRegistration.Builder clientRegistration() { + // @formatter:off + return ClientRegistration.withRegistrationId("registration-id") + .redirectUri("http://localhost/uua/oauth2/code/{registrationId}") + .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .scope("read:user") + .authorizationUri("https://example.com/login/oauth/authorize") + .tokenUri("https://example.com/login/oauth/access_token") + .jwkSetUri("https://example.com/oauth2/jwk") + .issuerUri("https://example.com") + .userInfoUri("https://api.example.com/user") + .userNameAttributeName("id") + .clientName("Client Name") + .clientId("client-id") + .clientSecret("client-secret"); + // @formatter:on + } + + public static OAuth2AccessToken noScopes() { + return new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "no-scopes", Instant.now(), + Instant.now().plus(Duration.ofDays(1))); + } +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java index 9ab6afaa71..4d6876fd41 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java @@ -40,6 +40,7 @@ public class RpcException extends RuntimeException { public static final int ROUTER_CACHE_NOT_BUILD = 10; public static final int METHOD_NOT_FOUND = 11; public static final int VALIDATION_EXCEPTION = 12; + public static final int AUTHORIZATION_EXCEPTION = 13; private static final long serialVersionUID = 7815426752583648734L; /** * RpcException cannot be extended, use error code for exception type to keep compatibility @@ -110,6 +111,10 @@ public class RpcException extends RuntimeException { return code == SERIALIZATION_EXCEPTION; } + public boolean isAuthorization(){ + return code == AUTHORIZATION_EXCEPTION; + } + public boolean isNoInvokerAvailableAfterFilter() { return code == NO_INVOKER_AVAILABLE_AFTER_FILTER; } From c68faccd5625d677047983998558c6c61e17067b Mon Sep 17 00:00:00 2001 From: Laukik Chahande <103280327+Lauquik@users.noreply.github.com> Date: Fri, 24 Feb 2023 12:17:06 +0530 Subject: [PATCH 021/144] fixed broken link readme.md (#11641) --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index eac2bdcddd..2b23fea32b 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ We are now collecting Dubbo user info to help us to improve Dubbo further. Kindl ## Getting started -The following code snippet comes from [Dubbo Samples](https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-api). You may clone the sample project and step into the `dubbo-samples-api` subdirectory before proceeding. +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. ```bash git clone https://github.com/apache/dubbo-samples.git cd dubbo-samples/dubbo-samples-api ``` -There's a [README](https://github.com/apache/dubbo-samples/tree/master/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: +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 @@ -70,7 +70,7 @@ public interface GreetingsService { } ``` -*See [api/GreetingsService.java](https://github.com/apache/dubbo-samples/blob/master/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java) on GitHub.* +*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 @@ -87,7 +87,7 @@ public class GreetingsServiceImpl implements GreetingsService { } ``` -*See [provider/GreetingsServiceImpl.java](https://github.com/apache/dubbo-samples/blob/master/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java) on GitHub.* +*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 @@ -119,7 +119,7 @@ public class Application { } ``` -*See [provider/Application.java](https://github.com/apache/dubbo-samples/blob/master/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/Application.java) on GitHub.* +*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.* ### Build and run the provider @@ -153,7 +153,7 @@ public class Application { } } ``` -*See [consumer/Application.java](https://github.com/apache/dubbo-samples/blob/master/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java) on GitHub.* +*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 From d52c59b94c3eb5c5ee0dd057c367ceef6c3e2376 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 24 Feb 2023 21:26:44 +0800 Subject: [PATCH 022/144] Fix license check --- .licenserc.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.licenserc.yaml b/.licenserc.yaml index 04f643df2f..651c2f5076 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -8,9 +8,9 @@ header: 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. @@ -192,7 +192,9 @@ dependency: license: EPL-2.0 - name: org.glassfish:jakarta.el license: EPL-2.0 - - name: org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec - license: CDDL-1.1 + - name: org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.1_spec + license: EPL-2.0 + - name: org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec + license: EPL-2.0 excludes: - name: javax.xml.bind:jsr173_api From 29d32afd79513330f3cd83a78b405b8b33cc6b91 Mon Sep 17 00:00:00 2001 From: aamingaa <49740762+aamingaa@users.noreply.github.com> Date: Sat, 25 Feb 2023 16:43:22 +0800 Subject: [PATCH 023/144] fix: executor (#11652) --- .../manager/DefaultExecutorRepository.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java index 2a0858a2c4..399567f97d 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java @@ -31,7 +31,6 @@ import org.apache.dubbo.config.ModuleConfig; import org.apache.dubbo.config.ProviderConfig; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ModuleModel; -import org.apache.dubbo.rpc.model.ServiceDescriptor; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -47,7 +46,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_EXPORT_T import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_PROTOCOL; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_REFER_THREAD_NUM; import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.INTERNAL_EXECUTOR_SERVICE_COMPONENT_KEY; import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY; import static org.apache.dubbo.common.constants.CommonConstants.THREAD_NAME_KEY; @@ -122,18 +120,10 @@ public class DefaultExecutorRepository implements ExecutorRepository, ExtensionA * @return */ private String getExecutorKey(URL url) { - String executorKey = INTERNAL_EXECUTOR_SERVICE_COMPONENT_KEY; - ServiceDescriptor serviceDescriptor = applicationModel.getInternalModule().getServiceRepository().lookupService(url.getServiceInterface()); - // if not found in internal service repository, then it's biz service defined by user. - if (serviceDescriptor == null) { - executorKey = EXECUTOR_SERVICE_COMPONENT_KEY; - - } - if (CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(SIDE_KEY))) { - executorKey = CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY; + return CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY; } - return executorKey; + return EXECUTOR_SERVICE_COMPONENT_KEY; } private ExecutorService createExecutor(URL url) { From 848edaa80fe4128adb9f8809f776272465b1d18e Mon Sep 17 00:00:00 2001 From: aamingaa <49740762+aamingaa@users.noreply.github.com> Date: Sat, 25 Feb 2023 17:13:44 +0800 Subject: [PATCH 024/144] Fix service name mapping check failed (#11643) --- .../metadata/MetadataServiceNameMapping.java | 28 +++++++++++-------- .../protocol/tri/call/AbstractServerCall.java | 14 +++++----- .../tri/call/AbstractServerCallListener.java | 4 +-- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java index e5925bba8c..3da0d20df1 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java @@ -16,12 +16,6 @@ */ package org.apache.dubbo.registry.client.metadata; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ThreadLocalRandom; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.config.configcenter.ConfigItem; @@ -37,6 +31,12 @@ import org.apache.dubbo.metadata.report.MetadataReportInstance; import org.apache.dubbo.registry.client.RegistryClusterIdentifier; import org.apache.dubbo.rpc.model.ApplicationModel; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; + import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_PROPERTY_TYPE_MISMATCH; @@ -92,17 +92,23 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping { continue; } - boolean succeeded; + boolean succeeded = false; int currentRetryTimes = 1; String newConfigContent = appName; do { ConfigItem configItem = metadataReport.getConfigItem(serviceInterface, DEFAULT_MAPPING_GROUP); String oldConfigContent = configItem.getContent(); if (StringUtils.isNotEmpty(oldConfigContent)) { - boolean contains = StringUtils.isContains(oldConfigContent, appName); - if (contains) { - // From the user's perspective, it means successful when the oldConfigContent has contained the current appName. So we should not throw an Exception to user, it will confuse the user. - succeeded = true; + String[] oldAppNames = oldConfigContent.split(","); + if (oldAppNames.length > 0) { + for (String oldAppName : oldAppNames) { + if (oldAppName.equals(appName)) { + succeeded = true; + break; + } + } + } + if (succeeded) { break; } newConfigContent = oldConfigContent + COMMA_SEPARATOR + appName; diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java index cd538a7a58..7780579a69 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java @@ -143,7 +143,7 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis final byte[] data; try { data = packableMethod.packResponse(message); - } catch (Throwable e) { + } catch (Exception e) { close(TriRpcStatus.INTERNAL.withDescription("Serialize response failed") .withCause(e), null); LOGGER.error(PROTOCOL_FAILED_SERIALIZE_TRIPLE,"","",String.format("Serialize triple response failed, service=%s method=%s", @@ -188,12 +188,12 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis try { Object instance = parseSingleMessage(message); listener.onMessage(instance); - } catch (Throwable t) { + } catch (Exception e) { final TriRpcStatus status = TriRpcStatus.UNKNOWN.withDescription("Server error") - .withCause(t); + .withCause(e); close(status, null); LOGGER.error(PROTOCOL_FAILED_REQUEST,"","","Process request failed. service=" + serviceName + - " method=" + methodName, t); + " method=" + methodName, e); } finally { ClassLoadUtil.switchContextLoader(tccl); } @@ -391,10 +391,10 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis throw new IllegalStateException("Can not reach here"); } return listener; - } catch (Throwable t) { - LOGGER.error(PROTOCOL_FAILED_CREATE_STREAM_TRIPLE, "", "", "Create triple stream failed", t); + } catch (Exception e) { + LOGGER.error(PROTOCOL_FAILED_CREATE_STREAM_TRIPLE, "", "", "Create triple stream failed", e); responseErr(TriRpcStatus.INTERNAL.withDescription("Create stream failed") - .withCause(t)); + .withCause(e)); } return null; } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java index 61de32a9ba..3256cd1731 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java @@ -85,8 +85,8 @@ public abstract class AbstractServerCallListener implements AbstractServerCall.L } onReturn(r.getValue()); }); - } catch (Throwable t) { - responseObserver.onError(t); + } catch (Exception e) { + responseObserver.onError(e); } finally { RpcContext.removeCancellationContext(); RpcContext.removeContext(); From d57ad312994dc29d84ffc5b83768a784ae901d6c Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Sat, 25 Feb 2023 17:15:07 +0800 Subject: [PATCH 025/144] Migration bugfix & optimization (#11629) * Code optimize * Thread pool leak fix * Fix volatile problem --- .../DefaultMigrationAddressComparator.java | 9 +-- .../client/migration/MigrationInvoker.java | 19 ++--- .../migration/MigrationRuleHandler.java | 14 ++-- .../migration/MigrationRuleListener.java | 70 +++++++++---------- ...DefaultMigrationAddressComparatorTest.java | 5 +- .../migration/MigrationInvokerTest.java | 14 ++-- .../migration/MigrationRuleHandlerTest.java | 8 +-- .../migration/model/MigrationRuleTest.java | 10 +-- 8 files changed, 72 insertions(+), 77 deletions(-) diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java index b02f5209ec..72a5b590e4 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java @@ -42,7 +42,7 @@ public class DefaultMigrationAddressComparator implements MigrationAddressCompar public static final String OLD_ADDRESS_SIZE = "OLD_ADDRESS_SIZE"; public static final String NEW_ADDRESS_SIZE = "NEW_ADDRESS_SIZE"; - private ConcurrentMap> serviceMigrationData = new ConcurrentHashMap<>(); + private final ConcurrentMap> serviceMigrationData = new ConcurrentHashMap<>(); @Override public boolean shouldMigrate(ClusterInvoker newInvoker, ClusterInvoker oldInvoker, MigrationRule rule) { @@ -90,10 +90,7 @@ public class DefaultMigrationAddressComparator implements MigrationAddressCompar return false; } - if (((float) newAddressSize / (float) oldAddressSize) >= threshold) { - return true; - } - return false; + return ((float) newAddressSize / (float) oldAddressSize) >= threshold; } private int getAddressSize(ClusterInvoker invoker) { @@ -115,6 +112,4 @@ public class DefaultMigrationAddressComparator implements MigrationAddressCompar } return "interface"; } - - } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java index 9fbe66fa0a..d9176f4c43 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java @@ -49,17 +49,17 @@ import static org.apache.dubbo.registry.client.migration.model.MigrationStep.APP import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY; public class MigrationInvoker implements MigrationClusterInvoker { - private ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MigrationInvoker.class); + private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MigrationInvoker.class); private URL url; - private URL consumerUrl; - private Cluster cluster; - private Registry registry; - private Class type; - private RegistryProtocol registryProtocol; + private final URL consumerUrl; + private final Cluster cluster; + private final Registry registry; + private final Class type; + private final RegistryProtocol registryProtocol; private MigrationRuleListener migrationRuleListener; - private ConsumerModel consumerModel; - private FrameworkStatusReportService reportService; + private final ConsumerModel consumerModel; + private final FrameworkStatusReportService reportService; private volatile ClusterInvoker invoker; private volatile ClusterInvoker serviceDiscoveryInvoker; @@ -77,6 +77,7 @@ public class MigrationInvoker implements MigrationClusterInvoker { this(null, null, registryProtocol, cluster, registry, type, url, consumerUrl); } + @SuppressWarnings("unchecked") public MigrationInvoker(ClusterInvoker invoker, ClusterInvoker serviceDiscoveryInvoker, RegistryProtocol registryProtocol, @@ -249,6 +250,7 @@ public class MigrationInvoker implements MigrationClusterInvoker { calcPreferredInvoker(newRule); } + @SuppressWarnings("all") private void waitAddressNotify(MigrationRule newRule, CountDownLatch latch) { // wait and compare threshold int delay = newRule.getDelay(consumerUrl); @@ -317,6 +319,7 @@ public class MigrationInvoker implements MigrationClusterInvoker { : (invoker != null && invoker.isAvailable()) || (serviceDiscoveryInvoker != null && serviceDiscoveryInvoker.isAvailable()); } + @SuppressWarnings("unchecked") @Override public void destroy() { if (migrationRuleListener != null) { diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java index 334a180a43..920e1d65c2 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java @@ -30,10 +30,10 @@ public class MigrationRuleHandler { public static final String DUBBO_SERVICEDISCOVERY_MIGRATION = "dubbo.application.migration.step"; private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MigrationRuleHandler.class); - private MigrationClusterInvoker migrationInvoker; - private MigrationStep currentStep; - private Float currentThreshold = 0f; - private URL consumerURL; + private final MigrationClusterInvoker migrationInvoker; + private volatile MigrationStep currentStep; + private volatile Float currentThreshold = 0f; + private final URL consumerURL; public MigrationRuleHandler(MigrationClusterInvoker invoker, URL url) { this.migrationInvoker = invoker; @@ -115,12 +115,6 @@ public class MigrationRuleHandler { this.migrationInvoker.setMigrationRule(rule); } - private Float getMigrationThreshold(MigrationRule rule, Float threshold) { - Float configuredThreshold = rule.getThreshold(consumerURL); - threshold = configuredThreshold == null ? threshold : configuredThreshold; - return threshold; - } - private void setCurrentStepAndThreshold(MigrationStep currentStep, Float currentThreshold) { if (currentThreshold != null) { this.currentThreshold = currentThreshold; diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java index bc5c5a4876..02e877ca89 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java @@ -51,10 +51,10 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_THREAD_INTERRUPTED_EXCEPTION; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_PROPERTY_TYPE_MISMATCH; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_EMPTY_ADDRESS; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_THREAD_INTERRUPTED_EXCEPTION; import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_EMPTY_ADDRESS; import static org.apache.dubbo.common.constants.RegistryConstants.INIT; /** @@ -75,7 +75,7 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur private static final int MIGRATION_DEFAULT_DELAY_TIME = 60000; private String ruleKey; - protected final ConcurrentMap handlers = new ConcurrentHashMap<>(); + protected final ConcurrentMap, MigrationRuleHandler> handlers = new ConcurrentHashMap<>(); protected final LinkedBlockingQueue ruleQueue = new LinkedBlockingQueue<>(); private final AtomicBoolean executorSubmit = new AtomicBoolean(false); @@ -88,7 +88,7 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur private volatile String rawRule; private volatile MigrationRule rule; - private ModuleModel moduleModel; + private final ModuleModel moduleModel; public MigrationRuleListener(ModuleModel moduleModel) { this.moduleModel = moduleModel; @@ -175,44 +175,44 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur logger.info("Ignore duplicated rule"); continue; } + + logger.info("Using the following migration rule to migrate:"); + logger.info(rule); + + setRawRule(rule); + + if (CollectionUtils.isEmptyMap(handlers)) { + continue; + } + + ExecutorService executorService = null; try { - logger.info("Using the following migration rule to migrate:"); - logger.info(rule); + executorService = Executors.newFixedThreadPool(Math.min(handlers.size(), 100), new NamedThreadFactory("Dubbo-Invoker-Migrate")); + List> migrationFutures = new ArrayList<>(handlers.size()); + for (MigrationRuleHandler handler : handlers.values()) { + Future future = executorService.submit(() -> handler.doMigrate(this.rule)); + migrationFutures.add(future); + } - setRawRule(rule); - - if (CollectionUtils.isNotEmptyMap(handlers)) { - ExecutorService executorService = Executors.newFixedThreadPool(100, new NamedThreadFactory("Dubbo-Invoker-Migrate")); - List> migrationFutures = new ArrayList<>(handlers.size()); - handlers.forEach((_key, handler) -> { - Future future = executorService.submit(() -> { - handler.doMigrate(this.rule); - }); - migrationFutures.add(future); - }); - - Throwable migrationException = null; - for (Future future : migrationFutures) { - try { - future.get(); - } catch (InterruptedException ie) { - logger.warn(INTERNAL_ERROR, "unknown error in registry module", "", "Interrupted while waiting for migration async task to finish."); - } catch (ExecutionException ee) { - migrationException = ee.getCause(); - } + for (Future future : migrationFutures) { + try { + future.get(); + } catch (InterruptedException ie) { + logger.warn(INTERNAL_ERROR, "unknown error in registry module", "", "Interrupted while waiting for migration async task to finish."); + } catch (ExecutionException ee) { + logger.error(INTERNAL_ERROR, "unknown error in registry module", "", "Migration async task failed.", ee.getCause()); } - if (migrationException != null) { - logger.error(INTERNAL_ERROR, "unknown error in registry module", "", "Migration async task failed.", migrationException); - } - executorService.shutdown(); } } catch (Throwable t) { logger.error(INTERNAL_ERROR, "unknown error in registry module", "", "Error occurred when migration.", t); + } finally { + if (executorService != null) { + executorService.shutdown(); + } } } }); } - } public void setRawRule(String rawRule) { @@ -260,13 +260,11 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur if (localRuleMigrationFuture != null) { localRuleMigrationFuture.cancel(true); } - if (ruleManageExecutor != null) { - ruleManageExecutor.shutdown(); - } + ruleManageExecutor.shutdown(); ruleQueue.clear(); } - public Map getHandlers() { + public Map, MigrationRuleHandler> getHandlers() { return handlers; } diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparatorTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparatorTest.java index b6c43baa2c..f97f0b0c1a 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparatorTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparatorTest.java @@ -35,6 +35,7 @@ import static org.apache.dubbo.registry.client.migration.DefaultMigrationAddress class DefaultMigrationAddressComparatorTest { + @SuppressWarnings("all") @Test void test() { DefaultMigrationAddressComparator comparator = new DefaultMigrationAddressComparator(); @@ -69,13 +70,13 @@ class DefaultMigrationAddressComparatorTest { Mockito.when(oldInvoker.hasProxyInvokers()).thenReturn(true); - List newInvokerList = new LinkedList<>(); + List> newInvokerList = new LinkedList<>(); newInvokerList.add(Mockito.mock(Invoker.class)); newInvokerList.add(Mockito.mock(Invoker.class)); newInvokerList.add(Mockito.mock(Invoker.class)); Mockito.when(newDirectory.getAllInvokers()).thenReturn(newInvokerList); - List oldInvokerList = new LinkedList<>(); + List> oldInvokerList = new LinkedList<>(); oldInvokerList.add(Mockito.mock(Invoker.class)); oldInvokerList.add(Mockito.mock(Invoker.class)); Mockito.when(oldDirectory.getAllInvokers()).thenReturn(oldInvokerList); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationInvokerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationInvokerTest.java index 5bed016013..fd5cf5d115 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationInvokerTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationInvokerTest.java @@ -54,6 +54,7 @@ class MigrationInvokerTest { FrameworkModel.destroyAll(); } + @SuppressWarnings("all") @Test void test() { RegistryProtocol registryProtocol = Mockito.mock(RegistryProtocol.class); @@ -73,10 +74,10 @@ class MigrationInvokerTest { Mockito.when(invoker.hasProxyInvokers()).thenReturn(true); Mockito.when(serviceDiscoveryInvoker.hasProxyInvokers()).thenReturn(true); - List invokers = new LinkedList<>(); + List> invokers = new LinkedList<>(); invokers.add(Mockito.mock(Invoker.class)); invokers.add(Mockito.mock(Invoker.class)); - List serviceDiscoveryInvokers = new LinkedList<>(); + List> serviceDiscoveryInvokers = new LinkedList<>(); serviceDiscoveryInvokers.add(Mockito.mock(Invoker.class)); serviceDiscoveryInvokers.add(Mockito.mock(Invoker.class)); Mockito.when(directory.getAllInvokers()).thenReturn(invokers); @@ -96,7 +97,7 @@ class MigrationInvokerTest { Mockito.when(invoker.getUrl()).thenReturn(consumerURL); Mockito.when(serviceDiscoveryInvoker.getUrl()).thenReturn(consumerURL); - MigrationInvoker migrationInvoker = new MigrationInvoker(registryProtocol, null, null, DemoService.class, null, consumerURL); + MigrationInvoker migrationInvoker = new MigrationInvoker<>(registryProtocol, null, null, DemoService.class, null, consumerURL); MigrationRule migrationRule = Mockito.mock(MigrationRule.class); Mockito.when(migrationRule.getForce(Mockito.any())).thenReturn(true); @@ -225,6 +226,7 @@ class MigrationInvokerTest { Assertions.assertTrue(System.currentTimeMillis() - currentTimeMillis >= 2000); } + @SuppressWarnings("all") @Test void testDecide() { RegistryProtocol registryProtocol = Mockito.mock(RegistryProtocol.class); @@ -244,10 +246,10 @@ class MigrationInvokerTest { Mockito.when(invoker.hasProxyInvokers()).thenReturn(true); Mockito.when(serviceDiscoveryInvoker.hasProxyInvokers()).thenReturn(true); - List invokers = new LinkedList<>(); + List> invokers = new LinkedList<>(); invokers.add(Mockito.mock(Invoker.class)); invokers.add(Mockito.mock(Invoker.class)); - List serviceDiscoveryInvokers = new LinkedList<>(); + List> serviceDiscoveryInvokers = new LinkedList<>(); serviceDiscoveryInvokers.add(Mockito.mock(Invoker.class)); serviceDiscoveryInvokers.add(Mockito.mock(Invoker.class)); Mockito.when(directory.getAllInvokers()).thenReturn(invokers); @@ -267,7 +269,7 @@ class MigrationInvokerTest { Mockito.when(invoker.getUrl()).thenReturn(consumerURL); Mockito.when(serviceDiscoveryInvoker.getUrl()).thenReturn(consumerURL); - MigrationInvoker migrationInvoker = new MigrationInvoker(registryProtocol, null, null, DemoService.class, null, consumerURL); + MigrationInvoker migrationInvoker = new MigrationInvoker<>(registryProtocol, null, null, DemoService.class, null, consumerURL); MigrationRule migrationRule = Mockito.mock(MigrationRule.class); Mockito.when(migrationRule.getForce(Mockito.any())).thenReturn(true); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandlerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandlerTest.java index a98a4f4385..318da69cbe 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandlerTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandlerTest.java @@ -28,12 +28,12 @@ import org.mockito.Mockito; class MigrationRuleHandlerTest { @Test void test() { - MigrationClusterInvoker invoker = Mockito.mock(MigrationClusterInvoker.class); + MigrationClusterInvoker invoker = Mockito.mock(MigrationClusterInvoker.class); URL url = Mockito.mock(URL.class); Mockito.when(url.getDisplayServiceKey()).thenReturn("test"); Mockito.when(url.getParameter(Mockito.any(), (String) Mockito.any())).thenAnswer(i->i.getArgument(1)); Mockito.when(url.getOrDefaultApplicationModel()).thenReturn(ApplicationModel.defaultModel()); - MigrationRuleHandler handler = new MigrationRuleHandler(invoker, url); + MigrationRuleHandler handler = new MigrationRuleHandler<>(invoker, url); Mockito.when(invoker.migrateToForceApplicationInvoker(Mockito.any())).thenReturn(true); Mockito.when(invoker.migrateToForceInterfaceInvoker(Mockito.any())).thenReturn(true); @@ -61,7 +61,7 @@ class MigrationRuleHandlerTest { testMigrationWithStepUnchanged(rule, url, handler, invoker); } - private void testMigrationFailed(MigrationRule rule, URL url, MigrationRuleHandler handler, MigrationClusterInvoker invoker) { + private void testMigrationFailed(MigrationRule rule, URL url, MigrationRuleHandler handler, MigrationClusterInvoker invoker) { Assertions.assertEquals(MigrationStep.FORCE_INTERFACE, handler.getMigrationStep()); Mockito.when(invoker.migrateToForceApplicationInvoker(Mockito.any())).thenReturn(false); @@ -72,7 +72,7 @@ class MigrationRuleHandlerTest { Assertions.assertEquals(MigrationStep.FORCE_INTERFACE, handler.getMigrationStep()); } - private void testMigrationWithStepUnchanged(MigrationRule rule, URL url, MigrationRuleHandler handler, MigrationClusterInvoker invoker) { + private void testMigrationWithStepUnchanged(MigrationRule rule, URL url, MigrationRuleHandler handler, MigrationClusterInvoker invoker) { // set the same as Mockito.when(rule.getStep(url)).thenReturn(handler.getMigrationStep()); handler.doMigrate(rule); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java index 79b20de724..e801688f7d 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java @@ -30,13 +30,15 @@ import java.util.Set; import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_TYPE_KEY; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; class MigrationRuleTest { - private static ServiceNameMapping mapping = mock(ServiceNameMapping.class); + private static final ServiceNameMapping mapping = mock(ServiceNameMapping.class); @Test void test_parse() { @@ -87,14 +89,14 @@ class MigrationRuleTest { assertEquals(0.5f, migrationRule.getThreshold(url)); assertEquals(30, migrationRule.getProportion(url)); assertEquals(30, migrationRule.getDelay(url)); - assertEquals(true, migrationRule.getForce(url)); + assertTrue(migrationRule.getForce(url)); assertEquals(MigrationStep.APPLICATION_FIRST, migrationRule.getStep(url)); Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.0"); assertEquals(1.0f, migrationRule.getThreshold(url)); assertEquals(60, migrationRule.getProportion(url)); assertEquals(60, migrationRule.getDelay(url)); - assertEquals(false, migrationRule.getForce(url)); + assertFalse(migrationRule.getForce(url)); assertEquals(MigrationStep.FORCE_APPLICATION, migrationRule.getStep(url)); Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.1"); @@ -107,7 +109,7 @@ class MigrationRuleTest { assertEquals(0.3f, migrationRule.getThreshold(url)); assertEquals(20, migrationRule.getProportion(url)); assertEquals(10, migrationRule.getDelay(url)); - assertEquals(false, migrationRule.getForce(url)); + assertFalse(migrationRule.getForce(url)); assertEquals(MigrationStep.FORCE_INTERFACE, migrationRule.getStep(url)); when(mapping.getMapping(any(URL.class))).thenReturn(Collections.emptySet()); From c041fa1f9331a96f65f5fe006f035d4679b41c04 Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Sat, 25 Feb 2023 17:22:44 +0800 Subject: [PATCH 026/144] Observability task: registration center (#11493) --- dubbo-cluster/pom.xml | 6 + .../cluster/directory/AbstractDirectory.java | 63 +++-- .../directory/StaticDirectoryTest.java | 3 + .../support/AbstractClusterInvokerTest.java | 19 +- .../support/ConnectivityValidationTest.java | 3 + .../support/FailoverClusterInvokerTest.java | 12 +- .../wrapper/MockClusterInvokerTest.java | 3 + .../wrapper/MockProviderRpcExceptionTest.java | 3 + .../apache/dubbo/config/MetricsConfig.java | 15 +- dubbo-config/dubbo-config-api/pom.xml | 12 + .../deploy/DefaultApplicationDeployer.java | 8 + dubbo-distribution/dubbo-all/pom.xml | 8 + dubbo-distribution/dubbo-bom/pom.xml | 5 + dubbo-metrics/dubbo-metrics-api/pom.xml | 5 - .../event/SimpleMetricsEventMulticaster.java | 2 +- .../dubbo/metrics/model/MetricsKey.java | 23 +- .../apache/dubbo/metrics/model/TimePair.java | 5 + dubbo-metrics/dubbo-metrics-default/pom.xml | 6 + dubbo-metrics/dubbo-metrics-registry/pom.xml | 40 +++ .../collector/RegistryMetricsCollector.java | 123 +++++++++ .../collector/stat/RegistryStatComposite.java | 240 ++++++++++++++++++ .../collector/stat/ServiceKeyMetric.java | 83 ++++++ .../event/MetricsDirectoryListener.java | 43 ++++ .../registry/event/MetricsNotifyListener.java | 54 ++++ .../event/MetricsRegisterListener.java | 52 ++++ .../event/MetricsSubscribeListener.java | 52 ++++ .../metrics/registry/event/RegistryEvent.java | 156 ++++++++++++ .../RegistryMetricsEventMulticaster.java | 33 +++ ...e.dubbo.metrics.collector.MetricsCollector | 1 + .../RegistryMetricsCollectorTest.java | 115 +++++++++ .../collector/RegistryMetricsSampleTest.java | 97 +++++++ .../metrics/model/MethodMetricTest.java | 79 ++++++ .../model/sample/GaugeMetricSampleTest.java | 63 +++++ dubbo-metrics/pom.xml | 1 + dubbo-registry/dubbo-registry-api/pom.xml | 7 + .../ServiceInstancesChangedListener.java | 60 +++-- .../integration/RegistryDirectory.java | 39 ++- dubbo-test/dubbo-dependencies-all/pom.xml | 5 + 38 files changed, 1462 insertions(+), 82 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-registry/pom.xml create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsDirectoryListener.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsRegisterListener.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java diff --git a/dubbo-cluster/pom.xml b/dubbo-cluster/pom.xml index f7235cf7d6..744d0f9f11 100644 --- a/dubbo-cluster/pom.xml +++ b/dubbo-cluster/pom.xml @@ -68,5 +68,11 @@ ${project.parent.version} test + + org.apache.dubbo + dubbo-metrics-registry + ${project.parent.version} + compile + diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java index eb69309f24..6af8bdb98d 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java @@ -16,6 +16,31 @@ */ package org.apache.dubbo.rpc.cluster.directory; +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.Version; +import org.apache.dubbo.common.config.Configuration; +import org.apache.dubbo.common.config.ConfigurationUtils; +import org.apache.dubbo.common.constants.LoggerCodeConstants; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; +import org.apache.dubbo.common.utils.ConcurrentHashSet; +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.cluster.Directory; +import org.apache.dubbo.rpc.cluster.Router; +import org.apache.dubbo.rpc.cluster.RouterChain; +import org.apache.dubbo.rpc.cluster.SingleRouterChain; +import org.apache.dubbo.rpc.cluster.router.state.BitList; +import org.apache.dubbo.rpc.cluster.support.ClusterUtils; +import org.apache.dubbo.rpc.model.ApplicationModel; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -31,29 +56,6 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.Version; -import org.apache.dubbo.common.config.Configuration; -import org.apache.dubbo.common.config.ConfigurationUtils; -import org.apache.dubbo.common.constants.LoggerCodeConstants; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; -import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.common.utils.NetUtils; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.RpcContext; -import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.cluster.Directory; -import org.apache.dubbo.rpc.cluster.Router; -import org.apache.dubbo.rpc.cluster.RouterChain; -import org.apache.dubbo.rpc.cluster.SingleRouterChain; -import org.apache.dubbo.rpc.cluster.router.state.BitList; -import org.apache.dubbo.rpc.cluster.support.ClusterUtils; -import org.apache.dubbo.rpc.model.ApplicationModel; - import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_RECONNECT_TASK_PERIOD; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_RECONNECT_TASK_TRY_COUNT; @@ -128,6 +130,10 @@ public abstract class AbstractDirectory implements Directory { */ private final int reconnectTaskPeriod; + private final GlobalMetricsEventMulticaster eventMulticaster; + + private ApplicationModel applicationModel; + public AbstractDirectory(URL url) { this(url, null, false); } @@ -153,7 +159,7 @@ public abstract class AbstractDirectory implements Directory { } // remove some local only parameters - ApplicationModel applicationModel = url.getOrDefaultApplicationModel(); + applicationModel = url.getOrDefaultApplicationModel(); this.queryMap = applicationModel.getBeanFactory().getBean(ClusterUtils.class).mergeLocalParams(queryMap); if (consumerUrl == null) { @@ -179,12 +185,14 @@ public abstract class AbstractDirectory implements Directory { this.reconnectTaskTryCount = configuration.getInt(RECONNECT_TASK_TRY_COUNT, DEFAULT_RECONNECT_TASK_TRY_COUNT); this.reconnectTaskPeriod = configuration.getInt(RECONNECT_TASK_PERIOD, DEFAULT_RECONNECT_TASK_PERIOD); setRouterChain(routerChain); + + eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); } @Override public List> list(Invocation invocation) throws RpcException { if (destroyed) { - throw new RpcException("Directory of type " + this.getClass().getSimpleName() + " already destroyed for service " + getConsumerUrl().getServiceKey() + " from registry " + getUrl()); + throw new RpcException("Directory of type " + this.getClass().getSimpleName() + " already destroyed for service " + getConsumerUrl().getServiceKey() + " from registry " + getUrl()); } BitList> availableInvokers; @@ -381,6 +389,7 @@ public abstract class AbstractDirectory implements Directory { @Override public void addDisabledInvoker(Invoker invoker) { + eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_DISABLE)); if (invokers.contains(invoker)) { disabledInvokers.add(invoker); removeValidInvoker(invoker); @@ -390,6 +399,7 @@ public abstract class AbstractDirectory implements Directory { @Override public void recoverDisabledInvoker(Invoker invoker) { + eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_RECOVER_DISABLE)); if (disabledInvokers.remove(invoker)) { try { addValidInvoker(invoker); @@ -453,6 +463,7 @@ public abstract class AbstractDirectory implements Directory { this.invokers = invokers; refreshInvokerInternal(); this.invokersInitialized = true; + eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_CURRENT, invokers.size())); } protected void destroyInvokers() { @@ -463,12 +474,14 @@ public abstract class AbstractDirectory implements Directory { } private boolean addValidInvoker(Invoker invoker) { + eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_VALID)); synchronized (this.validInvokers) { return this.validInvokers.add(invoker); } } private boolean removeValidInvoker(Invoker invoker) { + eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_UN_VALID)); synchronized (this.validInvokers) { return this.validInvokers.remove(invoker); } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java index 379d50b1c1..62787ccd2b 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectoryTest.java @@ -19,6 +19,7 @@ package org.apache.dubbo.rpc.cluster.directory; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.Holder; import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcInvocation; import org.apache.dubbo.rpc.cluster.router.MockInvoker; @@ -26,6 +27,7 @@ import org.apache.dubbo.rpc.cluster.router.condition.ConditionStateRouterFactory import org.apache.dubbo.rpc.cluster.router.state.BitList; import org.apache.dubbo.rpc.cluster.router.state.StateRouter; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -60,6 +62,7 @@ class StaticDirectoryTest { List> filteredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation(), false, new Holder<>()); + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); StaticDirectory staticDirectory = new StaticDirectory<>(filteredInvokers); boolean isAvailable = staticDirectory.isAvailable(); Assertions.assertTrue(!isAvailable); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java index 665a9ef65d..9028114aab 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java @@ -16,18 +16,11 @@ */ package org.apache.dubbo.rpc.cluster.support; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; @@ -41,6 +34,7 @@ import org.apache.dubbo.rpc.cluster.filter.DemoService; import org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance; import org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance; import org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -50,6 +44,14 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; import static org.apache.dubbo.common.constants.CommonConstants.ENABLE_CONNECTIVITY_VALIDATION; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; @@ -104,6 +106,7 @@ class AbstractClusterInvokerTest { @SuppressWarnings({"unchecked"}) @BeforeEach public void setUp() throws Exception { + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); Map attributes = new HashMap<>(); attributes.put("application", "abstractClusterInvokerTest"); url = url.putAttribute(REFER_KEY, attributes); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ConnectivityValidationTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ConnectivityValidationTest.java index 0ccb77b8d5..59fc9cfd10 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ConnectivityValidationTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ConnectivityValidationTest.java @@ -19,6 +19,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.utils.CollectionUtils; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; @@ -28,6 +29,7 @@ import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.LoadBalance; import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -70,6 +72,7 @@ class ConnectivityValidationTest { @BeforeEach public void setup() { + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); invoker1 = Mockito.mock(Invoker.class); invoker2 = Mockito.mock(Invoker.class); invoker3 = Mockito.mock(Invoker.class); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java index 736d5a71d2..de20e2d262 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java @@ -16,11 +16,8 @@ */ package org.apache.dubbo.rpc.cluster.support; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; - import org.apache.dubbo.common.URL; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; @@ -33,10 +30,15 @@ import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.SingleRouterChain; import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; import org.apache.dubbo.rpc.cluster.router.state.BitList; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.protocol.AbstractInvoker; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertSame; @@ -65,7 +67,7 @@ class FailoverClusterInvokerTest { @BeforeEach public void setUp() throws Exception { - + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); dic = mock(Directory.class); given(dic.getUrl()).willReturn(url); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java index 62646cb201..7db7129e81 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java @@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.support.wrapper; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; @@ -28,6 +29,7 @@ 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.cluster.support.AbstractClusterInvoker; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.support.MockProtocol; import org.junit.jupiter.api.Assertions; @@ -49,6 +51,7 @@ class MockClusterInvokerTest { @BeforeEach public void beforeMethod() { + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); invokers.clear(); } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java index 89917f1de9..c0a737280f 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java @@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.support.wrapper; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.ProxyFactory; @@ -28,6 +29,7 @@ import org.apache.dubbo.rpc.cluster.LoadBalance; import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -46,6 +48,7 @@ class MockProviderRpcExceptionTest { @BeforeEach public void beforeMethod() { + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); invokers.clear(); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java index 1b8340138b..07a1e5f425 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java @@ -41,7 +41,12 @@ public class MetricsConfig extends AbstractConfig { private Boolean enableJvmMetrics; /** - * Enable jvm metrics when collecting. + * Enable registry metrics. + */ + private Boolean enableRegistryMetrics; + + /** + * Enable metadata metrics. */ private Boolean enableMetadataMetrics; @@ -103,6 +108,14 @@ public class MetricsConfig extends AbstractConfig { this.enableJvmMetrics = enableJvmMetrics; } + public Boolean getEnableRegistryMetrics() { + return enableRegistryMetrics; + } + + public void setEnableRegistryMetrics(Boolean enableRegistryMetrics) { + this.enableRegistryMetrics = enableRegistryMetrics; + } + public String getPort() { return port; } diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml index 2ba42d26a3..42ee10a4e0 100644 --- a/dubbo-config/dubbo-config-api/pom.xml +++ b/dubbo-config/dubbo-config-api/pom.xml @@ -42,12 +42,24 @@ ${project.parent.version} + + org.apache.dubbo + dubbo-metrics-api + ${project.parent.version} + + org.apache.dubbo dubbo-metrics-default ${project.parent.version} + + org.apache.dubbo + dubbo-metrics-registry + ${project.parent.version} + + org.apache.dubbo dubbo-metrics-metadata diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index c526864ab4..f605c6d09e 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -51,6 +51,9 @@ import org.apache.dubbo.config.utils.ConfigValidationUtils; import org.apache.dubbo.metadata.report.MetadataReportFactory; import org.apache.dubbo.metadata.report.MetadataReportInstance; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.metrics.report.MetricsReporter; import org.apache.dubbo.metrics.report.MetricsReporterFactory; import org.apache.dubbo.metrics.service.MetricsServiceExporter; @@ -825,10 +828,15 @@ public class DefaultApplicationDeployer extends AbstractDeployercompile true + + org.apache.dubbo + dubbo-metrics-registry + ${project.version} + compile + true + org.apache.dubbo dubbo-metrics-prometheus @@ -502,6 +509,7 @@ org.apache.dubbo:dubbo-metadata-report-zookeeper org.apache.dubbo:dubbo-metrics-api org.apache.dubbo:dubbo-metrics-default + org.apache.dubbo:dubbo-metrics-registry org.apache.dubbo:dubbo-metrics-metadata org.apache.dubbo:dubbo-metrics-prometheus org.apache.dubbo:dubbo-monitor-api diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml index 42b26038cd..4b5b5fcd51 100644 --- a/dubbo-distribution/dubbo-bom/pom.xml +++ b/dubbo-distribution/dubbo-bom/pom.xml @@ -235,6 +235,11 @@ dubbo-metrics-default ${project.version} + + org.apache.dubbo + dubbo-metrics-registry + ${project.version} + org.apache.dubbo dubbo-metrics-prometheus diff --git a/dubbo-metrics/dubbo-metrics-api/pom.xml b/dubbo-metrics/dubbo-metrics-api/pom.xml index 7ee8df194d..3c31ae389c 100644 --- a/dubbo-metrics/dubbo-metrics-api/pom.xml +++ b/dubbo-metrics/dubbo-metrics-api/pom.xml @@ -36,11 +36,6 @@ dubbo-common ${project.parent.version} - - org.apache.dubbo - dubbo-cluster - ${project.parent.version} - org.apache.dubbo dubbo-rpc-api diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java index 6f5df6660b..c3f187c82e 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java @@ -71,7 +71,7 @@ public class SimpleMetricsEventMulticaster implements MetricsEventMulticaster { publishTimeEvent(event, metricsLifeListener -> metricsLifeListener.onEventError(event)); } - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({"rawtypes"}) private void publishTimeEvent(MetricsEvent event, Consumer consumer) { if (event instanceof EmptyEvent) { return; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java index 96c879c8dd..39cecbfe49 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java @@ -23,7 +23,7 @@ public enum MetricsKey { // provider metrics key METRIC_REQUESTS("dubbo.%s.requests.total", "Total Requests"), METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Succeed Requests"), - METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total","Failed Business Requests"), + METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total", "Failed Business Requests"), METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing", "Processing Requests"), METRIC_REQUESTS_TIMEOUT("dubbo.%s.requests.timeout.total", "Total Timeout Failed Requests"), METRIC_REQUESTS_LIMIT("dubbo.%s.requests.limit.total", "Total Limit Failed Requests"), @@ -59,6 +59,26 @@ public enum MetricsKey { GENERIC_METRIC_RT_P99("dubbo.%s.rt.seconds.p99", "Response Time P99"), GENERIC_METRIC_RT_P95("dubbo.%s.rt.seconds.p95", "Response Time P95"), + // register metrics key + REGISTER_METRIC_REQUESTS("dubbo.registry.register.requests.total", "Total Register Requests"), + REGISTER_METRIC_REQUESTS_SUCCEED("dubbo.registry.register.requests.succeed.total", "Succeed Register Requests"), + REGISTER_METRIC_REQUESTS_FAILED("dubbo.registry.register.requests.failed.total", "Failed Register Requests"), + + // subscribe metrics key + SUBSCRIBE_METRIC_NUM("dubbo.registry.subscribe.num.total", "Total Subscribe Num"), + SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.registry.subscribe.num.succeed.total", "Succeed Subscribe Num"), + SUBSCRIBE_METRIC_NUM_FAILED("dubbo.registry.subscribe.num.failed.total", "Failed Subscribe Num"), + + // directory metrics key + DIRECTORY_METRIC_NUM_CURRENT("dubbo.registry.directory.num.current", "Current Directory Urls"), + DIRECTORY_METRIC_NUM_VALID("dubbo.registry.directory.num.valid.total", "Valid Directory Urls"), + DIRECTORY_METRIC_NUM_UN_VALID("dubbo.registry.directory.num.un_valid.total", "UnValid Directory Urls"), + DIRECTORY_METRIC_NUM_DISABLE("dubbo.registry.directory.num.disable.total", "Disable Directory Urls"), + DIRECTORY_METRIC_NUM_RECOVER_DISABLE("dubbo.registry.directory.num.recover.disable.total", "Recover Disable Directory Urls"), + + NOTIFY_METRIC_REQUESTS("dubbo.registry.notify.requests.total", "Total Notify Requests"), + NOTIFY_METRIC_NUM_LAST("dubbo.registry.notify.num.last", "Last Notify Nums"), + THREAD_POOL_CORE_SIZE("dubbo.thread.pool.core.size", "Thread Pool Core Size"), THREAD_POOL_LARGEST_SIZE("dubbo.thread.pool.largest.size", "Thread Pool Largest Size"), THREAD_POOL_MAX_SIZE("dubbo.thread.pool.max.size", "Thread Pool Max Size"), @@ -85,6 +105,7 @@ public enum MetricsKey { public final String getName() { return this.name; } + public final String getNameByType(String type) { return String.format(name, type); } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/TimePair.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/TimePair.java index 3994fe9dd2..70e0aba1d6 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/TimePair.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/TimePair.java @@ -21,6 +21,7 @@ public class TimePair { private final long begin; private long end; + private static final TimePair empty = new TimePair(0L); public TimePair(long currentTimeMillis) { this.begin = currentTimeMillis; @@ -37,4 +38,8 @@ public class TimePair { public long calc() { return end - begin; } + + public static TimePair empty() { + return empty; + } } diff --git a/dubbo-metrics/dubbo-metrics-default/pom.xml b/dubbo-metrics/dubbo-metrics-default/pom.xml index 71be413c6a..bc4165d765 100644 --- a/dubbo-metrics/dubbo-metrics-default/pom.xml +++ b/dubbo-metrics/dubbo-metrics-default/pom.xml @@ -46,5 +46,11 @@ micrometer-tracing-integration-test test + + org.apache.dubbo + dubbo-cluster + ${project.parent.version} + compile + diff --git a/dubbo-metrics/dubbo-metrics-registry/pom.xml b/dubbo-metrics/dubbo-metrics-registry/pom.xml new file mode 100644 index 0000000000..86f190ff76 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + org.apache.dubbo + dubbo-metrics + ${revision} + ../pom.xml + + dubbo-metrics-registry + jar + ${project.artifactId} + The metrics module of dubbo project + + false + + + + org.apache.dubbo + dubbo-metrics-api + ${project.parent.version} + + + diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java new file mode 100644 index 0000000000..c30b7c0f11 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.metrics.registry.collector; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.config.context.ConfigManager; +import org.apache.dubbo.metrics.collector.ApplicationMetricsCollector; +import org.apache.dubbo.metrics.collector.MetricsCollector; +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.event.MetricsEventMulticaster; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; +import org.apache.dubbo.metrics.registry.event.RegistryMetricsEventMulticaster; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + + +/** + * Registry implementation of {@link MetricsCollector} + */ +@Activate +public class RegistryMetricsCollector implements ApplicationMetricsCollector { + + private Boolean collectEnabled = null; + private final RegistryStatComposite stats; + private final MetricsEventMulticaster registryMulticaster; + private final ApplicationModel applicationModel; + + public RegistryMetricsCollector(ApplicationModel applicationModel) { + this.stats = new RegistryStatComposite(); + this.registryMulticaster = new RegistryMetricsEventMulticaster(); + this.applicationModel = applicationModel; + } + + public void setCollectEnabled(Boolean collectEnabled) { + if (collectEnabled != null) { + this.collectEnabled = collectEnabled; + } + } + + @Override + public boolean isCollectEnabled() { + if (collectEnabled == null) { + ConfigManager configManager = applicationModel.getApplicationConfigManager(); + configManager.getMetrics().ifPresent(metricsConfig -> setCollectEnabled(metricsConfig.getEnableRegistryMetrics())); + } + return Optional.ofNullable(collectEnabled).orElse(false); + } + + public void setNum(RegistryEvent.Type registryType, String applicationName, Map lastNumMap) { + lastNumMap.forEach((serviceKey, num) -> + this.stats.setServiceKey(registryType, applicationName, serviceKey, num)); + } + + public void setNum(RegistryEvent.Type registryType, String applicationName, Integer num) { + this.stats.setApplicationKey(registryType, applicationName, num); + } + + + @Override + public void increment(String applicationName, RegistryEvent.Type registryType) { + this.stats.increment(registryType, applicationName); + } + + @Override + public void addRT(String applicationName, String registryOpType, Long responseTime) { + stats.calcRt(applicationName, registryOpType, responseTime); + } + + @Override + public List collect() { + if (!isCollectEnabled()) { + new ArrayList<>(); + } + List list = new ArrayList<>(); + list.addAll(stats.exportNumMetrics()); + list.addAll(stats.exportRtMetrics()); + list.addAll(stats.exportSkMetrics()); + + return list; + } + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof RegistryEvent; + } + + @Override + public void onEvent(RegistryEvent event) { + registryMulticaster.publishEvent(event); + } + + + @Override + public void onEventFinish(RegistryEvent event) { + registryMulticaster.publishFinishEvent(event); + } + + @Override + public void onEventError(RegistryEvent event) { + registryMulticaster.publishErrorEvent(event); + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java new file mode 100644 index 0000000000..1d955cd7a7 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java @@ -0,0 +1,240 @@ +/* + * 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.metrics.registry.collector.stat; + +import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; +import org.apache.dubbo.metrics.collector.MetricsCollector; +import org.apache.dubbo.metrics.model.ApplicationMetric; +import org.apache.dubbo.metrics.model.MetricsCategory; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; +import org.apache.dubbo.metrics.report.MetricsExport; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.LongAccumulator; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * As a data aggregator, use internal data containers calculates and classifies + * the registry data collected by {@link MetricsCollector MetricsCollector}, and + * provides an {@link MetricsExport MetricsExport} interface for exporting standard output formats. + */ +public class RegistryStatComposite implements MetricsExport { + + + public Map> numStats = new ConcurrentHashMap<>(); + public Map> skStats = new ConcurrentHashMap<>(); + public List> rtStats = new ArrayList<>(); + public static String OP_TYPE_REGISTER = "register"; + public static String OP_TYPE_SUBSCRIBE = "subscribe"; + public static String OP_TYPE_NOTIFY = "notify"; + + public RegistryStatComposite() { + for (RegistryEvent.Type type : RegistryEvent.Type.values()) { + numStats.put(type, new ConcurrentHashMap<>()); + } + + rtStats.addAll(initStats(OP_TYPE_REGISTER)); + rtStats.addAll(initStats(OP_TYPE_SUBSCRIBE)); + rtStats.addAll(initStats(OP_TYPE_NOTIFY)); + } + + private List> initStats(String registryOpType) { + List> singleRtStats = new ArrayList<>(); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_LAST))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MIN), new LongAccumulator(Long::min, Long.MAX_VALUE))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MAX), new LongAccumulator(Long::max, Long.MIN_VALUE))); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_SUM), (responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime))); + // AvgContainer is a special counter that stores the number of times but outputs function of sum/times + AtomicLongContainer avgContainer = new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_AVG), (k, v) -> v.incrementAndGet()); + avgContainer.setValueSupplier(applicationName -> { + LongContainer totalContainer = rtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.GENERIC_METRIC_RT_SUM, registryOpType)).findFirst().get(); + AtomicLong totalRtTimes = avgContainer.get(applicationName); + AtomicLong totalRtSum = (AtomicLong) totalContainer.get(applicationName); + return totalRtSum.get() / totalRtTimes.get(); + }); + singleRtStats.add(avgContainer); + return singleRtStats; + } + + public void setApplicationKey(RegistryEvent.Type type, String applicationName, int num) { + if (!numStats.containsKey(type)) { + return; + } + numStats.get(type).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).set(num); + } + + public void setServiceKey(RegistryEvent.Type type, String applicationName, String serviceKey, int num) { + if (!skStats.containsKey(type)) { + return; + } + skStats.get(type).computeIfAbsent(new ServiceKeyMetric(applicationName, serviceKey), k -> new AtomicLong(0L)).set(num); + } + + public void increment(RegistryEvent.Type type, String applicationName) { + if (!numStats.containsKey(type)) { + return; + } + numStats.get(type).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).incrementAndGet(); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + public void calcRt(String applicationName, String registryOpType, Long responseTime) { + for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { + Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, applicationName, container.getInitFunc()); + container.getConsumerFunc().accept(responseTime, current); + } + } + + @Override + public List exportNumMetrics() { + List list = new ArrayList<>(); + for (RegistryEvent.Type type : numStats.keySet()) { + Map stringAtomicLongMap = numStats.get(type); + for (String applicationName : stringAtomicLongMap.keySet()) { + list.add(convertToSample(applicationName, type, MetricsCategory.REGISTRY, stringAtomicLongMap.get(applicationName))); + } + } + return list; + } + + @Override + public List exportRtMetrics() { + List list = new ArrayList<>(); + for (LongContainer rtContainer : rtStats) { + MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); + for (Map.Entry entry : rtContainer.entrySet()) { + list.add(new GaugeMetricSample(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, () -> rtContainer.getValueSupplier().apply(entry.getKey()))); + } + } + return list; + } + + public List exportSkMetrics() { + List list = new ArrayList<>(); + for (RegistryEvent.Type type : skStats.keySet()) { + Map stringAtomicLongMap = skStats.get(type); + for (ServiceKeyMetric serviceKeyMetric : stringAtomicLongMap.keySet()) { + list.add(new GaugeMetricSample(type.getMetricsKey(), serviceKeyMetric.getTags(), MetricsCategory.REGISTRY, stringAtomicLongMap.get(serviceKeyMetric)::get)); + } + } + return list; + } + + public GaugeMetricSample convertToSample(String applicationName, RegistryEvent.Type type, MetricsCategory category, AtomicLong targetNumber) { + return new GaugeMetricSample(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber::get); + } + + + /** + * Collect Number type data + * + * @param + */ + public static class LongContainer extends ConcurrentHashMap { + + /** + * Provide the metric type name + */ + private final MetricsKeyWrapper metricsKeyWrapper; + /** + * The initial value corresponding to the key is generally 0 of different data types + */ + private final Function initFunc; + /** + * Statistical data calculation function, which can be self-increment, self-decrement, or more complex avg function + */ + private final BiConsumer consumerFunc; + /** + * Data output function required by {@link GaugeMetricSample GaugeMetricSample} + */ + private Function valueSupplier; + + + public LongContainer(MetricsKeyWrapper metricsKeyWrapper, Supplier initFunc, BiConsumer consumerFunc) { + this.metricsKeyWrapper = metricsKeyWrapper; + this.initFunc = s -> initFunc.get(); + this.consumerFunc = consumerFunc; + this.valueSupplier = k -> this.get(k).longValue(); + } + + public boolean specifyType(String type) { + return type.equals(getMetricsKeyWrapper().getType()); + } + + public MetricsKeyWrapper getMetricsKeyWrapper() { + return metricsKeyWrapper; + } + + public boolean isKeyWrapper(MetricsKey metricsKey, String registryOpType) { + return metricsKeyWrapper.isKey(metricsKey,registryOpType); + } + + public Function getInitFunc() { + return initFunc; + } + + public BiConsumer getConsumerFunc() { + return consumerFunc; + } + + public Function getValueSupplier() { + return valueSupplier; + } + + public void setValueSupplier(Function valueSupplier) { + this.valueSupplier = valueSupplier; + } + + @Override + public String toString() { + return "LongContainer{" + + "metricsKeyWrapper=" + metricsKeyWrapper + + '}'; + } + } + + public static class AtomicLongContainer extends LongContainer { + + public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper) { + super(metricsKeyWrapper, AtomicLong::new, (responseTime, longAccumulator) -> longAccumulator.set(responseTime)); + } + + public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper, BiConsumer consumerFunc) { + super(metricsKeyWrapper, AtomicLong::new, consumerFunc); + } + + } + + public static class LongAccumulatorContainer extends LongContainer { + public LongAccumulatorContainer(MetricsKeyWrapper metricsKeyWrapper, LongAccumulator accumulator) { + super(metricsKeyWrapper, () -> accumulator, (responseTime, longAccumulator) -> longAccumulator.accumulate(responseTime)); + } + } + + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java new file mode 100644 index 0000000000..0b39ff8376 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.metrics.registry.collector.stat; + +import org.apache.dubbo.metrics.model.Metric; + +import java.util.HashMap; +import java.util.Map; + +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; +import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; +import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; + +/** + * Metric class for service. + */ +public class ServiceKeyMetric implements Metric { + private final String applicationName; + private final String serviceKey; + + public ServiceKeyMetric(String applicationName, String serviceKey) { + this.applicationName = applicationName; + this.serviceKey = serviceKey; + } + + public String getServiceKey() { + return serviceKey; + } + + public Map getTags() { + Map tags = new HashMap<>(); + tags.put(TAG_IP, getLocalHost()); + tags.put(TAG_HOSTNAME, getLocalHostName()); + tags.put(TAG_APPLICATION_NAME, applicationName); + + tags.put(TAG_INTERFACE_KEY, serviceKey); + return tags; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ServiceKeyMetric that = (ServiceKeyMetric) o; + + if (!applicationName.equals(that.applicationName)) return false; + return serviceKey.equals(that.serviceKey); + } + + @Override + public int hashCode() { + int result = applicationName.hashCode(); + result = 31 * result + serviceKey.hashCode(); + return result; + } + + @Override + public String toString() { + return "ServiceKeyMetric{" + + "applicationName='" + applicationName + '\'' + + ", serviceKey='" + serviceKey + '\'' + + '}'; + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsDirectoryListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsDirectoryListener.java new file mode 100644 index 0000000000..27648f962d --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsDirectoryListener.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.metrics.registry.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsListener; + +public class MetricsDirectoryListener implements MetricsListener { + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof RegistryEvent.MetricsDirectoryEvent; + } + + @Override + public void onEvent(RegistryEvent.MetricsDirectoryEvent event) { + if (!event.isAvailable()) { + return; + } + if (event.getType().isIncrement()) { + event.getCollector().increment(event.getSource().getApplicationName(), event.getType()); + } else { + event.getCollector().setNum(event.getType(), event.getSource().getApplicationName(), event.getSize()); + } + } + + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java new file mode 100644 index 0000000000..3b5561cb1f --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java @@ -0,0 +1,54 @@ +/* + * 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.metrics.registry.event; + +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; + +import static org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_NOTIFY; + +/** + * The registration center actively pushes Listener, no failure and rt statistics + */ +public class MetricsNotifyListener implements MetricsLifeListener { + + protected final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass()); + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof RegistryEvent.MetricsNotifyEvent; + } + + @Override + public void onEvent(RegistryEvent.MetricsNotifyEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.N_TOTAL); + } + + @Override + public void onEventFinish(RegistryEvent.MetricsNotifyEvent event) { + event.getCollector().setNum(RegistryEvent.Type.N_LAST_NUM, event.getSource().getApplicationName(), event.getLastNotifyNum()); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_NOTIFY, event.getTimePair().calc()); + } + + @Override + public void onEventError(RegistryEvent.MetricsNotifyEvent event) { + } + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsRegisterListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsRegisterListener.java new file mode 100644 index 0000000000..f3c6352fcf --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsRegisterListener.java @@ -0,0 +1,52 @@ +/* + * 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.metrics.registry.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; + +import static org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_REGISTER; + +public class MetricsRegisterListener implements MetricsLifeListener { + + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof RegistryEvent.MetricsRegisterEvent; + } + + @Override + public void onEvent(RegistryEvent.MetricsRegisterEvent event) { + if (!event.isAvailable()) { + return; + } + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.R_TOTAL); + } + + @Override + public void onEventFinish(RegistryEvent.MetricsRegisterEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.R_SUCCEED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_REGISTER, event.getTimePair().calc()); + } + + @Override + public void onEventError(RegistryEvent.MetricsRegisterEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.R_FAILED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_REGISTER, event.getTimePair().calc()); + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java new file mode 100644 index 0000000000..abfc5a0624 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java @@ -0,0 +1,52 @@ +/* + * 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.metrics.registry.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; + +import static org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_SUBSCRIBE; + +public class MetricsSubscribeListener implements MetricsLifeListener { + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof RegistryEvent.MetricsSubscribeEvent; + } + + @Override + public void onEvent(RegistryEvent.MetricsSubscribeEvent event) { + if (!event.isAvailable()) { + return; + } + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.S_TOTAL); + } + + @Override + public void onEventFinish(RegistryEvent.MetricsSubscribeEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.S_SUCCEED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_SUBSCRIBE, event.getTimePair().calc()); + } + + @Override + public void onEventError(RegistryEvent.MetricsSubscribeEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.S_FAILED); + event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_SUBSCRIBE, event.getTimePair().calc()); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java new file mode 100644 index 0000000000..c13eb2310d --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryEvent.java @@ -0,0 +1,156 @@ +/* + * 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.metrics.registry.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.event.TimeCounter; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import java.util.Map; + +/** + * Registry related events + */ +public class RegistryEvent extends MetricsEvent implements TimeCounter { + private final TimePair timePair; + private final RegistryMetricsCollector collector; + private final boolean available; + + public RegistryEvent(ApplicationModel applicationModel, TimePair timePair) { + super(applicationModel); + this.timePair = timePair; + this.collector = applicationModel.getBeanFactory().getBean(RegistryMetricsCollector.class); + this.available = this.collector != null && collector.isCollectEnabled(); + } + + public ApplicationModel getSource() { + return (ApplicationModel) source; + } + + public RegistryMetricsCollector getCollector() { + return collector; + } + + public boolean isAvailable() { + return available; + } + + @Override + public TimePair getTimePair() { + return timePair; + } + + public enum Type { + R_TOTAL(MetricsKey.REGISTER_METRIC_REQUESTS), + R_SUCCEED(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED), + R_FAILED(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED), + + S_TOTAL(MetricsKey.SUBSCRIBE_METRIC_NUM), + S_SUCCEED(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED), + S_FAILED(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED), + + D_VALID(MetricsKey.DIRECTORY_METRIC_NUM_VALID), + D_UN_VALID(MetricsKey.DIRECTORY_METRIC_NUM_UN_VALID), + D_DISABLE(MetricsKey.DIRECTORY_METRIC_NUM_DISABLE), + D_CURRENT(MetricsKey.DIRECTORY_METRIC_NUM_CURRENT, false), + D_RECOVER_DISABLE(MetricsKey.DIRECTORY_METRIC_NUM_RECOVER_DISABLE), + + N_TOTAL(MetricsKey.NOTIFY_METRIC_REQUESTS), + N_LAST_NUM(MetricsKey.NOTIFY_METRIC_NUM_LAST), + ; + + + private final MetricsKey metricsKey; + private final boolean isIncrement; + + + Type(MetricsKey metricsKey) { + this(metricsKey, true); + } + + Type(MetricsKey metricsKey, boolean isIncrement) { + this.metricsKey = metricsKey; + this.isIncrement = isIncrement; + } + + public MetricsKey getMetricsKey() { + return metricsKey; + } + + public boolean isIncrement() { + return isIncrement; + } + } + + public static class MetricsRegisterEvent extends RegistryEvent { + + public MetricsRegisterEvent(ApplicationModel applicationModel, TimePair timePair) { + super(applicationModel, timePair); + } + + } + + public static class MetricsSubscribeEvent extends RegistryEvent { + + public MetricsSubscribeEvent(ApplicationModel applicationModel, TimePair timePair) { + super(applicationModel, timePair); + } + + } + + public static class MetricsNotifyEvent extends RegistryEvent { + + private final Map lastNumMap; + + public MetricsNotifyEvent(ApplicationModel applicationModel, TimePair timePair, Map lastNumMap) { + super(applicationModel, timePair); + this.lastNumMap = lastNumMap; + } + + public Map getLastNotifyNum() { + return lastNumMap; + } + } + + public static class MetricsDirectoryEvent extends RegistryEvent { + + private final RegistryEvent.Type type; + private final int size; + + public MetricsDirectoryEvent(ApplicationModel applicationModel, RegistryEvent.Type type) { + this(applicationModel, type, 1); + } + + public MetricsDirectoryEvent(ApplicationModel applicationModel, RegistryEvent.Type type, int size) { + super(applicationModel, TimePair.empty()); + this.type = type; + this.size = size; + } + + public RegistryEvent.Type getType() { + return type; + } + + public int getSize() { + return size; + } + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java new file mode 100644 index 0000000000..566607efdb --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/RegistryMetricsEventMulticaster.java @@ -0,0 +1,33 @@ +/* + * 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.metrics.registry.event; + +import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster; + +public final class RegistryMetricsEventMulticaster extends SimpleMetricsEventMulticaster { + + public RegistryMetricsEventMulticaster() { + super.addListener(new MetricsRegisterListener()); + super.addListener(new MetricsSubscribeListener()); + super.addListener(new MetricsNotifyListener()); + super.addListener(new MetricsDirectoryListener()); + + setAvailable(); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector b/dubbo-metrics/dubbo-metrics-registry/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector new file mode 100644 index 0000000000..3b14cf6c7b --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector @@ -0,0 +1 @@ +registry-collector=org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java new file mode 100644 index 0000000000..d4e8f34cec --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java @@ -0,0 +1,115 @@ +/* + * 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.metrics.registry.metrics.collector; + +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; +import static org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_REGISTER; + + +class RegistryMetricsCollectorTest { + + private ApplicationModel applicationModel; + + @BeforeEach + public void setup() { + FrameworkModel frameworkModel = FrameworkModel.defaultModel(); + applicationModel = frameworkModel.newApplication(); + ApplicationConfig config = new ApplicationConfig(); + config.setName("MockMetrics"); + + applicationModel.getApplicationConfigManager().setApplication(config); + + } + + @AfterEach + public void teardown() { + applicationModel.destroy(); + } + + @Test + void testPushMetrics() throws InterruptedException { + + TimePair timePair = TimePair.start(); + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getOrRegisterBean(GlobalMetricsEventMulticaster.class); + RegistryMetricsCollector collector = applicationModel.getBeanFactory().getOrRegisterBean(RegistryMetricsCollector.class); + collector.setCollectEnabled(true); + + eventMulticaster.publishEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, timePair)); + List metricSamples = collector.collect(); + + // push success +1 + Assertions.assertEquals(metricSamples.size(), 1); + Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); + + eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, timePair)); + // push finish rt +1 + metricSamples = collector.collect(); + //num(total+success) + rt(5) = 7 + Assertions.assertEquals(metricSamples.size(), 7); + long c1 = timePair.calc(); + TimePair lastTimePair = TimePair.start(); + eventMulticaster.publishEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, lastTimePair)); + Thread.sleep(50); + // push error rt +1 + eventMulticaster.publishErrorEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, lastTimePair)); + long c2 = lastTimePair.calc(); + metricSamples = collector.collect(); + + // num(total+success+error) + rt(5) + Assertions.assertEquals(metricSamples.size(), 8); + + // calc rt + for (MetricSample sample : metricSamples) { + Map tags = sample.getTags(); + Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationModel.getApplicationName()); + } + Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { + Number number = ((GaugeMetricSample) k).getSupplier().get(); + return number.longValue(); + })); + + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc()); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), c1 + c2); + } + + + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java new file mode 100644 index 0000000000..92025d71c9 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java @@ -0,0 +1,97 @@ +/* + * 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.metrics.registry.metrics.collector; + +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector; +import org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; + +class RegistryMetricsSampleTest { + + private ApplicationModel applicationModel; + + @BeforeEach + public void setup() { + FrameworkModel frameworkModel = FrameworkModel.defaultModel(); + applicationModel = frameworkModel.newApplication(); + ApplicationConfig config = new ApplicationConfig(); + config.setName("MockMetrics"); + applicationModel.getApplicationConfigManager().setApplication(config); + } + + @AfterEach + public void teardown() { + applicationModel.destroy(); + } + + @Test + void testRegisterMetrics() { + } + + @Test + void testRTMetrics() { + RegistryMetricsCollector collector = new RegistryMetricsCollector(applicationModel); + collector.setCollectEnabled(true); + String applicationName = applicationModel.getApplicationName(); + collector.addRT(applicationName, RegistryStatComposite.OP_TYPE_REGISTER, 10L); + collector.addRT(applicationName, RegistryStatComposite.OP_TYPE_REGISTER, 0L); + + List samples = collector.collect(); + for (MetricSample sample : samples) { + Map tags = sample.getTags(); + Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationName); + } + + Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { + Number number = ((GaugeMetricSample) k).getSupplier().get(); + return number.longValue(); + })); + + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), 0L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), 0L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), 10L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), 5L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), 10L); + } + + @Test + void testListener() { + RegistryMetricsCollector collector = new RegistryMetricsCollector(applicationModel); + collector.setCollectEnabled(true); + String applicationName = applicationModel.getApplicationName(); + collector.increment(applicationName,RegistryEvent.Type.R_TOTAL); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java new file mode 100644 index 0000000000..44beb3a608 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java @@ -0,0 +1,79 @@ +/* + * 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.metrics.registry.metrics.model; + +import org.apache.dubbo.metrics.model.MethodMetric; +import org.apache.dubbo.rpc.RpcInvocation; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_VERSION_KEY; +import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; +import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; + +class MethodMetricTest { + + private static final String applicationName = null; + private static String interfaceName; + private static String methodName; + private static String group; + private static String version; + private static RpcInvocation invocation; + + @BeforeAll + public static void setup() { + interfaceName = "org.apache.dubbo.MockInterface"; + methodName = "mockMethod"; + group = "mockGroup"; + version = "1.0.0"; + invocation = new RpcInvocation(methodName, interfaceName, "serviceKey", null, null); + invocation.setTargetServiceUniqueName(group + "/" + interfaceName + ":" + version); + invocation.setAttachment(GROUP_KEY, group); + invocation.setAttachment(VERSION_KEY, version); + } + + @Test + void test() { + MethodMetric metric = new MethodMetric(applicationName, invocation); + Assertions.assertEquals(metric.getInterfaceName(), interfaceName); + Assertions.assertEquals(metric.getMethodName(), methodName); + Assertions.assertEquals(metric.getGroup(), group); + Assertions.assertEquals(metric.getVersion(), version); + + Map tags = metric.getTags(); + Assertions.assertEquals(tags.get(TAG_IP), getLocalHost()); + Assertions.assertEquals(tags.get(TAG_HOSTNAME), getLocalHostName()); + Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationName); + + Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), interfaceName); + Assertions.assertEquals(tags.get(TAG_METHOD_KEY), methodName); + Assertions.assertEquals(tags.get(TAG_GROUP_KEY), group); + Assertions.assertEquals(tags.get(TAG_VERSION_KEY), version); + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java new file mode 100644 index 0000000000..bfa6d2e176 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java @@ -0,0 +1,63 @@ +/* + * 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.metrics.registry.metrics.model.sample; + +import org.apache.dubbo.metrics.model.MetricsCategory; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +class GaugeMetricSampleTest { + + private static String name; + private static String description; + private static Map tags; + private static MetricsCategory category; + private static String baseUnit; + private static Supplier supplier; + + @BeforeAll + public static void setup() { + name = "test"; + description = "test"; + tags = new HashMap<>(); + category = MetricsCategory.REQUESTS; + baseUnit = "byte"; + supplier = () -> 1; + } + + @Test + void test() { + GaugeMetricSample sample = new GaugeMetricSample(name, description, tags, category, baseUnit, supplier); + Assertions.assertEquals(sample.getName(), name); + Assertions.assertEquals(sample.getDescription(), description); + Assertions.assertEquals(sample.getTags(), tags); + Assertions.assertEquals(sample.getType(), MetricSample.Type.GAUGE); + Assertions.assertEquals(sample.getCategory(), category); + Assertions.assertEquals(sample.getBaseUnit(), baseUnit); + Assertions.assertEquals(sample.getSupplier().get(), 1); + sample.setSupplier(() -> 2); + Assertions.assertEquals(sample.getSupplier().get(), 2); + } +} diff --git a/dubbo-metrics/pom.xml b/dubbo-metrics/pom.xml index 835c2b1b44..d5527ecf7c 100644 --- a/dubbo-metrics/pom.xml +++ b/dubbo-metrics/pom.xml @@ -20,6 +20,7 @@ dubbo-metrics-api dubbo-metrics-default + dubbo-metrics-registry dubbo-metrics-metadata dubbo-metrics-prometheus diff --git a/dubbo-registry/dubbo-registry-api/pom.xml b/dubbo-registry/dubbo-registry-api/pom.xml index f9c580f8c9..4c3a15f353 100644 --- a/dubbo-registry/dubbo-registry-api/pom.xml +++ b/dubbo-registry/dubbo-registry-api/pom.xml @@ -98,5 +98,12 @@ ${project.parent.version} compile + + + org.apache.dubbo + dubbo-metrics-registry + ${project.parent.version} + compile + diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java index c6eb7a83ec..0859c1e9e2 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java @@ -16,6 +16,32 @@ */ package org.apache.dubbo.registry.client.event.listener; +import org.apache.dubbo.common.ProtocolServiceKey; +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.URLBuilder; +import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; +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.threadpool.manager.FrameworkExecutorRepository; +import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.common.utils.ConcurrentHashSet; +import org.apache.dubbo.metadata.MetadataInfo; +import org.apache.dubbo.metadata.MetadataInfo.ServiceInfo; +import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; +import org.apache.dubbo.registry.NotifyListener; +import org.apache.dubbo.registry.client.DefaultServiceInstance; +import org.apache.dubbo.registry.client.ServiceDiscovery; +import org.apache.dubbo.registry.client.ServiceInstance; +import org.apache.dubbo.registry.client.event.RetryServiceInstancesChangedEvent; +import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent; +import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils; +import org.apache.dubbo.registry.client.metadata.ServiceInstanceNotificationCustomizer; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.ScopeModelUtil; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -32,28 +58,6 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.dubbo.common.ProtocolServiceKey; -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.URLBuilder; -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.threadpool.manager.FrameworkExecutorRepository; -import org.apache.dubbo.common.utils.CollectionUtils; -import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.metadata.MetadataInfo; -import org.apache.dubbo.metadata.MetadataInfo.ServiceInfo; -import org.apache.dubbo.registry.NotifyListener; -import org.apache.dubbo.registry.client.DefaultServiceInstance; -import org.apache.dubbo.registry.client.ServiceDiscovery; -import org.apache.dubbo.registry.client.ServiceInstance; -import org.apache.dubbo.registry.client.event.RetryServiceInstancesChangedEvent; -import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent; -import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils; -import org.apache.dubbo.registry.client.metadata.ServiceInstanceNotificationCustomizer; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; - import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR; import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_REFRESH_ADDRESS; @@ -87,6 +91,7 @@ public class ServiceInstancesChangedListener { private final ScheduledExecutorService scheduler; private volatile boolean hasEmptyMetadata; private final Set serviceInstanceNotificationCustomizers; + private final ApplicationModel applicationModel; public ServiceInstancesChangedListener(Set serviceNames, ServiceDiscovery serviceDiscovery) { @@ -99,6 +104,7 @@ public class ServiceInstancesChangedListener { ApplicationModel applicationModel = ScopeModelUtil.getApplicationModel(serviceDiscovery == null || serviceDiscovery.getUrl() == null ? null : serviceDiscovery.getUrl().getScopeModel()); this.scheduler = applicationModel.getBeanFactory().getBean(FrameworkExecutorRepository.class).getMetadataRetryExecutor(); this.serviceInstanceNotificationCustomizers = applicationModel.getExtensionLoader(ServiceInstanceNotificationCustomizer.class).getSupportedExtensionInstances(); + this.applicationModel = applicationModel; } /** @@ -398,6 +404,13 @@ public class ServiceInstancesChangedListener { * race condition is protected by onEvent/doOnEvent */ protected void notifyAddressChanged() { + + ScopeBeanFactory beanFactory = applicationModel.getFrameworkModel().getBeanFactory(); + SimpleMetricsEventMulticaster eventMulticaster = beanFactory.getOrRegisterBean(SimpleMetricsEventMulticaster.class); + + TimePair timePair = TimePair.start(); + eventMulticaster.publishEvent(new RegistryEvent.MetricsNotifyEvent(applicationModel, timePair, null)); + Map lastNumMap = new HashMap<>(); // 1 different services listeners.forEach((serviceKey, listenerSet) -> { // 2 multiple subscription listener of the same service @@ -407,8 +420,11 @@ public class ServiceInstancesChangedListener { List urls = toUrlsWithEmpty(getAddresses(listenerWithKey.getProtocolServiceKey(), notifyListener.getConsumerUrl())); logger.info("Notify service " + listenerWithKey.getProtocolServiceKey() + " with urls " + urls.size()); notifyListener.notify(urls); + lastNumMap.put(serviceKey, urls.size()); } }); + eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsNotifyEvent(applicationModel, timePair, lastNumMap)); + } protected List toUrlsWithEmpty(List urls) { diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java index a994f1f1c7..65c8ef3190 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java @@ -16,19 +16,6 @@ */ package org.apache.dubbo.registry.integration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.URLBuilder; import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; @@ -43,6 +30,9 @@ import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.common.utils.UrlUtils; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.registry.AddressListener; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.rpc.Invoker; @@ -53,8 +43,22 @@ import org.apache.dubbo.rpc.cluster.Router; import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; import org.apache.dubbo.rpc.cluster.router.state.BitList; import org.apache.dubbo.rpc.cluster.support.ClusterUtils; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ModuleModel; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL; @@ -110,11 +114,18 @@ public class RegistryDirectory extends DynamicDirectory { super(serviceType, url); moduleModel = getModuleModel(url.getScopeModel()); consumerConfigurationListener = getConsumerConfigurationListener(moduleModel); + } @Override public void subscribe(URL url) { + ApplicationModel applicationModel = url.getApplicationModel(); + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); + TimePair timePair = TimePair.start(); + + eventMulticaster.publishEvent(new RegistryEvent.MetricsSubscribeEvent(applicationModel, timePair)); super.subscribe(url); + eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsSubscribeEvent(applicationModel, timePair)); if (moduleModel.getModelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) { consumerConfigurationListener.addNotifyListener(this); referenceConfigurationListener = new ReferenceConfigurationListener(moduleModel, this, url); @@ -233,7 +244,7 @@ public class RegistryDirectory extends DynamicDirectory { // use local reference to avoid NPE as this.cachedInvokerUrls will be set null by destroyAllInvokers(). Set localCachedInvokerUrls = this.cachedInvokerUrls; if (invokerUrls.isEmpty()) { - if(CollectionUtils.isNotEmpty(localCachedInvokerUrls)){ + if (CollectionUtils.isNotEmpty(localCachedInvokerUrls)) { // 1-4 Empty address. logger.warn(REGISTRY_EMPTY_ADDRESS, "configuration ", "", "Service" + serviceKey + " received empty address list with no EMPTY protocol set, trigger empty protection."); diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index 66f84b58f6..8922e63208 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -148,6 +148,11 @@ org.apache.dubbo dubbo-metrics-default + + org.apache.dubbo + dubbo-metrics-registry + + org.apache.dubbo dubbo-metrics-metadata From 5d070383a1452d0b637d00e1082b22f54712f0bb Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Sat, 25 Feb 2023 17:25:04 +0800 Subject: [PATCH 027/144] Metrics RT count optimization (#11628) * Metrics RT count optimization * Fix camel case naming problem --- .../sample/MethodMetricsSampler.java | 23 +--- .../collector/sample/MetricsCountSampler.java | 21 ++-- .../sample/SimpleMetricsCountSampler.java | 111 +++++++++--------- .../sample/ThreadPoolMetricsSampler.java | 9 +- .../filter/MethodMetricsInterceptor.java | 2 +- 5 files changed, 72 insertions(+), 94 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java index 82f0693821..75bc637ab0 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java @@ -31,7 +31,6 @@ import org.apache.dubbo.rpc.Invocation; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; @@ -39,7 +38,7 @@ import static org.apache.dubbo.metrics.model.MetricsCategory.RT; public class MethodMetricsSampler extends SimpleMetricsCountSampler { - private DefaultMetricsCollector collector; + private final DefaultMetricsCollector collector; public MethodMetricsSampler(DefaultMetricsCollector collector) { this.collector = collector; @@ -64,7 +63,7 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler metricSamples = new ArrayList<>(); collect(metricSamples); - collectRT(metricSamples); + metricSamples.addAll(collectRT((key, metric, count) -> getGaugeMetricSample(key, metric, RT, () -> count))); return metricSamples; } @@ -80,24 +79,6 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler list) { - this.getLastRT().forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_LAST, k, RT, v::get) - )); - this.getMinRT().forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_MIN, k, RT, v::get))); - this.getMaxRT().forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_MAX, k, RT, v::get))); - - this.getTotalRT().forEach((k, v) -> { - list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_SUM, k, RT, v::get)); - AtomicLong avg = this.getAvgRT().get(k); - AtomicLong count = this.getRtCount().get(k); - avg.set(v.get() / count.get()); - list.add(getGaugeMetricSample(MetricsKey.METRIC_RT_AVG, k, RT, avg::get)); - }); - } - private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey, MethodMetric methodMetric, MetricsCategory metricsCategory, Supplier get) { return new GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()), metricsKey.getDescription(), diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java index 1d16155c10..06512199aa 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java @@ -18,13 +18,15 @@ package org.apache.dubbo.metrics.collector.sample; import org.apache.dubbo.metrics.model.Metric; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import java.util.List; import java.util.Optional; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.LongAccumulator; -public interface MetricsCountSampler extends MetricsSampler { +public interface MetricsCountSampler extends MetricsSampler { void inc(S source, K metricName); @@ -38,16 +40,9 @@ public interface MetricsCountSampler extends MetricsSampl Optional> getCount(K metricName); - ConcurrentMap getLastRT(); - - ConcurrentMap getMinRT(); - - ConcurrentMap getMaxRT(); - - ConcurrentMap getAvgRT(); - - ConcurrentMap getTotalRT(); - - ConcurrentMap getRtCount(); + List collectRT(MetricSampleFactory factory); + interface MetricSampleFactory { + R newInstance(MetricsKey key, M metric, Long count); + } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java index 1160e5ca76..898e0d9dd8 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java @@ -20,12 +20,17 @@ package org.apache.dubbo.metrics.collector.sample; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.metrics.model.Metric; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongArray; import java.util.concurrent.atomic.LongAccumulator; import java.util.function.Function; @@ -38,18 +43,19 @@ import java.util.function.Function; public abstract class SimpleMetricsCountSampler implements MetricsCountSampler { - private final ConcurrentMap lastRT = new ConcurrentHashMap<>(); - private final ConcurrentMap minRT = new ConcurrentHashMap<>(); - private final ConcurrentMap maxRT = new ConcurrentHashMap<>(); - private final ConcurrentMap avgRT = new ConcurrentHashMap<>(); - private final ConcurrentMap totalRT = new ConcurrentHashMap<>(); - private final ConcurrentMap rtCount = new ConcurrentHashMap<>(); + private final ConcurrentMap EMPTY_COUNT = new ConcurrentHashMap<>(); - private Map> metricCounter = new ConcurrentHashMap<>(); + private final ConcurrentMap minRT = new ConcurrentHashMap<>(); + private final ConcurrentMap maxRT = new ConcurrentHashMap<>(); + + // lastRT, totalRT, rtCount, avgRT share a container, can utilize the system cache line + private final ConcurrentMap rtArray = new ConcurrentHashMap<>(); + + private final Map> metricCounter = new ConcurrentHashMap<>(); @Override public void inc(S source, K metricName) { - doExecute(source,metricName,counter->{ + doExecute(source, metricName, counter -> { counter.incrementAndGet(); return false; }); @@ -57,7 +63,7 @@ public abstract class SimpleMetricsCountSampler @Override public void dec(S source, K metricName) { - doExecute(source,metricName,counter->{ + doExecute(source, metricName, counter -> { counter.decrementAndGet(); return false; }); @@ -65,7 +71,7 @@ public abstract class SimpleMetricsCountSampler @Override public void incOnEvent(S source, K metricName) { - doExecute(source,metricName,counter->{ + doExecute(source, metricName, counter -> { counter.incrementAndGet(); return true; }); @@ -73,7 +79,7 @@ public abstract class SimpleMetricsCountSampler @Override public void decOnEvent(S source, K metricName) { - doExecute(source,metricName,counter->{ + doExecute(source, metricName, counter -> { counter.decrementAndGet(); return true; }); @@ -81,15 +87,26 @@ public abstract class SimpleMetricsCountSampler @Override public void addRT(S source, Long rt) { - MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); + MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); sampleConfigure.setSource(source); this.rtConfigure(sampleConfigure); M metric = sampleConfigure.getMetric(); - AtomicLong last = ConcurrentHashMapUtils.computeIfAbsent(lastRT, metric, k -> new AtomicLong()); - last.set(rt); + AtomicLongArray rtArray = ConcurrentHashMapUtils.computeIfAbsent(this.rtArray, metric, k -> new AtomicLongArray(4)); + + // set lastRT + rtArray.set(0, rt); + + // add to totalRT + rtArray.addAndGet(1, rt); + + // add to rtCount + rtArray.incrementAndGet(2); + + // calc avgRT. In order to reduce the amount of calculation, calculated when collect + //rtArray.set(3, Math.floorDiv(rtArray.get(1), rtArray.get(2))); LongAccumulator min = ConcurrentHashMapUtils.computeIfAbsent(minRT, metric, k -> new LongAccumulator(Long::min, Long.MAX_VALUE)); min.accumulate(rt); @@ -97,65 +114,49 @@ public abstract class SimpleMetricsCountSampler LongAccumulator max = ConcurrentHashMapUtils.computeIfAbsent(maxRT, metric, k -> new LongAccumulator(Long::max, Long.MIN_VALUE)); max.accumulate(rt); - AtomicLong total = ConcurrentHashMapUtils.computeIfAbsent(totalRT, metric, k -> new AtomicLong()); - total.addAndGet(rt); - - AtomicLong count = ConcurrentHashMapUtils.computeIfAbsent(rtCount, metric, k -> new AtomicLong()); - count.incrementAndGet(); - - ConcurrentHashMapUtils.computeIfAbsent(avgRT, metric, key -> new AtomicLong()); - sampleConfigure.setRt(rt); sampleConfigure.getFireEventHandler().accept(sampleConfigure); - } @Override public Optional> getCount(K metricName) { return Optional.ofNullable(metricCounter.get(metricName) == null ? - new ConcurrentHashMap<>() : + EMPTY_COUNT : metricCounter.get(metricName)); } @Override - public ConcurrentMap getLastRT() { - return this.lastRT; + public List collectRT(MetricSampleFactory factory) { + final List rtMetricSamples = new ArrayList<>(); + rtArray.forEach((k, v) -> { + // lastRT + rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_LAST, k, v.get(0))); + // totalRT + long totalRT = v.get(1); + long rtCount = v.get(2); + rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_SUM, k, totalRT)); + // avgRT + rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_AVG, k, Math.floorDiv(totalRT, rtCount))); + }); + + this.minRT.forEach((k, v) -> + rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MIN, k, v.get()))); + + this.maxRT.forEach((k, v) -> + rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MAX, k, v.get()))); + + return rtMetricSamples; } - @Override - public ConcurrentMap getMinRT() { - return this.minRT; - } - - @Override - public ConcurrentMap getMaxRT() { - return this.maxRT; - } - - @Override - public ConcurrentMap getAvgRT() { - return this.avgRT; - } - - @Override - public ConcurrentMap getTotalRT() { - return this.totalRT; - } - - @Override - public ConcurrentMap getRtCount() { - return this.rtCount; - } - - protected void rtConfigure(MetricsCountSampleConfigurer configure) { + protected void rtConfigure(MetricsCountSampleConfigurer configure) { } - protected abstract void countConfigure(MetricsCountSampleConfigurer sampleConfigure); + protected abstract void countConfigure(MetricsCountSampleConfigurer sampleConfigure); - private void doExecute(S source,K metricsName,Function counter){ - MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); + private void doExecute(S source, K metricsName, Function counter) { + MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); sampleConfigure.setSource(source); sampleConfigure.setMetricsName(metricsName); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java index 67cb73d3fe..17ad4bb5e3 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java @@ -35,9 +35,9 @@ import static org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL; public class ThreadPoolMetricsSampler implements MetricsSampler { - private DefaultMetricsCollector collector; + private final DefaultMetricsCollector collector; private FrameworkExecutorRepository frameworkExecutorRepository; - private Set threadPoolMetricSet = new HashSet<>(); + private final Set threadPoolMetricSet = new HashSet<>(); public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) { this.collector = collector; @@ -58,11 +58,12 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { } private void collect() { - try{ + try { if (this.frameworkExecutorRepository == null) { this.frameworkExecutorRepository = collector.getApplicationModel().getFrameworkModel().getBeanFactory().getBean(FrameworkExecutorRepository.class); } - }catch(Exception ex){} + } catch (Exception ignored) { + } if (frameworkExecutorRepository != null) { addThread("SharedExecutor", frameworkExecutorRepository.getSharedExecutor()); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java index d327dcb789..9dd6113909 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java @@ -29,7 +29,7 @@ import static org.apache.dubbo.common.constants.MetricsConstants.METRIC_FILTER_S public class MethodMetricsInterceptor { - private MethodMetricsSampler sampler; + private final MethodMetricsSampler sampler; public MethodMetricsInterceptor(MethodMetricsSampler sampler) { this.sampler = sampler; From 837b9c5515936ef16710743b54783f53c0581e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=AA=E4=B8=8D=E7=9F=A5=E5=90=8D=E7=9A=84Java?= =?UTF-8?q?=E9=9D=93=E4=BB=94?= Date: Sat, 25 Feb 2023 18:26:47 +0800 Subject: [PATCH 028/144] remove duplicate flowcontroller listener (#11642) * remove duplicate flowcontroller listener * remove duplicate flowcontroller listener --- .../tri/TripleHttp2FrameCodecBuilder.java | 70 +++++++++++++++++++ .../rpc/protocol/tri/TripleHttp2Protocol.java | 9 ++- 2 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2FrameCodecBuilder.java diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2FrameCodecBuilder.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2FrameCodecBuilder.java new file mode 100644 index 0000000000..217b8c1496 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2FrameCodecBuilder.java @@ -0,0 +1,70 @@ +/* + * 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.protocol.tri; + +import io.netty.handler.codec.http2.DefaultHttp2Connection; +import io.netty.handler.codec.http2.Http2CodecUtil; +import io.netty.handler.codec.http2.Http2Connection; +import io.netty.handler.codec.http2.Http2FrameCodecBuilder; +import io.netty.handler.codec.http2.Http2LocalFlowController; +import io.netty.handler.codec.http2.Http2RemoteFlowController; +import org.apache.dubbo.common.utils.Assert; + +import java.util.function.Consumer; + +public class TripleHttp2FrameCodecBuilder extends Http2FrameCodecBuilder { + + TripleHttp2FrameCodecBuilder(Http2Connection connection) { + connection(connection); + } + + public static TripleHttp2FrameCodecBuilder fromConnection(Http2Connection connection) { + return new TripleHttp2FrameCodecBuilder(connection); + } + + public static TripleHttp2FrameCodecBuilder forClient() { + return forClient(Http2CodecUtil.SMALLEST_MAX_CONCURRENT_STREAMS); + } + + public static TripleHttp2FrameCodecBuilder forClient(int maxReservedStreams) { + return fromConnection(new DefaultHttp2Connection(false, maxReservedStreams)); + } + + public static TripleHttp2FrameCodecBuilder forServer() { + return forServer(Http2CodecUtil.SMALLEST_MAX_CONCURRENT_STREAMS); + } + + public static TripleHttp2FrameCodecBuilder forServer(int maxReservedStreams) { + return fromConnection(new DefaultHttp2Connection(true, maxReservedStreams)); + } + + public TripleHttp2FrameCodecBuilder customizeConnection(Consumer connectionCustomizer) { + Http2Connection connection = this.connection(); + Assert.notNull(connection, "connection cannot be null."); + connectionCustomizer.accept(connection); + return this; + } + + public TripleHttp2FrameCodecBuilder remoteFlowController(Http2RemoteFlowController remoteFlowController) { + return this.customizeConnection((connection) -> connection.remote().flowController(remoteFlowController)); + } + + public TripleHttp2FrameCodecBuilder localFlowController(Http2LocalFlowController localFlowController) { + return this.customizeConnection((connection) -> connection.local().flowController(localFlowController)); + } +} diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java index d13e4bfcd2..321af9d614 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java @@ -43,7 +43,6 @@ import org.apache.dubbo.rpc.protocol.tri.transport.TripleWriteQueue; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http2.Http2FrameCodec; -import io.netty.handler.codec.http2.Http2FrameCodecBuilder; import io.netty.handler.codec.http2.Http2FrameLogger; import io.netty.handler.codec.http2.Http2MultiplexHandler; import io.netty.handler.codec.http2.Http2Settings; @@ -113,7 +112,8 @@ public class TripleHttp2Protocol extends AbstractWireProtocol implements ScopeMo } else { headFilters = Collections.emptyList(); } - final Http2FrameCodec codec = Http2FrameCodecBuilder.forServer() + final Http2FrameCodec codec = TripleHttp2FrameCodecBuilder.forServer() + .customizeConnection((connection) -> connection.remote().flowController(new TriHttp2RemoteFlowController(connection, url.getOrDefaultApplicationModel()))) .gracefulShutdownTimeoutMillis(10000) .initialSettings(new Http2Settings().headerTableSize( config.getInt(H2_SETTINGS_HEADER_TABLE_SIZE_KEY, DEFAULT_SETTING_HEADER_LIST_SIZE)) @@ -127,7 +127,6 @@ public class TripleHttp2Protocol extends AbstractWireProtocol implements ScopeMo .frameLogger(SERVER_LOGGER) .build(); ExecutorSupport executorSupport = ExecutorRepository.getInstance(url.getOrDefaultApplicationModel()).getExecutorSupport(url); - codec.connection().remote().flowController(new TriHttp2RemoteFlowController(codec.connection(), url.getOrDefaultApplicationModel())); codec.connection().local().flowController().frameWriter(codec.encoder().frameWriter()); TripleWriteQueue writeQueue = new TripleWriteQueue(); final Http2MultiplexHandler handler = new Http2MultiplexHandler( @@ -152,7 +151,8 @@ public class TripleHttp2Protocol extends AbstractWireProtocol implements ScopeMo @Override public void configClientPipeline(URL url, ChannelOperator operator, ContextOperator contextOperator) { - final Http2FrameCodec codec = Http2FrameCodecBuilder.forClient() + final Http2FrameCodec codec = TripleHttp2FrameCodecBuilder.forClient() + .customizeConnection((connection) -> connection.remote().flowController(new TriHttp2RemoteFlowController(connection, url.getOrDefaultApplicationModel()))) .gracefulShutdownTimeoutMillis(10000) .initialSettings(new Http2Settings().headerTableSize( config.getInt(H2_SETTINGS_HEADER_TABLE_SIZE_KEY, DEFAULT_SETTING_HEADER_LIST_SIZE)) @@ -166,7 +166,6 @@ public class TripleHttp2Protocol extends AbstractWireProtocol implements ScopeMo DEFAULT_MAX_HEADER_LIST_SIZE))) .frameLogger(CLIENT_LOGGER) .build(); - codec.connection().remote().flowController(new TriHttp2RemoteFlowController(codec.connection(), url.getOrDefaultApplicationModel())); codec.connection().local().flowController().frameWriter(codec.encoder().frameWriter()); final Http2MultiplexHandler handler = new Http2MultiplexHandler( new TripleClientHandler(frameworkModel)); From 9e38c48b685b6e47862f697add746b018c745ab0 Mon Sep 17 00:00:00 2001 From: earthchen Date: Sat, 25 Feb 2023 20:12:34 +0800 Subject: [PATCH 029/144] fix tri wrapper pack npe (#11656) --- .../dubbo/rpc/protocol/tri/ReflectionPackableMethod.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java index 39e16fa7cd..8667beb87a 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java @@ -360,6 +360,7 @@ public class ReflectionPackableMethod implements PackableMethod { private final String serialize; private final MultipleSerialization multipleSerialization; private final String[] argumentsType; + private final Class[] actualRequestTypes; private final URL url; private final boolean singleArgument; @@ -371,6 +372,7 @@ public class ReflectionPackableMethod implements PackableMethod { this.url = url; this.serialize = convertHessianToWrapper(serialize); this.multipleSerialization = multipleSerialization; + this.actualRequestTypes = actualRequestTypes; this.argumentsType = Stream.of(actualRequestTypes).map(Class::getName).toArray(String[]::new); this.singleArgument = singleArgument; } @@ -388,9 +390,10 @@ public class ReflectionPackableMethod implements PackableMethod { for (String type : argumentsType) { builder.addArgTypes(type); } - for (Object argument : arguments) { + for (int i = 0; i < arguments.length; i++) { + Object argument = arguments[i]; ByteArrayOutputStream bos = new ByteArrayOutputStream(); - multipleSerialization.serialize(url, serialize, argument.getClass(), argument, bos); + multipleSerialization.serialize(url, serialize, actualRequestTypes[i], argument, bos); builder.addArgs(bos.toByteArray()); } return builder.build().toByteArray(); From 4ee5d0251bcfee4b889359e455e29df671f1c699 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sun, 26 Feb 2023 11:22:35 +0800 Subject: [PATCH 030/144] Update .licenserc.yaml --- .licenserc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.licenserc.yaml b/.licenserc.yaml index 651c2f5076..8c08d076f4 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -192,6 +192,8 @@ dependency: license: EPL-2.0 - name: org.glassfish:jakarta.el license: EPL-2.0 + - name: org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec + license: CDDL-1.1 - name: org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.1_spec license: EPL-2.0 - name: org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec From d2e9dcea33d60d34c2e9b67db731b00db6a0566e Mon Sep 17 00:00:00 2001 From: conghuhu <56248584+conghuhu@users.noreply.github.com> Date: Sun, 26 Feb 2023 12:06:18 +0800 Subject: [PATCH 031/144] fix: fix observation spi config (#11660) * fix: fix observation spi config * fix: fix ObservationFilter style --- .../dubbo/metrics/observation/ObservationReceiverFilter.java | 3 ++- .../dubbo/metrics/observation/ObservationSenderFilter.java | 3 ++- .../META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter | 3 ++- .../internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java index ba4e1957d8..e3b039177e 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java @@ -18,6 +18,7 @@ package org.apache.dubbo.metrics.observation; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; + import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.metrics.filter.observation.DefaultDubboServerObservationConvention; import org.apache.dubbo.metrics.filter.observation.DubboObservation; @@ -37,7 +38,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; /** * A {@link Filter} that creates an {@link Observation} around the incoming message. */ -@Activate(group = PROVIDER, order = -1,onClass = "io.micrometer.observation.NoopObservationRegistry") +@Activate(group = PROVIDER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry") public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, ScopeModelAware { private final ObservationRegistry observationRegistry; diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java index a3ffcc8e5d..356c824f6e 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java @@ -18,6 +18,7 @@ package org.apache.dubbo.metrics.observation; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; + import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.metrics.filter.observation.DefaultDubboClientObservationConvention; import org.apache.dubbo.metrics.filter.observation.DubboClientContext; @@ -38,7 +39,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; /** * A {@link Filter} that creates an {@link Observation} around the outgoing message. */ -@Activate(group = CONSUMER, order = -1,onClass = "io.micrometer.observation.NoopObservationRegistry") +@Activate(group = CONSUMER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry") public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware { private final ObservationRegistry observationRegistry; diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter index c169595307..5ee6c1d455 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter +++ b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter @@ -1 +1,2 @@ -metrics-beta=org.apache.dubbo.metrics.filter.MetricsFilter \ No newline at end of file +metrics-beta=org.apache.dubbo.metrics.filter.MetricsFilter +observationreceiver=org.apache.dubbo.metrics.observation.ObservationReceiverFilter \ No newline at end of file diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter index 2e0234add3..8407d6c769 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter +++ b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter @@ -1 +1 @@ -observationsender=org.apache.dubbo.metrics.filter.observation.ObservationSenderFilter +observationsender=org.apache.dubbo.metrics.observation.ObservationSenderFilter From 9497802ec338b4dde815c98546a8efbe8ee31873 Mon Sep 17 00:00:00 2001 From: huazhongming Date: Sun, 26 Feb 2023 15:14:11 +0800 Subject: [PATCH 032/144] Dubbo maven plugin with native (#11540) * ADD dubbo-maven-plugin * add dubbo-maven-plugin module Signed-off-by: crazyhzm * fix license and compiler error Signed-off-by: crazyhzm * fix license and ci error Signed-off-by: crazyhzm * fix ci error Signed-off-by: crazyhzm * Remove proxy-config, hard code Signed-off-by: crazyhzm * ignoredModulesInDubboAll Signed-off-by: crazyhzm * throw exception for generated adaptive class sources Signed-off-by: crazyhzm --------- Signed-off-by: crazyhzm Co-authored-by: Albumen Kevin --- .github/workflows/build-and-test-pr.yml | 8 +- .../build-and-test-scheduled-3.1.yml | 8 +- .../build-and-test-scheduled-3.2.yml | 8 +- .github/workflows/release-test.yml | 8 +- .gitignore | 5 - .licenserc.yaml | 15 + .../org/apache/dubbo/common/utils/Assert.java | 12 + .../dubbo-demo-native-consumer/pom.xml | 90 +- .../META-INF/native-image/proxy-config.json | 7 + .../dubbo-demo-native-provider/pom.xml | 93 +- dubbo-distribution/dubbo-bom/pom.xml | 6 + dubbo-maven-plugin/pom.xml | 109 + .../maven/plugin/aot/AbstractAotMojo.java | 219 ++ .../aot/AbstractDependencyFilterMojo.java | 172 + .../maven/plugin/aot/CommandLineBuilder.java | 136 + .../maven/plugin/aot/DependencyFilter.java | 83 + .../maven/plugin/aot/DubboProcessAotMojo.java | 138 + .../dubbo/maven/plugin/aot/Exclude.java | 26 + .../dubbo/maven/plugin/aot/ExcludeFilter.java | 50 + .../plugin/aot/FilterableDependency.java | 70 + .../dubbo/maven/plugin/aot/Include.java | 26 + .../dubbo/maven/plugin/aot/IncludeFilter.java | 46 + .../aot/JavaCompilerPluginConfiguration.java | 107 + .../maven/plugin/aot/JavaExecutable.java | 71 + .../maven/plugin/aot/JavaProcessExecutor.java | 102 + .../plugin/aot/MatchingGroupIdFilter.java | 47 + .../dubbo/maven/plugin/aot/RunArguments.java | 68 + .../dubbo/maven/plugin/aot/RunProcess.java | 169 + .../META-INF/native-image/jni-config.json | 2 + .../META-INF/native-image/proxy-config.json | 3 + .../META-INF/native-image/reflect-config.json | 2925 +++++++++++++++++ .../native-image/resource-config.json | 169 + .../native-image/serialization-config.json | 2 + .../MetricsReporterFactory$Adaptive.java | 33 - .../threadpool/ThreadPool$Adaptive.java | 30 - ...lationExecutorSupportFactory$Adaptive.java | 33 - dubbo-native/pom.xml | 40 - .../generate/ClassSourceFinder.java} | 6 +- .../generate}/CodeGenerator.java | 25 +- .../MetricsReporterFactory$Adaptive.java | 33 - .../serialize/Serialization$Adaptive.java | 45 - .../threadpool/ThreadPool$Adaptive.java | 30 - .../MetadataReportFactory$Adaptive.java | 33 - .../monitor/MonitorFactory$Adaptive.java | 30 - .../registry/RegistryFactory$Adaptive.java | 30 - .../apache/dubbo/remoting/Codec$Adaptive.java | 41 - .../dubbo/remoting/Codec2$Adaptive.java | 41 - .../dubbo/remoting/Dispatcher$Adaptive.java | 30 - .../dubbo/remoting/Transporter$Adaptive.java | 39 - .../PortUnificationTransporter$Adaptive.java | 39 - .../remoting/exchange/Exchanger$Adaptive.java | 39 - .../apache/dubbo/rpc/Protocol$Adaptive.java | 49 - .../dubbo/rpc/ProxyFactory$Adaptive.java | 50 - .../dubbo/rpc/cluster/Cluster$Adaptive.java | 37 - .../cluster/ConfiguratorFactory$Adaptive.java | 30 - .../rpc/cluster/LoadBalance$Adaptive.java | 31 - .../rpc/cluster/RouterFactory$Adaptive.java | 30 - .../state/StateRouterFactory$Adaptive.java | 30 - ...lationExecutorSupportFactory$Adaptive.java | 33 - dubbo-test/dubbo-dependencies-all/pom.xml | 5 + .../org/apache/dubbo/dependency/FileTest.java | 1 + pom.xml | 16 + 62 files changed, 4860 insertions(+), 1049 deletions(-) create mode 100644 dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/proxy-config.json create mode 100644 dubbo-maven-plugin/pom.xml create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractAotMojo.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractDependencyFilterMojo.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/CommandLineBuilder.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DependencyFilter.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Exclude.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/ExcludeFilter.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/FilterableDependency.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Include.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/IncludeFilter.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaCompilerPluginConfiguration.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaExecutable.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaProcessExecutor.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java create mode 100644 dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java create mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json create mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json create mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json create mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json delete mode 100644 dubbo-native-plugin/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java delete mode 100644 dubbo-native-plugin/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java delete mode 100644 dubbo-native-plugin/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java rename dubbo-native/src/main/java/org/apache/dubbo/{utils/ClassFinder.java => aot/generate/ClassSourceFinder.java} (95%) rename dubbo-native/src/main/java/org/apache/dubbo/{utils => aot/generate}/CodeGenerator.java (81%) delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/monitor/MonitorFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec2$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/remoting/Dispatcher$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/remoting/Transporter$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/remoting/exchange/Exchanger$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/Protocol$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/ProxyFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/Cluster$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/LoadBalance$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java diff --git a/.github/workflows/build-and-test-pr.yml b/.github/workflows/build-and-test-pr.yml index 3dd5536095..1d0174dfd5 100644 --- a/.github/workflows/build-and-test-pr.yml +++ b/.github/workflows/build-and-test-pr.yml @@ -431,8 +431,8 @@ jobs: - name: "Compile and run Dubbo demo for native (Linux)" run: | cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - nohup ./target/demo-native-provider & + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + nohup ./target/dubbo-demo-native-provider & cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - ./target/demo-native-consumer + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + ./target/dubbo-demo-native-consumer diff --git a/.github/workflows/build-and-test-scheduled-3.1.yml b/.github/workflows/build-and-test-scheduled-3.1.yml index eebfdcc395..7b1d67449f 100644 --- a/.github/workflows/build-and-test-scheduled-3.1.yml +++ b/.github/workflows/build-and-test-scheduled-3.1.yml @@ -395,8 +395,8 @@ jobs: - name: "Compile and run Dubbo demo for native (Linux)" run: | cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - nohup ./target/demo-native-provider & + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + nohup ./target/dubbo-demo-native-provider & cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - ./target/demo-native-consumer + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + ./target/dubbo-demo-native-consumer diff --git a/.github/workflows/build-and-test-scheduled-3.2.yml b/.github/workflows/build-and-test-scheduled-3.2.yml index 5c8c43dd34..26593e2dc1 100644 --- a/.github/workflows/build-and-test-scheduled-3.2.yml +++ b/.github/workflows/build-and-test-scheduled-3.2.yml @@ -395,8 +395,8 @@ jobs: - name: "Compile and run Dubbo demo for native (Linux)" run: | cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - nohup ./target/demo-native-provider & + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + nohup ./target/dubbo-demo-native-provider & cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - ./target/demo-native-consumer + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + ./target/dubbo-demo-native-consumer diff --git a/.github/workflows/release-test.yml b/.github/workflows/release-test.yml index 17c591e6c8..08fbec1abc 100644 --- a/.github/workflows/release-test.yml +++ b/.github/workflows/release-test.yml @@ -374,8 +374,8 @@ jobs: - name: "Compile and run Dubbo demo for native (Linux)" run: | cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - nohup ./target/demo-native-provider & + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + nohup ./target/dubbo-demo-native-provider & cd ${{ github.workspace }}/dubbo/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer - ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true - ./target/demo-native-consumer + ${{ github.workspace }}/dubbo/mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean package -P native -Dmaven.test.skip=true native:compile + ./target/dubbo-demo-native-consumer diff --git a/.gitignore b/.gitignore index 4489022701..1f1a579238 100644 --- a/.gitignore +++ b/.gitignore @@ -48,8 +48,3 @@ dubbo-demo/dubbo-demo-triple/build/* # global registry center .tmp -dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image -dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/generated -dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image -dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/generated - diff --git a/.licenserc.yaml b/.licenserc.yaml index 3e6ecd2baf..f28b16a727 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -79,6 +79,21 @@ header: - 'dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/utils/TestSocketUtils.java' - 'dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriHttp2RemoteFlowController.java' - 'dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/serial/SerializingExecutor.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractAotMojo.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractDependencyFilterMojo.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/CommandLineBuilder.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DependencyFilter.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Exclude.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/ExcludeFilter.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/FilterableDependency.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Include.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/IncludeFilter.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaCompilerPluginConfiguration.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaExecutable.java' + - 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaProcessExecutor.java' + - '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' comment: on-failure diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Assert.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Assert.java index 42c7166c2c..9c5ec040ac 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Assert.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Assert.java @@ -17,6 +17,8 @@ package org.apache.dubbo.common.utils; +import java.util.function.Supplier; + public abstract class Assert { protected Assert() { @@ -46,4 +48,14 @@ public abstract class Assert { } } + public static void assertTrue(boolean expression, Supplier messageSupplier) { + if (!expression) { + throw new IllegalStateException(nullSafeGet(messageSupplier)); + } + } + + private static String nullSafeGet(Supplier messageSupplier) { + return (messageSupplier != null ? messageSupplier.get() : null); + } + } diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml index ca585c6368..279701893a 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml @@ -59,10 +59,6 @@ org.apache.dubbo dubbo-remoting-netty4 - - org.apache.dubbo - dubbo-serialization-hessian2 - org.apache.dubbo dubbo-serialization-fastjson2 @@ -94,17 +90,6 @@ - - - dev - - true - - - dev - - - native @@ -114,13 +99,16 @@ org.apache.dubbo - dubbo-native-plugin + dubbo-maven-plugin ${project.version} + + com.apache.dubbo.demo.graalvm.consumer.Application + process-sources - generate + dubbo-process-aot @@ -144,69 +132,19 @@ - org.graalvm.nativeimage - native-image-maven-plugin - 21.2.0 - - - - native-image - - package - - + org.graalvm.buildtools + native-maven-plugin + 0.9.19 - false - demo-native-consumer + ${project.build.outputDirectory} + + true + + 22.3 com.apache.dubbo.demo.graalvm.consumer.Application - - --no-fallback - - --initialize-at-build-time=org.slf4j.MDC - --initialize-at-build-time=org.apache.log4j.MDC - --initialize-at-build-time=org.slf4j.LoggerFactory - --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder - --initialize-at-build-time=org.apache.log4j.helpers.Loader - --initialize-at-build-time=org.apache.log4j.Logger - --initialize-at-build-time=org.apache.log4j.helpers.LogLog - --initialize-at-build-time=org.apache.log4j.LogManager - --initialize-at-build-time=org.apache.log4j.spi.LoggingEvent - --initialize-at-build-time=org.slf4j.impl.Log4jLoggerFactory - --initialize-at-build-time=org.slf4j.impl.Log4jLoggerAdapter - --initialize-at-build-time=org.eclipse.collections.api.factory.Sets - --initialize-at-build-time=io.netty.util.internal.logging.Log4JLogger - - - --initialize-at-run-time=io.netty.channel.epoll.Epoll - --initialize-at-run-time=io.netty.channel.epoll.Native - --initialize-at-run-time=io.netty.channel.epoll.EpollEventLoop - --initialize-at-run-time=io.netty.channel.epoll.EpollEventArray - --initialize-at-run-time=io.netty.channel.DefaultFileRegion - --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventArray - --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventLoop - --initialize-at-run-time=io.netty.channel.kqueue.Native - --initialize-at-run-time=io.netty.channel.unix.Errors - --initialize-at-run-time=io.netty.channel.unix.IovArray - --initialize-at-run-time=io.netty.channel.unix.Limits - --initialize-at-run-time=io.netty.channel.unix.Socket - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier - --initialize-at-run-time=io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod - --initialize-at-run-time=io.netty.handler.ssl.ReferenceCountedOpenSslEngine - --initialize-at-run-time=io.netty.handler.ssl.OpenSslPrivateKeyMethod - --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier - --initialize-at-run-time=io.netty.internal.tcnative.SSL - --initialize-at-run-time=io.netty.handler.ssl.OpenSslAsyncPrivateKeyMethod - --initialize-at-run-time=io.netty.internal.tcnative.SSLPrivateKeyMethod - - --report-unsupported-elements-at-runtime - --allow-incomplete-classpath - --enable-url-protocols=http - -H:+ReportExceptionStackTraces - -H:+AllowJRTFileSystem - + diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/proxy-config.json b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/proxy-config.json new file mode 100644 index 0000000000..49f2fc2d51 --- /dev/null +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/proxy-config.json @@ -0,0 +1,7 @@ +[ + [ + "org.apace.dubbo.graalvm.demo.DemoService", + "org.apache.dubbo.rpc.service.EchoService", + "org.apache.dubbo.rpc.service.Destroyable" + ] +] diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml index 4dff085cc6..b35faa8482 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml @@ -58,10 +58,6 @@ org.apache.dubbo dubbo-remoting-netty4 - - org.apache.dubbo - dubbo-serialization-hessian2 - org.apache.dubbo dubbo-serialization-fastjson2 @@ -94,17 +90,6 @@ - - - dev - - true - - - dev - - - native @@ -115,13 +100,16 @@ org.apache.dubbo - dubbo-native-plugin + dubbo-maven-plugin ${project.version} + + org.apache.dubbo.demo.graalvm.provider.Application + process-sources - generate + dubbo-process-aot @@ -129,7 +117,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.7.0 1.8 1.8 @@ -143,71 +131,20 @@ - - org.graalvm.nativeimage - native-image-maven-plugin - 21.2.0 - - - - native-image - - package - - + org.graalvm.buildtools + native-maven-plugin + 0.9.19 - false - demo-native-provider + ${project.build.outputDirectory} + + true + + 22.3 org.apache.dubbo.demo.graalvm.provider.Application - - --no-fallback - - --initialize-at-build-time=org.slf4j.MDC - --initialize-at-build-time=org.apache.log4j.MDC - --initialize-at-build-time=org.slf4j.LoggerFactory - --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder - --initialize-at-build-time=org.apache.log4j.helpers.Loader - --initialize-at-build-time=org.apache.log4j.Logger - --initialize-at-build-time=org.apache.log4j.helpers.LogLog - --initialize-at-build-time=org.apache.log4j.LogManager - --initialize-at-build-time=org.apache.log4j.spi.LoggingEvent - --initialize-at-build-time=org.slf4j.impl.Log4jLoggerFactory - --initialize-at-build-time=org.slf4j.impl.Log4jLoggerAdapter - --initialize-at-build-time=org.eclipse.collections.api.factory.Sets - --initialize-at-build-time=io.netty.util.internal.logging.Log4JLogger - - - --initialize-at-run-time=io.netty.channel.epoll.Epoll - --initialize-at-run-time=io.netty.channel.epoll.Native - --initialize-at-run-time=io.netty.channel.epoll.EpollEventLoop - --initialize-at-run-time=io.netty.channel.epoll.EpollEventArray - --initialize-at-run-time=io.netty.channel.DefaultFileRegion - --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventArray - --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventLoop - --initialize-at-run-time=io.netty.channel.kqueue.Native - --initialize-at-run-time=io.netty.channel.unix.Errors - --initialize-at-run-time=io.netty.channel.unix.IovArray - --initialize-at-run-time=io.netty.channel.unix.Limits - --initialize-at-run-time=io.netty.channel.unix.Socket - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier - --initialize-at-run-time=io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod - --initialize-at-run-time=io.netty.handler.ssl.ReferenceCountedOpenSslEngine - --initialize-at-run-time=io.netty.handler.ssl.OpenSslPrivateKeyMethod - --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier - --initialize-at-run-time=io.netty.internal.tcnative.SSL - --initialize-at-run-time=io.netty.handler.ssl.OpenSslAsyncPrivateKeyMethod - --initialize-at-run-time=io.netty.internal.tcnative.SSLPrivateKeyMethod - - --report-unsupported-elements-at-runtime - --allow-incomplete-classpath - --enable-url-protocols=http - -H:+ReportExceptionStackTraces - -H:+AllowJRTFileSystem - + diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml index 4b5b5fcd51..988e6cc411 100644 --- a/dubbo-distribution/dubbo-bom/pom.xml +++ b/dubbo-distribution/dubbo-bom/pom.xml @@ -282,6 +282,12 @@ ${project.version} + + org.apache.dubbo + dubbo-maven-plugin + ${project.version} + + org.apache.dubbo diff --git a/dubbo-maven-plugin/pom.xml b/dubbo-maven-plugin/pom.xml new file mode 100644 index 0000000000..e15d57d96f --- /dev/null +++ b/dubbo-maven-plugin/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + + dubbo-parent + org.apache.dubbo + ${revision} + + + dubbo-maven-plugin + + + + Dubbo Maven Plugin + maven-plugin + + + + org.apache.maven + maven-plugin-api + 3.5.4 + + + + org.apache.maven + maven-core + 3.8.7 + provided + + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.7.1 + provided + + + + org.apache.maven.shared + maven-common-artifact-filters + 3.2.0 + + + + org.apache.dubbo + dubbo-common + ${project.version} + + + + + commons-io + commons-io + 2.11.0 + + + + + + + maven-plugin-plugin + 3.7.1 + + + default-addPluginArtifactMetadata + package + + addPluginArtifactMetadata + + + + default-descriptor + process-classes + + descriptor + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + + + diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractAotMojo.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractAotMojo.java new file mode 100644 index 0000000000..efccafd249 --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractAotMojo.java @@ -0,0 +1,219 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; +import org.apache.maven.toolchain.ToolchainManager; + +import javax.tools.Diagnostic; +import javax.tools.DiagnosticListener; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Abstract base class for AOT processing MOJOs. + * + * @author Phillip Webb + * @author Scott Frederick + */ +public abstract class AbstractAotMojo extends AbstractDependencyFilterMojo { + + /** + * The current Maven session. This is used for toolchain manager API calls. + */ + @Parameter(defaultValue = "${session}", readonly = true) + private MavenSession session; + + /** + * The toolchain manager to use to locate a custom JDK. + */ + @Component + private ToolchainManager toolchainManager; + + /** + * Skip the execution. + */ + @Parameter(property = "dubbo.aot.skip", defaultValue = "false") + private boolean skip; + + /** + * List of JVM system properties to pass to the AOT process. + */ + @Parameter + private Map systemPropertyVariables; + + /** + * JVM arguments that should be associated with the AOT process. On command line, make + * sure to wrap multiple values between quotes. + */ + @Parameter(property = "dubbo.aot.jvmArguments") + private String jvmArguments; + + + /** + * Arguments that should be provided to the AOT compile process. On command line, make + * sure to wrap multiple values between quotes. + */ + @Parameter(property = "dubbo.aot.compilerArguments") + private String compilerArguments; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + if (this.skip) { + getLog().debug("Skipping AOT execution as per configuration"); + return; + } + try { + executeAot(); + } catch (Exception ex) { + throw new MojoExecutionException(ex.getMessage(), ex); + } + } + + protected abstract void executeAot() throws Exception; + + protected void generateAotAssets(URL[] classPath, String processorClassName, String... arguments) throws Exception { + List command = CommandLineBuilder.forMainClass(processorClassName) + .withSystemProperties(this.systemPropertyVariables) + .withJvmArguments(new RunArguments(this.jvmArguments).asArray()).withClasspath(classPath) + .withArguments(arguments).build(); + if (getLog().isDebugEnabled()) { + getLog().debug("Generating AOT assets using command: " + command); + } + JavaProcessExecutor processExecutor = new JavaProcessExecutor(this.session, this.toolchainManager); + getLog().info("dir: " + this.project.getBasedir()); + processExecutor.run(this.project.getBasedir(), command, Collections.emptyMap()); + } + + protected final void compileSourceFiles(URL[] classPath, File sourcesDirectory, File outputDirectory) + throws Exception { + List sourceFiles; + try (Stream pathStream = Files.walk(sourcesDirectory.toPath())) { + sourceFiles = pathStream.filter(Files::isRegularFile).map(Path::toFile).collect(Collectors.toList()); + } + if (sourceFiles.isEmpty()) { + return; + } + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) { + JavaCompilerPluginConfiguration compilerConfiguration = new JavaCompilerPluginConfiguration(this.project); + List options = new ArrayList<>(); + options.add("-cp"); + options.add(CommandLineBuilder.ClasspathBuilder.build(Arrays.asList(classPath))); + options.add("-d"); + options.add(outputDirectory.toPath().toAbsolutePath().toString()); + String releaseVersion = compilerConfiguration.getReleaseVersion(); + if (releaseVersion != null) { + options.add("--release"); + options.add(releaseVersion); + } + else { + options.add("--source"); + options.add(compilerConfiguration.getSourceMajorVersion()); + options.add("--target"); + options.add(compilerConfiguration.getTargetMajorVersion()); + } + options.addAll(new RunArguments(this.compilerArguments).getArgs()); + Iterable compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFiles); + Errors errors = new Errors(); + JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, errors, options, null, compilationUnits); + boolean result = task.call(); + if (!result || errors.hasReportedErrors()) { + throw new IllegalStateException("Unable to compile generated source" + errors); + } + } + } + + protected final List getClassPath(File[] directories, ArtifactsFilter... artifactFilters) + throws MojoExecutionException { + List urls = new ArrayList<>(); + Arrays.stream(directories).map(this::toURL).forEach(urls::add); + urls.addAll(getDependencyURLs(artifactFilters)); + return urls; + } + + protected final void copyAll(Path from, Path to) throws IOException { + if (!Files.exists(from)) { + return; + } + List files; + try (Stream pathStream = Files.walk(from)) { + files = pathStream.filter(Files::isRegularFile).collect(Collectors.toList()); + } + for (Path file : files) { + String relativeFileName = file.subpath(from.getNameCount(), file.getNameCount()).toString(); + getLog().debug("Copying '" + relativeFileName + "' to " + to); + Path target = to.resolve(relativeFileName); + Files.createDirectories(target.getParent()); + Files.copy(file, target, StandardCopyOption.REPLACE_EXISTING); + } + } + + /** + * {@link DiagnosticListener} used to collect errors. + */ + protected static class Errors implements DiagnosticListener { + + private final StringBuilder message = new StringBuilder(); + + @Override + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + this.message.append("\n"); + this.message.append(diagnostic.getMessage(Locale.getDefault())); + if (diagnostic.getSource() != null) { + this.message.append(" "); + this.message.append(diagnostic.getSource().getName()); + this.message.append(" "); + this.message.append(diagnostic.getLineNumber()).append(":").append(diagnostic.getColumnNumber()); + } + } + } + + boolean hasReportedErrors() { + return this.message.length() > 0; + } + + @Override + public String toString() { + return this.message.toString(); + } + + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractDependencyFilterMojo.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractDependencyFilterMojo.java new file mode 100644 index 0000000000..84ba4ac26c --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractDependencyFilterMojo.java @@ -0,0 +1,172 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactFeatureFilter; +import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; +import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +/** + * A base mojo filtering the dependencies of the project. + * + * @author Stephane Nicoll + * @author David Turanski + */ +public abstract class AbstractDependencyFilterMojo extends AbstractMojo { + + /** + * The Maven project. + */ + @Parameter(defaultValue = "${project}", readonly = true, required = true) + protected MavenProject project; + + /** + * Collection of artifact definitions to include. The {@link Include} element defines + * mandatory {@code groupId} and {@code artifactId} properties and an optional + * mandatory {@code groupId} and {@code artifactId} properties and an optional + * {@code classifier} property. + */ + @Parameter(property = "dubbo.includes") + private List includes; + + /** + * Collection of artifact definitions to exclude. The {@link Exclude} element defines + * mandatory {@code groupId} and {@code artifactId} properties and an optional + * {@code classifier} property. + */ + @Parameter(property = "dubbo.excludes") + private List excludes; + + /** + * Comma separated list of groupId names to exclude (exact match). + */ + @Parameter(property = "dubbo.excludeGroupIds", defaultValue = "") + private String excludeGroupIds; + + protected void setExcludes(List excludes) { + this.excludes = excludes; + } + + protected void setIncludes(List includes) { + this.includes = includes; + } + + protected void setExcludeGroupIds(String excludeGroupIds) { + this.excludeGroupIds = excludeGroupIds; + } + + protected List getDependencyURLs(ArtifactsFilter... additionalFilters) throws MojoExecutionException { + Set artifacts = filterDependencies(this.project.getArtifacts(), additionalFilters); + List urls = new ArrayList<>(); + for (Artifact artifact : artifacts) { + if (artifact.getFile() != null) { + urls.add(toURL(artifact.getFile())); + } + } + return urls; + } + + protected final Set filterDependencies(Set dependencies, ArtifactsFilter... additionalFilters) + throws MojoExecutionException { + try { + Set filtered = new LinkedHashSet<>(dependencies); + filtered.retainAll(getFilters(additionalFilters).filter(dependencies)); + return filtered; + } + catch (ArtifactFilterException ex) { + throw new MojoExecutionException(ex.getMessage(), ex); + } + } + + protected URL toURL(File file) { + try { + return file.toURI().toURL(); + } + catch (MalformedURLException ex) { + throw new IllegalStateException("Invalid URL for " + file, ex); + } + } + + /** + * Return artifact filters configured for this MOJO. + * @param additionalFilters optional additional filters to apply + * @return the filters + */ + private FilterArtifacts getFilters(ArtifactsFilter... additionalFilters) { + FilterArtifacts filters = new FilterArtifacts(); + for (ArtifactsFilter additionalFilter : additionalFilters) { + filters.addFilter(additionalFilter); + } + filters.addFilter(new MatchingGroupIdFilter(cleanFilterConfig(this.excludeGroupIds))); + if (this.includes != null && !this.includes.isEmpty()) { + filters.addFilter(new IncludeFilter(this.includes)); + } + if (this.excludes != null && !this.excludes.isEmpty()) { + filters.addFilter(new ExcludeFilter(this.excludes)); + } + return filters; + } + + private String cleanFilterConfig(String content) { + if (content == null || content.trim().isEmpty()) { + return ""; + } + StringBuilder cleaned = new StringBuilder(); + StringTokenizer tokenizer = new StringTokenizer(content, ","); + while (tokenizer.hasMoreElements()) { + cleaned.append(tokenizer.nextToken().trim()); + if (tokenizer.hasMoreElements()) { + cleaned.append(","); + } + } + return cleaned.toString(); + } + + /** + * {@link ArtifactFilter} to exclude test scope dependencies. + */ + protected static class ExcludeTestScopeArtifactFilter extends AbstractArtifactFeatureFilter { + + ExcludeTestScopeArtifactFilter() { + super("", Artifact.SCOPE_TEST); + } + + @Override + protected String getArtifactFeature(Artifact artifact) { + return artifact.getScope(); + } + + } + +} + diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/CommandLineBuilder.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/CommandLineBuilder.java new file mode 100644 index 0000000000..8c759d2d4e --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/CommandLineBuilder.java @@ -0,0 +1,136 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Helper class to build the command-line arguments of a java process. + * + * @author Stephane Nicoll + */ +final class CommandLineBuilder { + + private final List options = new ArrayList<>(); + + private final List classpathElements = new ArrayList<>(); + + private final String mainClass; + + private final List arguments = new ArrayList<>(); + + private CommandLineBuilder(String mainClass) { + this.mainClass = mainClass; + } + + static CommandLineBuilder forMainClass(String mainClass) { + return new CommandLineBuilder(mainClass); + } + + CommandLineBuilder withJvmArguments(String... jvmArguments) { + if (jvmArguments != null) { + this.options.addAll(Arrays.stream(jvmArguments).filter(Objects::nonNull).collect(Collectors.toList())); + } + return this; + } + + CommandLineBuilder withSystemProperties(Map systemProperties) { + if (systemProperties != null) { + systemProperties.entrySet().stream().map((e) -> SystemPropertyFormatter.format(e.getKey(), e.getValue())) + .forEach(this.options::add); + } + return this; + } + + CommandLineBuilder withClasspath(URL... elements) { + this.classpathElements.addAll(Arrays.asList(elements)); + return this; + } + + CommandLineBuilder withArguments(String... arguments) { + if (arguments != null) { + this.arguments.addAll(Arrays.stream(arguments).filter(Objects::nonNull).collect(Collectors.toList())); + } + return this; + } + + List build() { + List commandLine = new ArrayList<>(); + if (!this.options.isEmpty()) { + commandLine.addAll(this.options); + } + if (!this.classpathElements.isEmpty()) { + commandLine.add("-cp"); + commandLine.add(ClasspathBuilder.build(this.classpathElements)); + } + commandLine.add(this.mainClass); + if (!this.arguments.isEmpty()) { + commandLine.addAll(this.arguments); + } + return commandLine; + } + + static class ClasspathBuilder { + + static String build(List classpathElements) { + StringBuilder classpath = new StringBuilder(); + for (URL element : classpathElements) { + if (classpath.length() > 0) { + classpath.append(File.pathSeparator); + } + classpath.append(toFile(element)); + } + return classpath.toString(); + } + + private static File toFile(URL element) { + try { + return new File(element.toURI()); + } + catch (URISyntaxException ex) { + throw new IllegalArgumentException(ex); + } + } + + } + + /** + * Format System properties. + */ + private static class SystemPropertyFormatter { + + static String format(String key, String value) { + if (key == null) { + return ""; + } + if (value == null || value.isEmpty()) { + return String.format("-D%s", key); + } + return String.format("-D%s=\"%s\"", key, value); + } + + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DependencyFilter.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DependencyFilter.java new file mode 100644 index 0000000000..54ea0a7147 --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DependencyFilter.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactsFilter; +import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Base class for {@link ArtifactsFilter} based on a {@link org.apache.dubbo.maven.plugin.aot.FilterableDependency} list. + * + * @author Stephane Nicoll + * @author David Turanski + */ +public abstract class DependencyFilter extends AbstractArtifactsFilter { + + private final List filters; + + /** + * Create a new instance with the list of {@link FilterableDependency} instance(s) to + * use. + * @param dependencies the source dependencies + */ + public DependencyFilter(List dependencies) { + this.filters = dependencies; + } + + @Override + public Set filter(Set artifacts) throws ArtifactFilterException { + Set result = new HashSet<>(); + for (Artifact artifact : artifacts) { + if (!filter(artifact)) { + result.add(artifact); + } + } + return result; + } + + protected abstract boolean filter(Artifact artifact); + + /** + * Check if the specified {@link Artifact} matches the + * specified {@link org.apache.dubbo.maven.plugin.aot.FilterableDependency}. Returns + * {@code true} if it should be excluded + * @param artifact the Maven {@link Artifact} + * @param dependency the {@link org.apache.dubbo.maven.plugin.aot.FilterableDependency} + * @return {@code true} if the artifact matches the dependency + */ + protected final boolean equals(Artifact artifact, FilterableDependency dependency) { + if (!dependency.getGroupId().equals(artifact.getGroupId())) { + return false; + } + if (!dependency.getArtifactId().equals(artifact.getArtifactId())) { + return false; + } + return (dependency.getClassifier() == null + || artifact.getClassifier() != null && dependency.getClassifier().equals(artifact.getClassifier())); + } + + protected final List getFilters() { + return this.filters; + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java new file mode 100644 index 0000000000..5b4f26b8b4 --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java @@ -0,0 +1,138 @@ +/* + * 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.maven.plugin.aot; + + +import org.apache.commons.io.FileUtils; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Mojo(name = "dubbo-process-aot", defaultPhase = LifecyclePhase.PREPARE_PACKAGE, threadSafe = true, + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, + requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME) +public class DubboProcessAotMojo extends AbstractAotMojo { + + private static final String AOT_PROCESSOR_CLASS_NAME = "org.apache.dubbo.aot.generate.CodeGenerator"; + + /** + * Directory containing the classes and resource files that should be packaged into + * the archive. + */ + @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) + private File classesDirectory; + + /** + * Directory containing the generated sources. + */ + @Parameter(defaultValue = "${project.build.directory}/dubbo-aot/main/sources", required = true) + private File generatedSources; + + /** + * Directory containing the generated resources. + */ + @Parameter(defaultValue = "${project.build.directory}/dubbo-aot/main/resources", required = true) + private File generatedResources; + + /** + * Directory containing the generated classes. + */ + @Parameter(defaultValue = "${project.build.directory}/dubbo-aot/main/classes", required = true) + private File generatedClasses; + + /** + * Name of the main class to use as the source for the AOT process. If not specified + * the first compiled class found that contains a 'main' method will be used. + */ + @Parameter(property = "dubbo.aot.main-class") + private String mainClass; + + + /** + * Application arguments that should be taken into account for AOT processing. + */ + @Parameter + private String[] arguments; + + + @Override + protected void executeAot() throws Exception { + URL[] classPath = getClassPath().toArray(new URL[0]); + generateAotAssets(classPath, AOT_PROCESSOR_CLASS_NAME, getAotArguments(mainClass)); + compileSourceFiles(classPath, this.generatedSources, this.classesDirectory); + copyNativeConfigFile(project); + copyAll(this.generatedResources.toPath(), this.classesDirectory.toPath()); + copyAll(this.generatedClasses.toPath(), this.classesDirectory.toPath()); + } + + private String[] getAotArguments(String applicationClass) { + List aotArguments = new ArrayList<>(); + aotArguments.add(applicationClass); + aotArguments.add(this.generatedSources.toString()); + aotArguments.add(this.generatedResources.toString()); + aotArguments.add(this.generatedClasses.toString()); + aotArguments.add(this.project.getGroupId()); + aotArguments.add(this.project.getArtifactId()); + aotArguments.addAll(new RunArguments(this.arguments).getArgs()); + return aotArguments.toArray(new String[0]); + } + + private List getClassPath() throws Exception { + File[] directories = new File[]{this.classesDirectory, this.generatedClasses}; + return getClassPath(directories, new ExcludeTestScopeArtifactFilter()); + } + + private void copyNativeConfigFile(MavenProject project) { + String[] nativeFiles = {"META-INF/native-image/reflect-config.json", + "META-INF/native-image/jni-config.json", + "META-INF/native-image/proxy-config.json", + "META-INF/native-image/resource-config.json", + "META-INF/native-image/serialization-config.json"}; + + Arrays.stream(nativeFiles).forEach(nativeFile -> { + InputStream is = this.getClass().getClassLoader().getResourceAsStream(nativeFile); + project.getResources().stream().findFirst().ifPresent(resource -> { + try { + String path = generatedResources + File.separator + "META-INF" + File.separator + "native-image" + File.separator + + File.separator + this.project.getGroupId() + File.separator + this.project.getArtifactId(); + FileUtils.forceMkdir(new File(path)); + String[] str = nativeFile.split("/"); + File file = new File(path + File.separator + str[str.length - 1]); + if (!file.exists()) { + FileUtils.copyInputStreamToFile(is, file); + getLog().info("Copy native config file:" + file); + } else { + getLog().info("Skip copy config file:" + file); + } + } catch (Throwable ex) { + getLog().error("Copy native config file error:" + ex.getMessage()); + } + }); + }); + } + + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Exclude.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Exclude.java new file mode 100644 index 0000000000..ce1910577d --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Exclude.java @@ -0,0 +1,26 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +/** + * A model for a dependency to exclude. + * + * @author Stephane Nicoll + */ +public class Exclude extends FilterableDependency { + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/ExcludeFilter.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/ExcludeFilter.java new file mode 100644 index 0000000000..841c9a303b --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/ExcludeFilter.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.artifact.Artifact; + +import java.util.Arrays; +import java.util.List; + +/** + * An {DependencyFilter} that filters out any artifact matching an {@link Exclude}. + * + * @author Stephane Nicoll + * @author David Turanski + */ +public class ExcludeFilter extends DependencyFilter { + + public ExcludeFilter(Exclude... excludes) { + this(Arrays.asList(excludes)); + } + + public ExcludeFilter(List excludes) { + super(excludes); + } + + @Override + protected boolean filter(Artifact artifact) { + for (FilterableDependency dependency : getFilters()) { + if (equals(artifact, dependency)) { + return true; + } + } + return false; + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/FilterableDependency.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/FilterableDependency.java new file mode 100644 index 0000000000..58521297d8 --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/FilterableDependency.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.plugins.annotations.Parameter; + +/** + * A model for a dependency to include or exclude. + * + * @author Stephane Nicoll + * @author David Turanski + */ +abstract class FilterableDependency { + + /** + * The groupId of the artifact to exclude. + */ + @Parameter(required = true) + private String groupId; + + /** + * The artifactId of the artifact to exclude. + */ + @Parameter(required = true) + private String artifactId; + + /** + * The classifier of the artifact to exclude. + */ + @Parameter + private String classifier; + + String getGroupId() { + return this.groupId; + } + + void setGroupId(String groupId) { + this.groupId = groupId; + } + + String getArtifactId() { + return this.artifactId; + } + + void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + String getClassifier() { + return this.classifier; + } + + void setClassifier(String classifier) { + this.classifier = classifier; + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Include.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Include.java new file mode 100644 index 0000000000..1e27fc97e8 --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Include.java @@ -0,0 +1,26 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +/** + * A model for a dependency to include. + * + * @author David Turanski + */ +public class Include extends FilterableDependency { + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/IncludeFilter.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/IncludeFilter.java new file mode 100644 index 0000000000..e2fd85014f --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/IncludeFilter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; + +import java.util.List; + +/** + * An {@link ArtifactsFilter} that filters out any artifact not matching an + * {@link Include}. + * + * @author David Turanski + */ +public class IncludeFilter extends DependencyFilter { + + public IncludeFilter(List includes) { + super(includes); + } + + @Override + protected boolean filter(Artifact artifact) { + for (FilterableDependency dependency : getFilters()) { + if (equals(artifact, dependency)) { + return false; + } + } + return true; + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaCompilerPluginConfiguration.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaCompilerPluginConfiguration.java new file mode 100644 index 0000000000..5f842ff853 --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaCompilerPluginConfiguration.java @@ -0,0 +1,107 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.model.Plugin; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +import java.util.Arrays; + +/** + * Provides access to the Maven Java Compiler plugin configuration. + * + * @author Scott Frederick + */ +class JavaCompilerPluginConfiguration { + + private final MavenProject project; + + JavaCompilerPluginConfiguration(MavenProject project) { + this.project = project; + } + + String getSourceMajorVersion() { + String version = getConfigurationValue("source"); + + if (version == null) { + version = getPropertyValue("maven.compiler.source"); + } + + return majorVersionFor(version); + } + + String getTargetMajorVersion() { + String version = getConfigurationValue("target"); + + if (version == null) { + version = getPropertyValue("maven.compiler.target"); + } + + return majorVersionFor(version); + } + + String getReleaseVersion() { + String version = getConfigurationValue("release"); + + if (version == null) { + version = getPropertyValue("maven.compiler.release"); + } + + return majorVersionFor(version); + } + + private String getConfigurationValue(String propertyName) { + Plugin plugin = this.project.getPlugin("org.apache.maven.plugins:maven-compiler-plugin"); + if (plugin != null) { + Object pluginConfiguration = plugin.getConfiguration(); + if (pluginConfiguration instanceof Xpp3Dom) { + return getNodeValue((Xpp3Dom)pluginConfiguration, propertyName); + } + } + return null; + } + + private String getPropertyValue(String propertyName) { + if (this.project.getProperties().containsKey(propertyName)) { + return this.project.getProperties().get(propertyName).toString(); + } + return null; + } + + private String getNodeValue(Xpp3Dom dom, String... childNames) { + Xpp3Dom childNode = dom.getChild(childNames[0]); + + if (childNode == null) { + return null; + } + + if (childNames.length > 1) { + return getNodeValue(childNode, Arrays.copyOfRange(childNames, 1, childNames.length)); + } + + return childNode.getValue(); + } + + private String majorVersionFor(String version) { + if (version != null && version.startsWith("1.")) { + return version.substring("1.".length()); + } + return version; + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaExecutable.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaExecutable.java new file mode 100644 index 0000000000..d8bafe2e04 --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaExecutable.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + + +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.common.utils.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +/** + * Provides access to the java binary executable, regardless of OS. + * + * @author Phillip Webb + */ +public class JavaExecutable { + + private final File file; + + public JavaExecutable() { + String javaHome = System.getProperty("java.home"); + Assert.assertTrue(StringUtils.isNotEmpty(javaHome), "Unable to find java executable due to missing 'java.home'"); + this.file = findInJavaHome(javaHome); + } + + private File findInJavaHome(String javaHome) { + File bin = new File(new File(javaHome), "bin"); + File command = new File(bin, "java.exe"); + command = command.exists() ? command : new File(bin, "java"); + Assert.assertTrue(command.exists(), () -> "Unable to find java in " + javaHome); + return command; + } + + /** + * Create a new {@link ProcessBuilder} that will run with the Java executable. + * @param arguments the command arguments + * @return a {@link ProcessBuilder} + */ + public ProcessBuilder processBuilder(String... arguments) { + ProcessBuilder processBuilder = new ProcessBuilder(toString()); + processBuilder.command().addAll(Arrays.asList(arguments)); + return processBuilder; + } + + @Override + public String toString() { + try { + return this.file.getCanonicalPath(); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaProcessExecutor.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaProcessExecutor.java new file mode 100644 index 0000000000..7dda3cd3df --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaProcessExecutor.java @@ -0,0 +1,102 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.toolchain.Toolchain; +import org.apache.maven.toolchain.ToolchainManager; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +/** + * Ease the execution of a Java process using Maven's toolchain support. + * + * @author Stephane Nicoll + */ +class JavaProcessExecutor { + + private static final int EXIT_CODE_SIGINT = 130; + + private final MavenSession mavenSession; + + private final ToolchainManager toolchainManager; + + private final Consumer runProcessCustomizer; + + JavaProcessExecutor(MavenSession mavenSession, ToolchainManager toolchainManager) { + this(mavenSession, toolchainManager, null); + } + + private JavaProcessExecutor(MavenSession mavenSession, ToolchainManager toolchainManager, + Consumer runProcessCustomizer) { + this.mavenSession = mavenSession; + this.toolchainManager = toolchainManager; + this.runProcessCustomizer = runProcessCustomizer; + } + + JavaProcessExecutor withRunProcessCustomizer(Consumer customizer) { + Consumer combinedCustomizer = (this.runProcessCustomizer != null) + ? this.runProcessCustomizer.andThen(customizer) : customizer; + return new JavaProcessExecutor(this.mavenSession, this.toolchainManager, combinedCustomizer); + } + + int run(File workingDirectory, List args, Map environmentVariables) + throws MojoExecutionException { + RunProcess runProcess = new RunProcess(workingDirectory, getJavaExecutable()); + if (this.runProcessCustomizer != null) { + this.runProcessCustomizer.accept(runProcess); + } + try { + int exitCode = runProcess.run(true, args, environmentVariables); + if (!hasTerminatedSuccessfully(exitCode)) { + throw new MojoExecutionException("Process terminated with exit code: " + exitCode); + } + return exitCode; + } + catch (IOException ex) { + throw new MojoExecutionException("Process execution failed", ex); + } + } + + RunProcess runAsync(File workingDirectory, List args, Map environmentVariables) + throws MojoExecutionException { + try { + RunProcess runProcess = new RunProcess(workingDirectory, getJavaExecutable()); + runProcess.run(false, args, environmentVariables); + return runProcess; + } + catch (IOException ex) { + throw new MojoExecutionException("Process execution failed", ex); + } + } + + private boolean hasTerminatedSuccessfully(int exitCode) { + return (exitCode == 0 || exitCode == EXIT_CODE_SIGINT); + } + + private String getJavaExecutable() { + Toolchain toolchain = this.toolchainManager.getToolchainFromBuildContext("jdk", this.mavenSession); + String javaExecutable = (toolchain != null) ? toolchain.findTool("java") : null; + return (javaExecutable != null) ? javaExecutable : new JavaExecutable().toString(); + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java new file mode 100644 index 0000000000..9254c9271b --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactFeatureFilter; + +/** + * An {@link org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter + * ArtifactsFilter} that filters by matching groupId. + * + * Preferred over the + * {@link org.apache.maven.shared.artifact.filter.collection.GroupIdFilter} due to that + * classes use of {@link String#startsWith} to match on prefix. + * + * @author Mark Ingram + */ +public class MatchingGroupIdFilter extends AbstractArtifactFeatureFilter { + + /** + * Create a new instance with the CSV groupId values that should be excluded. + * @param exclude the group values to exclude + */ + public MatchingGroupIdFilter(String exclude) { + super("", exclude); + } + + @Override + protected String getArtifactFeature(Artifact artifact) { + return artifact.getGroupId(); + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java new file mode 100644 index 0000000000..224620533d --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import org.codehaus.plexus.util.cli.CommandLineUtils; + +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; +import java.util.Objects; + +/** + * Parse and expose arguments specified in a single string. + * + * @author Stephane Nicoll + */ +class RunArguments { + + private static final String[] NO_ARGS = {}; + + private final Deque args = new LinkedList<>(); + + RunArguments(String arguments) { + this(parseArgs(arguments)); + } + + RunArguments(String[] args) { + if (args != null) { + Arrays.stream(args).filter(Objects::nonNull).forEach(this.args::add); + } + } + + Deque getArgs() { + return this.args; + } + + String[] asArray() { + return this.args.toArray(new String[0]); + } + + private static String[] parseArgs(String arguments) { + if (arguments == null || arguments.trim().isEmpty()) { + return NO_ARGS; + } + try { + arguments = arguments.replace('\n', ' ').replace('\t', ' '); + return CommandLineUtils.translateCommandline(arguments); + } + catch (Exception ex) { + throw new IllegalArgumentException("Failed to parse arguments [" + arguments + "]", ex); + } + } + +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java new file mode 100644 index 0000000000..621d4dbc5b --- /dev/null +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java @@ -0,0 +1,169 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.maven.plugin.aot; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * Utility used to run a process. + * + * @author Phillip Webb + * @author Dave Syer + * @author Andy Wilkinson + * @author Stephane Nicoll + * @author Dmytro Nosan + */ +public class RunProcess { + + private static final long JUST_ENDED_LIMIT = 500; + + private final File workingDirectory; + + private final String[] command; + + private volatile Process process; + + private volatile long endTime; + + /** + * Creates new {@link RunProcess} instance for the specified command. + * @param command the program to execute and its arguments + */ + public RunProcess(String... command) { + this(null, command); + } + + /** + * Creates new {@link RunProcess} instance for the specified working directory and + * command. + * @param workingDirectory the working directory of the child process or {@code null} + * to run in the working directory of the current Java process + * @param command the program to execute and its arguments + */ + public RunProcess(File workingDirectory, String... command) { + this.workingDirectory = workingDirectory; + this.command = command; + } + + public int run(boolean waitForProcess, String... args) throws IOException { + return run(waitForProcess, Arrays.asList(args), Collections.emptyMap()); + } + + public int run(boolean waitForProcess, Collection args, Map environmentVariables) + throws IOException { + ProcessBuilder builder = new ProcessBuilder(this.command); + builder.directory(this.workingDirectory); + builder.command().addAll(args); + builder.environment().putAll(environmentVariables); + builder.redirectErrorStream(true); + builder.inheritIO(); + try { + Process process = builder.start(); + this.process = process; + if (waitForProcess) { + try { + return process.waitFor(); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + return 1; + } + } + return 5; + } + finally { + if (waitForProcess) { + this.endTime = System.currentTimeMillis(); + this.process = null; + } + } + } + + /** + * Return the running process. + * @return the process or {@code null} + */ + public Process getRunningProcess() { + return this.process; + } + + /** + * Return if the process was stopped. + * @return {@code true} if stopped + */ + public boolean handleSigInt() { + if (allowChildToHandleSigInt()) { + return true; + } + return doKill(); + } + + private boolean allowChildToHandleSigInt() { + Process process = this.process; + if (process == null) { + return true; + } + long end = System.currentTimeMillis() + 5000; + while (System.currentTimeMillis() < end) { + if (!process.isAlive()) { + return true; + } + try { + Thread.sleep(500); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + return false; + } + } + return false; + } + + /** + * Kill this process. + */ + public void kill() { + doKill(); + } + + private boolean doKill() { + // destroy the running process + Process process = this.process; + if (process != null) { + try { + process.destroy(); + process.waitFor(); + this.process = null; + return true; + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + return false; + } + + public boolean hasJustEnded() { + return System.currentTimeMillis() < (this.endTime + JUST_ENDED_LIMIT); + } + +} diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json new file mode 100644 index 0000000000..0d4f101c7a --- /dev/null +++ b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json @@ -0,0 +1,2 @@ +[ +] diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json new file mode 100644 index 0000000000..41b42e677b --- /dev/null +++ b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json @@ -0,0 +1,3 @@ +[ + +] diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 0000000000..64b4fd5431 --- /dev/null +++ b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,2925 @@ +[ + { + "name": "boolean", + "allPublicMethods": true + }, + { + "name": "com.intellij.rt.execution.application.AppMainV2$Agent", + "methods": [ + { + "name": "premain", + "parameterTypes": [ + "java.lang.String", + "java.lang.instrument.Instrumentation" + ] + } + ] + }, + { + "name": "io.netty.bootstrap.ServerBootstrap$1" + }, + { + "name": "io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor", + "methods": [ + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + } + ] + }, + { + "name": "io.netty.buffer.AbstractByteBufAllocator", + "allDeclaredMethods": true + }, + { + "name": "io.netty.buffer.AbstractReferenceCountedByteBuf", + "fields": [ + { + "name": "refCnt", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "io.netty.channel.ChannelDuplexHandler", + "methods": [ + { + "name": "bind", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.net.SocketAddress", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "close", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "connect", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.net.SocketAddress", + "java.net.SocketAddress", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "deregister", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "disconnect", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "flush", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "read", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + } + ] + }, + { + "name": "io.netty.channel.ChannelHandlerAdapter", + "methods": [ + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + } + ] + }, + { + "name": "io.netty.channel.ChannelInboundHandlerAdapter", + "methods": [ + { + "name": "channelActive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelInactive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "channelReadComplete", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRegistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelUnregistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelWritabilityChanged", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + }, + { + "name": "userEventTriggered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + } + ] + }, + { + "name": "io.netty.channel.ChannelInitializer", + "methods": [ + { + "name": "channelRegistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + } + ] + }, + { + "name": "io.netty.channel.ChannelOutboundHandlerAdapter", + "methods": [ + { + "name": "bind", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.net.SocketAddress", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "close", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "connect", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.net.SocketAddress", + "java.net.SocketAddress", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "deregister", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "disconnect", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "flush", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "read", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + } + ] + }, + { + "name": "io.netty.channel.DefaultChannelPipeline$HeadContext", + "methods": [ + { + "name": "bind", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.net.SocketAddress", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "channelActive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelInactive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "channelReadComplete", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRegistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelUnregistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelWritabilityChanged", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "close", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "connect", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.net.SocketAddress", + "java.net.SocketAddress", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "deregister", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "disconnect", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "io.netty.channel.ChannelPromise" + ] + }, + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + }, + { + "name": "flush", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "read", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "userEventTriggered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "write", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object", + "io.netty.channel.ChannelPromise" + ] + } + ] + }, + { + "name": "io.netty.channel.DefaultChannelPipeline$TailContext", + "methods": [ + { + "name": "channelActive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelInactive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "channelReadComplete", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRegistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelUnregistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelWritabilityChanged", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + }, + { + "name": "userEventTriggered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + } + ] + }, + { + "name": "io.netty.channel.socket.nio.NioServerSocketChannel", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "io.netty.channel.socket.nio.NioSocketChannel", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "io.netty.handler.codec.ByteToMessageDecoder", + "methods": [ + { + "name": "channelInactive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "channelReadComplete", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "userEventTriggered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + } + ] + }, + { + "name": "io.netty.handler.codec.MessageToByteEncoder", + "methods": [ + { + "name": "write", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object", + "io.netty.channel.ChannelPromise" + ] + } + ] + }, + { + "name": "io.netty.handler.timeout.IdleStateHandler", + "methods": [ + { + "name": "channelActive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelInactive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "channelReadComplete", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRegistered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "write", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object", + "io.netty.channel.ChannelPromise" + ] + } + ] + }, + { + "name": "io.netty.util.ReferenceCountUtil", + "allDeclaredMethods": true + }, + { + "name": "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields", + "fields": [ + { + "name": "producerLimit", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields", + "fields": [ + { + "name": "consumerIndex", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields", + "fields": [ + { + "name": "producerIndex", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField", + "fields": [ + { + "name": "consumerIndex", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField", + "fields": [ + { + "name": "producerIndex", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField", + "fields": [ + { + "name": "producerLimit", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "java.io.File", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.io.Serializable", + "allDeclaredMethods": true + }, + { + "name": "java.lang.Cloneable", + "allDeclaredMethods": true + }, + { + "name": "java.lang.Comparable", + "allDeclaredMethods": true + }, + { + "name": "java.lang.Enum", + "allDeclaredFields": true, + "allDeclaredMethods": true + }, + { + "name": "java.lang.Integer", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "java.lang.Number", + "allDeclaredFields": true, + "allDeclaredMethods": true + }, + { + "name": "java.lang.Object", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allPublicMethods": true + }, + { + "name": "java.lang.StackTraceElement", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "java.lang.String" + }, + { + "name": "java.lang.String[]" + }, + { + "name": "java.lang.Thread", + "methods": [ + { + "name": "getContextClassLoader", + "parameterTypes": [] + } + ] + }, + { + "name": "java.lang.Throwable", + "fields": [ + { + "name": "detailMessage" + }, + { + "name": "stackTrace" + } + ] + }, + { + "name": "java.lang.management.ManagementFactory", + "methods": [ + { + "name": "getRuntimeMXBean", + "parameterTypes": [] + } + ] + }, + { + "name": "java.lang.management.RuntimeMXBean", + "methods": [ + { + "name": "getName", + "parameterTypes": [] + } + ] + }, + { + "name": "java.math.BigDecimal", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.math.BigInteger", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "java.net.URL", + "fields": [ + { + "name": "ref" + } + ] + }, + { + "name": "java.nio.Bits", + "methods": [ + { + "name": "unaligned", + "parameterTypes": [] + } + ] + }, + { + "name": "java.nio.Buffer", + "fields": [ + { + "name": "address", + "allowUnsafeAccess": true + } + ] + }, + { + "name": "java.nio.DirectByteBuffer", + "fields": [ + { + "name": "cleaner", + "allowUnsafeAccess": true + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "long", + "int" + ] + } + ] + }, + { + "name": "java.security.MessageDigestSpi" + }, + { + "name": "java.sql.Date", + "methods": [ + { + "name": "", + "parameterTypes": [ + "long" + ] + } + ] + }, + { + "name": "java.sql.Time", + "methods": [ + { + "name": "", + "parameterTypes": [ + "long" + ] + } + ] + }, + { + "name": "java.sql.Timestamp", + "methods": [ + { + "name": "", + "parameterTypes": [ + "long" + ] + } + ] + }, + { + "name": "java.time.Duration" + }, + { + "name": "java.time.Instant" + }, + { + "name": "java.time.LocalDate" + }, + { + "name": "java.time.LocalDateTime" + }, + { + "name": "java.time.LocalTime" + }, + { + "name": "java.time.MonthDay" + }, + { + "name": "java.time.OffsetDateTime" + }, + { + "name": "java.time.OffsetTime" + }, + { + "name": "java.time.Period" + }, + { + "name": "java.time.Year" + }, + { + "name": "java.time.YearMonth" + }, + { + "name": "java.time.ZoneId" + }, + { + "name": "java.time.ZoneOffset" + }, + { + "name": "java.time.ZonedDateTime" + }, + { + "name": "java.util.AbstractMap", + "allDeclaredFields": true, + "allDeclaredMethods": true + }, + { + "name": "java.util.ArrayList", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "java.util.BitSet", + "allDeclaredFields": true + }, + { + "name": "java.util.HashMap", + "allDeclaredMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "java.util.LinkedHashMap", + "allPublicConstructors": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "java.util.Map", + "allDeclaredMethods": true + }, + { + "name": "java.util.NavigableMap", + "allDeclaredMethods": true + }, + { + "name": "java.util.SortedMap", + "allDeclaredMethods": true + }, + { + "name": "java.util.TreeMap", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "java.util.Map", + "allPublicConstructors": true + }, + { + "name": "java.util.concurrent.ConcurrentNavigableMap" + }, + { + "name": "java.util.concurrent.ConcurrentSkipListMap" + }, + { + "name": "javax.management.ObjectName", + "methods": [ + { + "name": "", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "org.apace.dubbo.graalvm.demo.DemoService", + "allPublicMethods": true + }, + { + "name": "org.apache.curator.x.discovery.ServiceType", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "org.apache.curator.x.discovery.details.OldServiceInstance", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "org.apache.dubbo.common.CommonScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.serialize.hessian2.Hessian2ScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.serialize.fastjson2.Fastjson2ScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.URL", + "allDeclaredFields": true + }, + { + "name": "org.apache.dubbo.common.beans.ScopeBeanExtensionInjector", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.compiler.support.AdaptiveCompiler", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.compiler.support.JavassistCompiler", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.compiler.support.JdkCompiler", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.config.Environment", + "allPublicMethods": true, + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.common.config.ModuleEnvironment", + "allPublicMethods": true, + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigurationFactory" + }, + { + "name": "org.apache.dubbo.common.config.configcenter.nop.NopDynamicConfigurationFactory" + }, + { + "name": "org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.extension.inject.SpiExtensionInjector", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.infra.support.EnvironmentAdapter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.lang.ShutdownHookCallbacks", + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.common.logger.jcl.JclLoggerAdapter" + }, + { + "name": "org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter" + }, + { + "name": "org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter" + }, + { + "name": "org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.serialize.hessian2.Hessian2FactoryManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.FrameworkModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.serialize.fastjson2.FastJson2Serialization", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.serialize.fastjson2.Fastjson2CreatorManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.FrameworkModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.serialize.fastjson2.Fastjson2SecurityManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.FrameworkModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.utils.SerializeSecurityConfigurator", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ModuleModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.utils.SerializeSecurityManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.utils.DefaultSerializeClassChecker", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.FrameworkModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.utils.SerializeClassChecker", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.status.reporter.FrameworkStatusReportService", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.threadpool.ThreadPool", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.common.threadpool.ThreadPool$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.threadpool.manager.DefaultExecutorRepository", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ApplicationModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool" + }, + { + "name": "org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool" + }, + { + "name": "org.apache.dubbo.common.url.component.URLAddress", + "allDeclaredFields": true + }, + { + "name": "org.apache.dubbo.common.url.component.URLParam", + "allDeclaredFields": true + }, + { + "name": "org.apache.dubbo.common.url.component.param.DefaultDynamicParamSource", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.AbstractConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.AbstractInterfaceConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.AbstractMethodConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.AbstractReferenceConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.AbstractServiceConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.ApplicationConfig", + "allPublicMethods": true, + "fields": [ + { + "name": "monitor" + }, + { + "name": "registries" + } + ] + }, + { + "name": "org.apache.dubbo.config.ArgumentConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.ConfigCenterConfig", + "allPublicMethods": true, + "fields": [ + { + "name": "appExternalConfiguration" + }, + { + "name": "externalConfiguration" + } + ] + }, + { + "name": "org.apache.dubbo.config.ConfigScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.ConsumerConfig", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.MethodConfig", + "allPublicMethods": true, + "fields": [ + { + "name": "arguments" + } + ] + }, + { + "name": "org.apache.dubbo.config.ModuleConfig", + "allPublicMethods": true, + "fields": [ + { + "name": "monitor" + }, + { + "name": "registries" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.ProtocolConfig", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.ProviderConfig", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.ReferenceConfig", + "allPublicMethods": true, + "fields": [ + { + "name": "invoker" + } + ] + }, + { + "name": "org.apache.dubbo.config.ReferenceConfigBase", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.RegistryConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.ServiceConfig", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.ServiceConfigBase", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.config.SslConfig", + "allPublicMethods": true, + "fields": [ + { + "name": "clientKeyCertChainPathStream" + }, + { + "name": "clientPrivateKeyPathStream" + }, + { + "name": "clientTrustCertCollectionPathStream" + }, + { + "name": "serverKeyCertChainPathStream" + }, + { + "name": "serverPrivateKeyPathStream" + }, + { + "name": "serverTrustCertCollectionPathStream" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.context.ConfigManager", + "allPublicMethods": true, + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.config.deploy.DefaultApplicationDeployer", + "allPublicConstructors": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ApplicationModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.config.deploy.DefaultModuleDeployer", + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.metadata.ServiceInstanceHostPortCustomizer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.utils.DefaultConfigValidator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ApplicationModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.demo.graalvm.provider.DemoServiceImpl", + "methods": [ + { + "name": "sayHello", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.InstanceMetadataChangedListener", + "allDeclaredFields": true + }, + { + "name": "org.apache.dubbo.metadata.MetadataInfo", + "allDeclaredFields": true + }, + { + "name": "org.apache.dubbo.metadata.MetadataInfo$ServiceInfo", + "allDeclaredFields": true + }, + { + "name": "org.apache.dubbo.metadata.MetadataService", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.metadata.definition.builder.ArrayTypeBuilder", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.definition.builder.CollectionTypeBuilder", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.definition.builder.EnumTypeBuilder", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.definition.builder.MapTypeBuilder", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.definition.model.MethodDefinition", + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.definition.model.ServiceDefinition", + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.definition.model.TypeDefinition", + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.report.MetadataReportInstance", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ApplicationModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.metadata.report.MetadataScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.monitor.MetricsService", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.monitor.MonitorService", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.monitor.support.MetricsServiceDetector", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.monitor.support.MonitorFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.monitor.support.MonitorClusterFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.monitor.support.MonitorFilter" + }, + { + "name": "org.apache.dubbo.monitor.support.MonitorServiceDetector", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.RegistryFactory", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.registry.RegistryFactory$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.RegistryFactoryWrapper", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.registry.RegistryFactory" + ] + } + ] + }, + { + "name": "org.apache.dubbo.registry.RegistryScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.DefaultRegistryClusterIdentifier", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.DefaultServiceInstance$Endpoint", + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.ServiceDiscoveryRegistryFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.metadata.MetadataServiceNameMapping", + "allPublicMethods": true, + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.registry.client.metadata.MetadataServiceURLParamsMetadataCustomizer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.metadata.ProtocolPortsMetadataCustomizer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataCustomizer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.migration.DefaultMigrationAddressComparator", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.client.migration.MigrationRuleListener", + "allPublicMethods": true, + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.integration.RegistryProtocol", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.multicast.MulticastRegistryFactory" + }, + { + "name": "org.apache.dubbo.registry.multicast.MulticastServiceDiscoveryFactory" + }, + { + "name": "org.apache.dubbo.registry.support.DefaultProviderFirstParams", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.support.RegistryManager", + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.registry.zookeeper.ZookeeperInstance", + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "org.apache.dubbo.registry.zookeeper.ZookeeperRegistryFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscoveryFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.Dispatcher", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.remoting.Dispatcher$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.Transporter", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.remoting.Transporter$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.exchange.codec.ExchangeCodec" + }, + { + "name": "org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.telnet.codec.TelnetCodec" + }, + { + "name": "org.apache.dubbo.remoting.transport.codec.TransportCodec" + }, + { + "name": "org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher" + }, + { + "name": "org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher" + }, + { + "name": "org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher" + }, + { + "name": "org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher" + }, + { + "name": "org.apache.dubbo.remoting.transport.netty4.NettyClient$1" + }, + { + "name": "org.apache.dubbo.remoting.transport.netty4.NettyClientHandler", + "methods": [ + { + "name": "channelActive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelInactive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + }, + { + "name": "userEventTriggered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "write", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object", + "io.netty.channel.ChannelPromise" + ] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalDecoder" + }, + { + "name": "org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder" + }, + { + "name": "org.apache.dubbo.remoting.transport.netty4.NettyServer$1" + }, + { + "name": "org.apache.dubbo.remoting.transport.netty4.NettyServerHandler", + "methods": [ + { + "name": "channelActive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelInactive", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext" + ] + }, + { + "name": "channelRead", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "exceptionCaught", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Throwable" + ] + }, + { + "name": "userEventTriggered", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object" + ] + }, + { + "name": "write", + "parameterTypes": [ + "io.netty.channel.ChannelHandlerContext", + "java.lang.Object", + "io.netty.channel.ChannelPromise" + ] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.transport.netty4.NettyTransporter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.remoting.zookeeper.curator5.Curator5ZookeeperTransporter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.Invoker", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.Protocol", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.Protocol$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.ProxyFactory", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.ProxyFactory$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.Cluster", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.cluster.Cluster$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.ClusterScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.ConfiguratorFactory", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.cluster.ConfiguratorFactory$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.Directory", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.cluster.RouterFactory", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.cluster.RouterFactory$Adaptive", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.configurator.absent.AbsentConfiguratorFactory" + }, + { + "name": "org.apache.dubbo.rpc.cluster.configurator.override.OverrideConfiguratorFactory" + }, + { + "name": "org.apache.dubbo.rpc.cluster.filter.DefaultFilterChainBuilder", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.Protocol" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter", + "allPublicMethods": true, + "allPublicConstructors": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ApplicationModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.filter.support.ZoneAwareFilter" + }, + { + "name": "org.apache.dubbo.rpc.cluster.governance.DefaultGovernanceRuleRepositoryImpl", + "allPublicMethods": true, + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance" + }, + { + "name": "org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance" + }, + { + "name": "org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance" + }, + { + "name": "org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance" + }, + { + "name": "org.apache.dubbo.rpc.cluster.merger.MergerFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.ClusterUtils", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.AccessLogFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.ClassLoaderFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.CompatibleFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.ContextFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ApplicationModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.DeprecatedFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.EchoFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.ExceptionFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.ExecuteLimitFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.GenericFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.GenericImplFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ModuleModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.TimeoutFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory" + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.file.FileStateRouterFactory" + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleAddressListenerInterceptor", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.mesh.route.StandardMeshRuleRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.mock.MockStateRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.tag.TagDynamicStateRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.tag.TagStaticStateRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.AvailableCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.BroadcastCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.ClusterUtils", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.FailbackCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.FailfastCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.FailoverCluster", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.FailsafeCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.ForkingCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.MergeableCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.merger.DefaultProviderURLMergeProcessor", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster" + }, + { + "name": "org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.cluster.Cluster" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.filter.AccessLogFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.ClassLoaderFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.CompatibleFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.DeprecatedFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.EchoFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.ExceptionFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.ExecuteLimitFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.GenericFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.TimeoutFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.TokenFilter" + }, + { + "name": "org.apache.dubbo.rpc.filter.TpsLimitFilter" + }, + { + "name": "org.apache.dubbo.rpc.listener.DeprecatedInvokerListener" + }, + { + "name": "org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.Protocol" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.Protocol" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec", + "allPublicMethods": true, + "allPublicConstructors": true + }, + { + "name": "org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.FrameworkModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.AdaptiveMetrics", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter" + }, + { + "name": "org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory" + }, + { + "name": "org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.proxy.wrapper.StubProxyFactoryWrapper", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.ProxyFactory" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.service.Destroyable", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.service.EchoService", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.service.EchoServiceDetector", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.service.GenericService", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.rpc.service.GenericServiceDetector", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.support.MockProtocol" + }, + { + "name": "org.apache.log4j.Appender" + }, + { + "name": "org.apache.log4j.Category" + }, + { + "name": "org.apache.log4j.CategoryKey" + }, + { + "name": "org.apache.log4j.ConsoleAppender", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.log4j.Layout", + "allPublicMethods": true + }, + { + "name": "org.apache.log4j.Logger" + }, + { + "name": "org.apache.log4j.PatternLayout", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.logging.log4j.Level", + "allPublicMethods": true + }, + { + "name": "org.apache.log4j.helpers.Loader" + }, + { + "name": "org.apache.log4j.spi.OptionHandler" + }, + { + "name": "org.apache.zookeeper.ClientCnxnSocketNIO", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.zookeeper.client.ZKClientConfig" + ] + }, + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.misc.Cleaner", + "methods": [ + { + "name": "clean", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.misc.Unsafe", + "fields": [ + { + "name": "theUnsafe" + } + ], + "methods": [ + { + "name": "copyMemory", + "parameterTypes": [ + "java.lang.Object", + "long", + "java.lang.Object", + "long", + "long" + ] + }, + { + "name": "getAndAddLong", + "parameterTypes": [ + "java.lang.Object", + "long", + "long" + ] + }, + { + "name": "getAndSetObject", + "parameterTypes": [ + "java.lang.Object", + "long", + "java.lang.Object" + ] + } + ] + }, + { + "name": "sun.misc.VM", + "methods": [ + { + "name": "maxDirectMemory", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.nio.ch.SelectorImpl", + "fields": [ + { + "name": "publicSelectedKeys" + }, + { + "name": "selectedKeys" + } + ] + }, + { + "name": "sun.security.provider.ConfigFile", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.MD5", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.NativePRNG", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.SHA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.security.provider.Sun", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.convert.ConverterUtil", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.FrameworkModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ModuleModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.config.context.ModuleConfigManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ModuleModel" + ] + } + ] + }, + { + "name": "org.apache.dubbo.common.store.support.SimpleDataStore", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.metrics.collector.DefaultMetricsCollector", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.config.deploy.DefaultMetricsServiceExporter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.alibaba.fastjson.JSON", + "allPublicMethods": true + }, + { + "name": "java.util.Collections$UnmodifiableMap", + "allPublicMethods": true + }, + { + "name": "java.util.Collections$UnmodifiableCollection", + "allPublicMethods": true + } +] diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json new file mode 100644 index 0000000000..51f17b21af --- /dev/null +++ b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json @@ -0,0 +1,169 @@ +{ + "resources": { + "includes": [ + { + "pattern": "\\QDENY_CLASS\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.context.ApplicationExt\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.context.ModuleExt\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.infra.InfraAdapter\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.threadpool.manager.ExecutorRepository\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.url.component.param.DynamicParamSource\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.AddressListener\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.ProviderFirstParams\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.RegistryClusterIdentifier\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.migration.MigrationAddressComparator\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.integration.RegistryProtocolListener\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.Codec2\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.Dispatcher\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.exchange.Exchanger\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.Filter\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.InvokerListener\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.ProxyFactory\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.ConfiguratorFactory\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.LoadBalance\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.ProviderURLMergeProcessor\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.model.BuiltinServiceDetector\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer\\E" + }, + { + "pattern": "\\QMETA-INF/services/org.apache.dubbo.common.extension.LoadingStrategy\\E" + }, + { + "pattern": "\\Qdubbo.properties\\E" + }, + { + "pattern": "\\Qlog4j.properties\\E" + }, + { + "pattern": "\\Qorg/apache/dubbo/common/Version.class\\E" + }, + { + "pattern": "\\Qorg/apache/dubbo/remoting/RemotingException.class\\E" + }, + { + "pattern": "\\Qorg/apache/dubbo/remoting/Transporters.class\\E" + }, + { + "pattern": "\\Qorg/apache/dubbo/remoting/exchange/Exchangers.class\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metrics.service.MetricsServiceExporter\\E" + }, + { + "pattern": "\\Qsecurity/serialize.blockedlist\\E" + }, + { + "pattern": "\\Qsecurity/serialize.allowlist\\E" + } + ] + }, + "bundles": [] +} diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json new file mode 100644 index 0000000000..0d4f101c7a --- /dev/null +++ b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json @@ -0,0 +1,2 @@ +[ +] diff --git a/dubbo-native-plugin/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java b/dubbo-native-plugin/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java deleted file mode 100644 index ed54214c78..0000000000 --- a/dubbo-native-plugin/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java +++ /dev/null @@ -1,33 +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.common.metrics; - -import org.apache.dubbo.metrics.report.MetricsReporter; -import org.apache.dubbo.metrics.report.MetricsReporterFactory; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class MetricsReporterFactory$Adaptive implements MetricsReporterFactory { -public MetricsReporter createMetricsReporter(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "nop" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (MetricsReporterFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), MetricsReporterFactory.class); -MetricsReporterFactory extension = (MetricsReporterFactory)scopeModel.getExtensionLoader(MetricsReporterFactory.class).getExtension(extName); -return extension.createMetricsReporter(arg0); -} -} diff --git a/dubbo-native-plugin/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java b/dubbo-native-plugin/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java deleted file mode 100644 index 194958ed19..0000000000 --- a/dubbo-native-plugin/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java +++ /dev/null @@ -1,30 +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.common.threadpool; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class ThreadPool$Adaptive implements org.apache.dubbo.common.threadpool.ThreadPool { -public java.util.concurrent.Executor getExecutor(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("threadpool", "fixed"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.threadpool.ThreadPool) name from url (" + url.toString() + ") use keys([threadpool])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.common.threadpool.ThreadPool.class); -org.apache.dubbo.common.threadpool.ThreadPool extension = (org.apache.dubbo.common.threadpool.ThreadPool)scopeModel.getExtensionLoader(org.apache.dubbo.common.threadpool.ThreadPool.class).getExtension(extName); -return extension.getExecutor(arg0); -} -} diff --git a/dubbo-native-plugin/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java b/dubbo-native-plugin/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java deleted file mode 100644 index 6360d71c54..0000000000 --- a/dubbo-native-plugin/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java +++ /dev/null @@ -1,33 +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.executor; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class IsolationExecutorSupportFactory$Adaptive implements org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory { -public org.apache.dubbo.rpc.executor.ExecutorSupport getIsolationExecutorSupport(org.apache.dubbo.common.URL arg0) { -throw new UnsupportedOperationException("The method public static org.apache.dubbo.rpc.executor.ExecutorSupport org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory.getIsolationExecutorSupport(org.apache.dubbo.common.URL) of interface org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory is not adaptive method!"); -} -public org.apache.dubbo.rpc.executor.ExecutorSupport createIsolationExecutorSupport(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory.class); -org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory extension = (org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory.class).getExtension(extName); -return extension.createIsolationExecutorSupport(arg0); -} -} diff --git a/dubbo-native/pom.xml b/dubbo-native/pom.xml index 73e37cb332..449148f20a 100644 --- a/dubbo-native/pom.xml +++ b/dubbo-native/pom.xml @@ -30,51 +30,11 @@ - org.apache.dubbo dubbo-common ${project.parent.version} - - - - org.apache.dubbo - dubbo-metadata-api - ${project.parent.version} - - - - - org.apache.dubbo - dubbo-monitor-api - ${project.parent.version} - - - - org.apache.dubbo - dubbo-registry-api - ${project.parent.version} - - - - - org.apache.dubbo - dubbo-remoting-zookeeper - ${project.parent.version} - - - - org.apache.dubbo - dubbo-test-check - ${project.parent.version} - test - - - org.apache.dubbo - dubbo-metrics-default - ${project.parent.version} - diff --git a/dubbo-native/src/main/java/org/apache/dubbo/utils/ClassFinder.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceFinder.java similarity index 95% rename from dubbo-native/src/main/java/org/apache/dubbo/utils/ClassFinder.java rename to dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceFinder.java index 75ef3277e8..545c427442 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/utils/ClassFinder.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceFinder.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.utils; +package org.apache.dubbo.aot.generate; import java.io.File; @@ -26,7 +26,7 @@ import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; -public class ClassFinder { +public class ClassSourceFinder { public Set findClassSet(String packageName) { packageName = packageName.replace(".", "/"); @@ -42,7 +42,7 @@ public class ClassFinder { findClassesByFile(packageName, resource.getPath(), result); } else if ("jar".equals(protocol)) { JarFile jar = ((JarURLConnection) resource.openConnection()).getJarFile(); - System.out.println("findClassSet jar:"+jar.getName()); + System.out.println("findClassSet jar:" + jar.getName()); findClassesByJar(packageName, jar, result); } } diff --git a/dubbo-native/src/main/java/org/apache/dubbo/utils/CodeGenerator.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/CodeGenerator.java similarity index 81% rename from dubbo-native/src/main/java/org/apache/dubbo/utils/CodeGenerator.java rename to dubbo-native/src/main/java/org/apache/dubbo/aot/generate/CodeGenerator.java index aae60bb5b2..2e6a68cb97 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/utils/CodeGenerator.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/CodeGenerator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.utils; +package org.apache.dubbo.aot.generate; import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator; @@ -27,7 +27,6 @@ import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; -import java.net.URL; import java.nio.charset.Charset; import java.nio.file.Paths; import java.util.ArrayList; @@ -42,13 +41,12 @@ import java.util.stream.Collectors; */ public class CodeGenerator { - public static void main(String[] args) { - URL r = Thread.currentThread().getContextClassLoader().getResource(""); - String targetClassPath = new File(r.getFile()).getAbsolutePath(); - String p = Paths.get(targetClassPath).getParent().getParent().toString() + File.separator + "src" + File.separator + "main" + File.separator + "java"; - System.out.println(p); + private static final String PACKAGE_NAME_PREFIX = "org.apache.dubbo"; - List> classes = new ClassFinder().findClassSet("org.apache.dubbo").stream().map(it -> { + public static void main(String[] args) { + String generatedSources = args[1]; + + List> classes = new ClassSourceFinder().findClassSet(PACKAGE_NAME_PREFIX).stream().map(it -> { try { return Class.forName(it); } catch (Throwable e) { @@ -73,23 +71,20 @@ public class CodeGenerator { } AdaptiveClassCodeGenerator codeGenerator = new AdaptiveClassCodeGenerator(it, value); String code = codeGenerator.generate(true); - System.out.println(code); - System.out.println("-----:" + it.getPackage()); try { - String file = p + File.separator + it.getName().replaceAll("\\.", Matcher.quoteReplacement(File.separator)); + String file = generatedSources + File.separator + it.getName().replaceAll("\\.", Matcher.quoteReplacement(File.separator)); String dir = Paths.get(file).getParent().toString(); FileUtils.forceMkdir(new File(dir)); - code = licensedStr + code + "\n"; + code = LICENSED_STR + code + "\n"; FileUtils.write(new File(file + "$Adaptive.java"), code, Charset.defaultCharset()); } catch (IOException e) { - e.printStackTrace(); + throw new IllegalStateException("Failed to generated adaptive class sources", e); } }); - System.out.println(classes.size()); } - private static String licensedStr = "/*\n" + + private static final String LICENSED_STR = "/*\n" + " * Licensed to the Apache Software Foundation (ASF) under one or more\n" + " * contributor license agreements. See the NOTICE file distributed with\n" + " * this work for additional information regarding copyright ownership.\n" + diff --git a/dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java deleted file mode 100644 index ed54214c78..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java +++ /dev/null @@ -1,33 +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.common.metrics; - -import org.apache.dubbo.metrics.report.MetricsReporter; -import org.apache.dubbo.metrics.report.MetricsReporterFactory; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class MetricsReporterFactory$Adaptive implements MetricsReporterFactory { -public MetricsReporter createMetricsReporter(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "nop" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (MetricsReporterFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), MetricsReporterFactory.class); -MetricsReporterFactory extension = (MetricsReporterFactory)scopeModel.getExtensionLoader(MetricsReporterFactory.class).getExtension(extName); -return extension.createMetricsReporter(arg0); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java deleted file mode 100644 index ae3a0b6d6a..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java +++ /dev/null @@ -1,45 +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.common.serialize; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Serialization$Adaptive implements org.apache.dubbo.common.serialize.Serialization { -public byte getContentTypeId() { -throw new UnsupportedOperationException("The method public abstract byte org.apache.dubbo.common.serialize.Serialization.getContentTypeId() of interface org.apache.dubbo.common.serialize.Serialization is not adaptive method!"); -} -public java.lang.String getContentType() { -throw new UnsupportedOperationException("The method public abstract java.lang.String org.apache.dubbo.common.serialize.Serialization.getContentType() of interface org.apache.dubbo.common.serialize.Serialization is not adaptive method!"); -} -public org.apache.dubbo.common.serialize.ObjectInput deserialize(org.apache.dubbo.common.URL arg0, java.io.InputStream arg1) throws java.io.IOException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("serialization", "adaptive"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.serialize.Serialization) name from url (" + url.toString() + ") use keys([serialization])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.common.serialize.Serialization.class); -org.apache.dubbo.common.serialize.Serialization extension = (org.apache.dubbo.common.serialize.Serialization)scopeModel.getExtensionLoader(org.apache.dubbo.common.serialize.Serialization.class).getExtension(extName); -return extension.deserialize(arg0, arg1); -} -public org.apache.dubbo.common.serialize.ObjectOutput serialize(org.apache.dubbo.common.URL arg0, java.io.OutputStream arg1) throws java.io.IOException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("serialization", "adaptive"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.serialize.Serialization) name from url (" + url.toString() + ") use keys([serialization])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.common.serialize.Serialization.class); -org.apache.dubbo.common.serialize.Serialization extension = (org.apache.dubbo.common.serialize.Serialization)scopeModel.getExtensionLoader(org.apache.dubbo.common.serialize.Serialization.class).getExtension(extName); -return extension.serialize(arg0, arg1); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java deleted file mode 100644 index 194958ed19..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/common/threadpool/ThreadPool$Adaptive.java +++ /dev/null @@ -1,30 +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.common.threadpool; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class ThreadPool$Adaptive implements org.apache.dubbo.common.threadpool.ThreadPool { -public java.util.concurrent.Executor getExecutor(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("threadpool", "fixed"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.threadpool.ThreadPool) name from url (" + url.toString() + ") use keys([threadpool])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.common.threadpool.ThreadPool.class); -org.apache.dubbo.common.threadpool.ThreadPool extension = (org.apache.dubbo.common.threadpool.ThreadPool)scopeModel.getExtensionLoader(org.apache.dubbo.common.threadpool.ThreadPool.class).getExtension(extName); -return extension.getExecutor(arg0); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java deleted file mode 100644 index 0816ad1ec3..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java +++ /dev/null @@ -1,33 +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.metadata.report; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class MetadataReportFactory$Adaptive implements org.apache.dubbo.metadata.report.MetadataReportFactory { -public org.apache.dubbo.metadata.report.MetadataReport getMetadataReport(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "redis" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.metadata.report.MetadataReportFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.metadata.report.MetadataReportFactory.class); -org.apache.dubbo.metadata.report.MetadataReportFactory extension = (org.apache.dubbo.metadata.report.MetadataReportFactory)scopeModel.getExtensionLoader(org.apache.dubbo.metadata.report.MetadataReportFactory.class).getExtension(extName); -return extension.getMetadataReport(arg0); -} -public void destroy() { -throw new UnsupportedOperationException("The method public default void org.apache.dubbo.metadata.report.MetadataReportFactory.destroy() of interface org.apache.dubbo.metadata.report.MetadataReportFactory is not adaptive method!"); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/monitor/MonitorFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/monitor/MonitorFactory$Adaptive.java deleted file mode 100644 index 081064d92a..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/monitor/MonitorFactory$Adaptive.java +++ /dev/null @@ -1,30 +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.monitor; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class MonitorFactory$Adaptive implements org.apache.dubbo.monitor.MonitorFactory { -public org.apache.dubbo.monitor.Monitor getMonitor(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.monitor.MonitorFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.monitor.MonitorFactory.class); -org.apache.dubbo.monitor.MonitorFactory extension = (org.apache.dubbo.monitor.MonitorFactory)scopeModel.getExtensionLoader(org.apache.dubbo.monitor.MonitorFactory.class).getExtension(extName); -return extension.getMonitor(arg0); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java deleted file mode 100644 index 8b3ebc963e..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java +++ /dev/null @@ -1,30 +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.registry; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class RegistryFactory$Adaptive implements org.apache.dubbo.registry.RegistryFactory { -public org.apache.dubbo.registry.Registry getRegistry(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.registry.RegistryFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.registry.RegistryFactory.class); -org.apache.dubbo.registry.RegistryFactory extension = (org.apache.dubbo.registry.RegistryFactory)scopeModel.getExtensionLoader(org.apache.dubbo.registry.RegistryFactory.class).getExtension(extName); -return extension.getRegistry(arg0); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec$Adaptive.java deleted file mode 100644 index 25c3b4146f..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec$Adaptive.java +++ /dev/null @@ -1,41 +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.remoting; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Codec$Adaptive implements org.apache.dubbo.remoting.Codec { -public java.lang.Object decode(org.apache.dubbo.remoting.Channel arg0, java.io.InputStream arg1) throws java.io.IOException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = url.getParameter("codec", "adaptive"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.Codec) name from url (" + url.toString() + ") use keys([codec])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.Codec.class); -org.apache.dubbo.remoting.Codec extension = (org.apache.dubbo.remoting.Codec)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.Codec.class).getExtension(extName); -return extension.decode(arg0, arg1); -} -public void encode(org.apache.dubbo.remoting.Channel arg0, java.io.OutputStream arg1, java.lang.Object arg2) throws java.io.IOException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = url.getParameter("codec", "adaptive"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.Codec) name from url (" + url.toString() + ") use keys([codec])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.Codec.class); -org.apache.dubbo.remoting.Codec extension = (org.apache.dubbo.remoting.Codec)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.Codec.class).getExtension(extName); -extension.encode(arg0, arg1, arg2); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec2$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec2$Adaptive.java deleted file mode 100644 index cffc978798..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Codec2$Adaptive.java +++ /dev/null @@ -1,41 +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.remoting; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Codec2$Adaptive implements org.apache.dubbo.remoting.Codec2 { -public java.lang.Object decode(org.apache.dubbo.remoting.Channel arg0, org.apache.dubbo.remoting.buffer.ChannelBuffer arg1) throws java.io.IOException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = url.getParameter("codec", "adaptive"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.Codec2) name from url (" + url.toString() + ") use keys([codec])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.Codec2.class); -org.apache.dubbo.remoting.Codec2 extension = (org.apache.dubbo.remoting.Codec2)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.Codec2.class).getExtension(extName); -return extension.decode(arg0, arg1); -} -public void encode(org.apache.dubbo.remoting.Channel arg0, org.apache.dubbo.remoting.buffer.ChannelBuffer arg1, java.lang.Object arg2) throws java.io.IOException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.remoting.Channel argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = url.getParameter("codec", "adaptive"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.Codec2) name from url (" + url.toString() + ") use keys([codec])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.Codec2.class); -org.apache.dubbo.remoting.Codec2 extension = (org.apache.dubbo.remoting.Codec2)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.Codec2.class).getExtension(extName); -extension.encode(arg0, arg1, arg2); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Dispatcher$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/remoting/Dispatcher$Adaptive.java deleted file mode 100644 index 51269145d4..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Dispatcher$Adaptive.java +++ /dev/null @@ -1,30 +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.remoting; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Dispatcher$Adaptive implements org.apache.dubbo.remoting.Dispatcher { -public org.apache.dubbo.remoting.ChannelHandler dispatch(org.apache.dubbo.remoting.ChannelHandler arg0, org.apache.dubbo.common.URL arg1) { -if (arg1 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg1; -String extName = url.getParameter("dispatcher", url.getParameter("dispather", url.getParameter("channel.handler", "all"))); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.Dispatcher) name from url (" + url.toString() + ") use keys([dispatcher, dispather, channel.handler])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.Dispatcher.class); -org.apache.dubbo.remoting.Dispatcher extension = (org.apache.dubbo.remoting.Dispatcher)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.Dispatcher.class).getExtension(extName); -return extension.dispatch(arg0, arg1); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Transporter$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/remoting/Transporter$Adaptive.java deleted file mode 100644 index 6a858aebf4..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/remoting/Transporter$Adaptive.java +++ /dev/null @@ -1,39 +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.remoting; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Transporter$Adaptive implements org.apache.dubbo.remoting.Transporter { -public org.apache.dubbo.remoting.Client connect(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.ChannelHandler arg1) throws org.apache.dubbo.remoting.RemotingException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("client", url.getParameter("transporter", "netty")); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.Transporter) name from url (" + url.toString() + ") use keys([client, transporter])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.Transporter.class); -org.apache.dubbo.remoting.Transporter extension = (org.apache.dubbo.remoting.Transporter)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.Transporter.class).getExtension(extName); -return extension.connect(arg0, arg1); -} -public org.apache.dubbo.remoting.RemotingServer bind(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.ChannelHandler arg1) throws org.apache.dubbo.remoting.RemotingException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("server", url.getParameter("transporter", "netty")); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.Transporter) name from url (" + url.toString() + ") use keys([server, transporter])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.Transporter.class); -org.apache.dubbo.remoting.Transporter extension = (org.apache.dubbo.remoting.Transporter)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.Transporter.class).getExtension(extName); -return extension.bind(arg0, arg1); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java deleted file mode 100644 index d5c1cc0a7a..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java +++ /dev/null @@ -1,39 +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.remoting.api.pu; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class PortUnificationTransporter$Adaptive implements org.apache.dubbo.remoting.api.pu.PortUnificationTransporter { -public org.apache.dubbo.remoting.api.connection.AbstractConnectionClient connect(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.ChannelHandler arg1) throws org.apache.dubbo.remoting.RemotingException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("client", url.getParameter("transporter", "netty4")); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter) name from url (" + url.toString() + ") use keys([client, transporter])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class); -org.apache.dubbo.remoting.api.pu.PortUnificationTransporter extension = (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class).getExtension(extName); -return extension.connect(arg0, arg1); -} -public org.apache.dubbo.remoting.api.pu.AbstractPortUnificationServer bind(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.ChannelHandler arg1) throws org.apache.dubbo.remoting.RemotingException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("server", url.getParameter("transporter", "netty4")); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter) name from url (" + url.toString() + ") use keys([server, transporter])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class); -org.apache.dubbo.remoting.api.pu.PortUnificationTransporter extension = (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class).getExtension(extName); -return extension.bind(arg0, arg1); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/remoting/exchange/Exchanger$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/remoting/exchange/Exchanger$Adaptive.java deleted file mode 100644 index 015bf179fa..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/remoting/exchange/Exchanger$Adaptive.java +++ /dev/null @@ -1,39 +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.remoting.exchange; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Exchanger$Adaptive implements org.apache.dubbo.remoting.exchange.Exchanger { -public org.apache.dubbo.remoting.exchange.ExchangeClient connect(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.exchange.ExchangeHandler arg1) throws org.apache.dubbo.remoting.RemotingException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("exchanger", "header"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.exchange.Exchanger) name from url (" + url.toString() + ") use keys([exchanger])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.exchange.Exchanger.class); -org.apache.dubbo.remoting.exchange.Exchanger extension = (org.apache.dubbo.remoting.exchange.Exchanger)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.exchange.Exchanger.class).getExtension(extName); -return extension.connect(arg0, arg1); -} -public org.apache.dubbo.remoting.exchange.ExchangeServer bind(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.exchange.ExchangeHandler arg1) throws org.apache.dubbo.remoting.RemotingException { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("exchanger", "header"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.exchange.Exchanger) name from url (" + url.toString() + ") use keys([exchanger])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.exchange.Exchanger.class); -org.apache.dubbo.remoting.exchange.Exchanger extension = (org.apache.dubbo.remoting.exchange.Exchanger)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.exchange.Exchanger.class).getExtension(extName); -return extension.bind(arg0, arg1); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/Protocol$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/Protocol$Adaptive.java deleted file mode 100644 index 16367fa414..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/Protocol$Adaptive.java +++ /dev/null @@ -1,49 +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; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol { -public int getDefaultPort() { -throw new UnsupportedOperationException("The method public abstract int org.apache.dubbo.rpc.Protocol.getDefaultPort() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!"); -} -public org.apache.dubbo.rpc.Exporter export(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.Protocol.class); -org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName); -return extension.export(arg0); -} -public org.apache.dubbo.rpc.Invoker refer(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) throws org.apache.dubbo.rpc.RpcException { -if (arg1 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg1; -String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.Protocol.class); -org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName); -return extension.refer(arg0, arg1); -} -public void destroy() { -throw new UnsupportedOperationException("The method public abstract void org.apache.dubbo.rpc.Protocol.destroy() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!"); -} -public java.util.List getServers() { -throw new UnsupportedOperationException("The method public default java.util.List org.apache.dubbo.rpc.Protocol.getServers() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!"); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/ProxyFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/ProxyFactory$Adaptive.java deleted file mode 100644 index 101925d8ab..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/ProxyFactory$Adaptive.java +++ /dev/null @@ -1,50 +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; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class ProxyFactory$Adaptive implements org.apache.dubbo.rpc.ProxyFactory { -public java.lang.Object getProxy(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = url.getParameter("proxy", "javassist"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.ProxyFactory) name from url (" + url.toString() + ") use keys([proxy])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.ProxyFactory.class); -org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName); -return extension.getProxy(arg0); -} -public java.lang.Object getProxy(org.apache.dubbo.rpc.Invoker arg0, boolean arg1) throws org.apache.dubbo.rpc.RpcException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = url.getParameter("proxy", "javassist"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.ProxyFactory) name from url (" + url.toString() + ") use keys([proxy])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.ProxyFactory.class); -org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName); -return extension.getProxy(arg0, arg1); -} -public org.apache.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1, org.apache.dubbo.common.URL arg2) throws org.apache.dubbo.rpc.RpcException { -if (arg2 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg2; -String extName = url.getParameter("proxy", "javassist"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.ProxyFactory) name from url (" + url.toString() + ") use keys([proxy])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.ProxyFactory.class); -org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName); -return extension.getInvoker(arg0, arg1, arg2); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/Cluster$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/Cluster$Adaptive.java deleted file mode 100644 index e8b087d611..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/Cluster$Adaptive.java +++ /dev/null @@ -1,37 +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.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class Cluster$Adaptive implements org.apache.dubbo.rpc.cluster.Cluster { -public org.apache.dubbo.rpc.Invoker join(org.apache.dubbo.rpc.cluster.Directory arg0, boolean arg1) throws org.apache.dubbo.rpc.RpcException { -if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.cluster.Directory argument == null"); -if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.cluster.Directory argument getUrl() == null"); -org.apache.dubbo.common.URL url = arg0.getUrl(); -String extName = url.getParameter("cluster", "failover"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.Cluster) name from url (" + url.toString() + ") use keys([cluster])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.cluster.Cluster.class); -org.apache.dubbo.rpc.cluster.Cluster extension = (org.apache.dubbo.rpc.cluster.Cluster)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.cluster.Cluster.class).getExtension(extName); -return extension.join(arg0, arg1); -} -public org.apache.dubbo.rpc.cluster.Cluster getCluster(org.apache.dubbo.rpc.model.ScopeModel arg0, java.lang.String arg1) { -throw new UnsupportedOperationException("The method public static org.apache.dubbo.rpc.cluster.Cluster org.apache.dubbo.rpc.cluster.Cluster.getCluster(org.apache.dubbo.rpc.model.ScopeModel,java.lang.String) of interface org.apache.dubbo.rpc.cluster.Cluster is not adaptive method!"); -} -public org.apache.dubbo.rpc.cluster.Cluster getCluster(org.apache.dubbo.rpc.model.ScopeModel arg0, java.lang.String arg1, boolean arg2) { -throw new UnsupportedOperationException("The method public static org.apache.dubbo.rpc.cluster.Cluster org.apache.dubbo.rpc.cluster.Cluster.getCluster(org.apache.dubbo.rpc.model.ScopeModel,java.lang.String,boolean) of interface org.apache.dubbo.rpc.cluster.Cluster is not adaptive method!"); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory$Adaptive.java deleted file mode 100644 index f4dec3f001..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory$Adaptive.java +++ /dev/null @@ -1,30 +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.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class ConfiguratorFactory$Adaptive implements org.apache.dubbo.rpc.cluster.ConfiguratorFactory { -public org.apache.dubbo.rpc.cluster.Configurator getConfigurator(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.ConfiguratorFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.cluster.ConfiguratorFactory.class); -org.apache.dubbo.rpc.cluster.ConfiguratorFactory extension = (org.apache.dubbo.rpc.cluster.ConfiguratorFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.cluster.ConfiguratorFactory.class).getExtension(extName); -return extension.getConfigurator(arg0); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/LoadBalance$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/LoadBalance$Adaptive.java deleted file mode 100644 index f941ecd4a3..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/LoadBalance$Adaptive.java +++ /dev/null @@ -1,31 +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.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class LoadBalance$Adaptive implements org.apache.dubbo.rpc.cluster.LoadBalance { -public org.apache.dubbo.rpc.Invoker select(java.util.List arg0, org.apache.dubbo.common.URL arg1, org.apache.dubbo.rpc.Invocation arg2) throws org.apache.dubbo.rpc.RpcException { -if (arg1 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg1; -if (arg2 == null) throw new IllegalArgumentException("invocation == null"); String methodName = arg2.getMethodName(); -String extName = url.getMethodParameter(methodName, "loadbalance", "random"); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.LoadBalance) name from url (" + url.toString() + ") use keys([loadbalance])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.cluster.LoadBalance.class); -org.apache.dubbo.rpc.cluster.LoadBalance extension = (org.apache.dubbo.rpc.cluster.LoadBalance)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.cluster.LoadBalance.class).getExtension(extName); -return extension.select(arg0, arg1, arg2); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory$Adaptive.java deleted file mode 100644 index a4aa21c140..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory$Adaptive.java +++ /dev/null @@ -1,30 +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.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class RouterFactory$Adaptive implements org.apache.dubbo.rpc.cluster.RouterFactory { -public org.apache.dubbo.rpc.cluster.Router getRouter(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.RouterFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.cluster.RouterFactory.class); -org.apache.dubbo.rpc.cluster.RouterFactory extension = (org.apache.dubbo.rpc.cluster.RouterFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.cluster.RouterFactory.class).getExtension(extName); -return extension.getRouter(arg0); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java deleted file mode 100644 index c33747dc83..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java +++ /dev/null @@ -1,30 +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.router.state; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class StateRouterFactory$Adaptive implements org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory { -public org.apache.dubbo.rpc.cluster.router.state.StateRouter getRouter(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) { -if (arg1 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg1; -String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory.class); -org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory extension = (org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory.class).getExtension(extName); -return extension.getRouter(arg0, arg1); -} -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java deleted file mode 100644 index fbf3bcf235..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/executor/IsolationExecutorSupportFactory$Adaptive.java +++ /dev/null @@ -1,33 +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.executor; -import org.apache.dubbo.rpc.model.ScopeModel; -import org.apache.dubbo.rpc.model.ScopeModelUtil; -public class IsolationExecutorSupportFactory$Adaptive implements org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory { -public org.apache.dubbo.rpc.executor.ExecutorSupport createIsolationExecutorSupport(org.apache.dubbo.common.URL arg0) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); -org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); -if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory) name from url (" + url.toString() + ") use keys([protocol])"); -ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory.class); -org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory extension = (org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory.class).getExtension(extName); -return extension.createIsolationExecutorSupport(arg0); -} -public org.apache.dubbo.rpc.executor.ExecutorSupport getIsolationExecutorSupport(org.apache.dubbo.common.URL arg0) { -throw new UnsupportedOperationException("The method public static org.apache.dubbo.rpc.executor.ExecutorSupport org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory.getIsolationExecutorSupport(org.apache.dubbo.common.URL) of interface org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory is not adaptive method!"); -} -} diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index 8922e63208..5e9a515d5a 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -184,6 +184,11 @@ dubbo-native-plugin + + org.apache.dubbo + dubbo-maven-plugin + + org.apache.dubbo diff --git a/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java b/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java index 4a69205f85..4f912e3001 100644 --- a/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java +++ b/dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java @@ -57,6 +57,7 @@ class FileTest { ignoredModulesInDubboAll.add(Pattern.compile("dubbo-metadata-processor")); ignoredModulesInDubboAll.add(Pattern.compile("dubbo-native.*")); ignoredModulesInDubboAll.add(Pattern.compile("dubbo-spring-boot.*")); + ignoredModulesInDubboAll.add(Pattern.compile("dubbo-maven-plugin")); } @Test diff --git a/pom.xml b/pom.xml index 9323273df3..eea92a1f98 100644 --- a/pom.xml +++ b/pom.xml @@ -161,6 +161,7 @@ dubbo-kubernetes dubbo-xds dubbo-native-plugin + dubbo-maven-plugin @@ -318,6 +319,21 @@ ${checkstyle.skip} **/JSONWriter.java, + **/org/apache/dubbo/maven/plugin/aot/AbstractAotMojo.java, + **/org/apache/dubbo/maven/plugin/aot/AbstractDependencyFilterMojo.java, + **/org/apache/dubbo/maven/plugin/aot/CommandLineBuilder.java, + **/org/apache/dubbo/maven/plugin/aot/DependencyFilter.java, + **/org/apache/dubbo/maven/plugin/aot/Exclude.java, + **/org/apache/dubbo/maven/plugin/aot/ExcludeFilter.java, + **/org/apache/dubbo/maven/plugin/aot/FilterableDependency.java, + **/org/apache/dubbo/maven/plugin/aot/Include.java, + **/org/apache/dubbo/maven/plugin/aot/IncludeFilter.java, + **/org/apache/dubbo/maven/plugin/aot/JavaCompilerPluginConfiguration.java, + **/org/apache/dubbo/maven/plugin/aot/JavaExecutable.java, + **/org/apache/dubbo/maven/plugin/aot/JavaProcessExecutor.java, + **/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java, + **/org/apache/dubbo/maven/plugin/aot/RunArguments.java, + **/org/apache/dubbo/maven/plugin/aot/RunProcess.java, **/org/apache/dubbo/common/threadpool/serial/SerializingExecutor.java, **/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java, **/org/apache/dubbo/common/threadlocal/InternalThreadLocalMap.java, From 8c786cdf01126cc559856968d211fa648788d4d2 Mon Sep 17 00:00:00 2001 From: Ken Liu Date: Sun, 26 Feb 2023 15:17:36 +0800 Subject: [PATCH 033/144] Add 'label match' support for override and tag rules (#11094) --- .../apache/dubbo/rpc/cluster/Constants.java | 6 +- .../configurator/AbstractConfigurator.java | 147 ++++++++--- .../override/OverrideConfigurator.java | 4 + .../configurator/parser/ConfigParser.java | 21 +- .../parser/model/ConditionMatch.java | 98 +++++++ .../configurator/parser/model/ConfigItem.java | 32 ++- .../parser/model/ConfiguratorConfig.java | 1 + .../configurator/parser/model/ParamMatch.java | 58 +++++ .../cluster/router/AbstractRouterRule.java | 11 + .../condition/ConditionStateRouter.java | 241 ++++++------------ .../config/ListenableStateRouter.java | 2 +- .../config/ProviderAppStateRouter.java | 77 ++++++ .../config/ProviderAppStateRouterFactory.java | 36 +++ .../matcher/AbstractConditionMatcher.java | 138 ++++++++++ .../condition/matcher/ConditionMatcher.java | 61 +++++ .../matcher/ConditionMatcherFactory.java | 43 ++++ .../argument/ArgumentConditionMatcher.java | 72 ++++++ .../ArgumentConditionMatcherFactory.java | 37 +++ .../AttachmentConditionMatcher.java | 76 ++++++ .../AttachmentConditionMatcherFactory.java | 37 +++ .../param/UrlParamConditionMatcher.java | 41 +++ .../UrlParamConditionMatcherFactory.java | 36 +++ .../matcher/pattern/ValuePattern.java | 47 ++++ .../pattern/range/RangeValuePattern.java | 84 ++++++ .../wildcard/WildcardValuePattern.java | 41 +++ .../router/mesh/route/MeshRuleCache.java | 7 +- .../virtualservice/match/AddressMatch.java | 80 ++++++ .../virtualservice/match/StringMatch.java | 15 +- .../script/config/AppScriptRouterFactory.java | 32 +++ .../script/config/AppScriptStateRouter.java | 150 +++++++++++ .../script/config/model/ScriptRule.java | 70 +++++ .../router/state/AbstractStateRouter.java | 4 +- .../cluster/router/tag/TagStateRouter.java | 47 +++- .../cluster/router/tag/model/ParamMatch.java | 47 ++++ .../rpc/cluster/router/tag/model/Tag.java | 36 ++- .../router/tag/model/TagRouterRule.java | 61 ++++- .../router/tag/model/TagRuleParser.java | 3 +- ....condition.matcher.ConditionMatcherFactory | 4 + ...ter.condition.matcher.pattern.ValuePattern | 2 + ...pc.cluster.router.state.StateRouterFactory | 2 + .../dubbo/rpc/cluster/RouterChainTest.java | 10 +- .../override/OverrideConfiguratorTest.java | 79 ++++++ .../configurator/parser/ConfigParserTest.java | 71 ++++++ .../router/RouterSnapshotFilterTest.java | 6 + .../condition/ConditionStateRouterTest.java | 120 +++++++++ .../ProviderAppConditionStateRouterTest.java | 97 +++++++ .../router/mesh/route/MeshRuleCacheTest.java | 15 +- .../config/AppScriptStateRouterTest.java | 100 ++++++++ .../router/tag/TagStateRouterTest.java | 127 +++++++++ .../src/test/resources/AppAnyServices.yml | 2 +- .../src/test/resources/ConfiguratorV3.yml | 40 +++ .../resources/ConfiguratorV3Compatibility.yml | 38 +++ .../resources/ConfiguratorV3Duplicate.yml | 43 ++++ .../src/test/resources/ScriptRule.yaml | 35 +++ dubbo-cluster/src/test/resources/log4j.xml | 10 +- .../java/org/apache/dubbo/common/URL.java | 29 +++ .../common/constants/CommonConstants.java | 2 + .../common/constants/LoggerCodeConstants.java | 3 + .../infra/support/EnvironmentAdapter.java | 5 + .../common/logger/log4j/Log4jLogger.java | 4 + .../url/component/ServiceAddressURL.java | 17 ++ .../apache/dubbo/common/utils/NetUtils.java | 31 ++- dubbo-distribution/dubbo-all/pom.xml | 12 + .../META-INF/native-image/reflect-config.json | 79 +++++- .../registry/client/InstanceAddressURL.java | 60 +++++ .../ServiceDiscoveryRegistryDirectory.java | 80 ++++-- .../AbstractConfiguratorListener.java | 6 +- .../integration/DynamicDirectory.java | 11 +- .../integration/RegistryDirectory.java | 6 +- .../integration/DynamicDirectoryTest.java | 5 + .../java/org/apache/dubbo/rpc/Constants.java | 2 + .../dubbo/rpc/filter/AccessLogFilter.java | 108 +++++--- .../dubbo/rpc/filter/AccessLogFilterTest.java | 93 +++++-- .../src/test/resources/log4j.xml | 10 +- 74 files changed, 3028 insertions(+), 335 deletions(-) create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConditionMatch.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ParamMatch.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouterFactory.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/AbstractConditionMatcher.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcher.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcherFactory.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcher.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcherFactory.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcher.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcherFactory.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcher.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcherFactory.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/ValuePattern.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/range/RangeValuePattern.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/wildcard/WildcardValuePattern.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/AddressMatch.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptRouterFactory.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouter.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/model/ScriptRule.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/ParamMatch.java create mode 100644 dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory create mode 100644 dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern create mode 100644 dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppConditionStateRouterTest.java create mode 100644 dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouterTest.java create mode 100644 dubbo-cluster/src/test/resources/ConfiguratorV3.yml create mode 100644 dubbo-cluster/src/test/resources/ConfiguratorV3Compatibility.yml create mode 100644 dubbo-cluster/src/test/resources/ConfiguratorV3Duplicate.yml create mode 100644 dubbo-cluster/src/test/resources/ScriptRule.yaml diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java index c4936102f9..ab8c50b568 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java @@ -72,8 +72,6 @@ public interface Constants { */ boolean DEFAULT_CLUSTER_STICKY = false; - String ADDRESS_KEY = "address"; - /** * When this attribute appears in invocation's attachment, mock invoker will be used */ @@ -137,4 +135,8 @@ public interface Constants { String SHORTEST_RESPONSE_SLIDE_PERIOD = "shortestResponseSlidePeriod"; String SHOULD_FAIL_FAST_KEY = "dubbo.router.should-fail-fast"; + + String RULE_VERSION_V27 = "v2.7"; + + String RULE_VERSION_V30 = "v3.0"; } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java index 89b3798c40..56c35c8965 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java @@ -17,10 +17,13 @@ package org.apache.dubbo.rpc.cluster.configurator; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.Logger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.rpc.cluster.Configurator; +import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConditionMatch; import java.util.HashSet; import java.util.Map; @@ -41,12 +44,14 @@ import static org.apache.dubbo.common.constants.RegistryConstants.COMPATIBLE_CON import static org.apache.dubbo.common.constants.RegistryConstants.DYNAMIC_KEY; import static org.apache.dubbo.rpc.cluster.Constants.CONFIG_VERSION_KEY; import static org.apache.dubbo.rpc.cluster.Constants.OVERRIDE_PROVIDERS_KEY; +import static org.apache.dubbo.rpc.cluster.Constants.RULE_VERSION_V30; +import static org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig.MATCH_CONDITION; /** * AbstractConfigurator */ public abstract class AbstractConfigurator implements Configurator { - + private static final Logger logger = LoggerFactory.getLogger(AbstractConfigurator.class); private static final String TILDE = "~"; private final URL configuratorUrl; @@ -67,19 +72,17 @@ public abstract class AbstractConfigurator implements Configurator { public URL configure(URL url) { // If override url is not enabled or is invalid, just return. if (!configuratorUrl.getParameter(ENABLED_KEY, true) || configuratorUrl.getHost() == null || url == null || url.getHost() == null) { + logger.info("Cannot apply configurator rule, the rule is disabled or is invalid: \n" + configuratorUrl); return url; } - /* - * This if branch is created since 2.7.0. - */ + String apiVersion = configuratorUrl.getParameter(CONFIG_VERSION_KEY); - if (StringUtils.isNotEmpty(apiVersion)) { + if (StringUtils.isNotEmpty(apiVersion)) { // v2.7 or above String currentSide = url.getSide(); String configuratorSide = configuratorUrl.getSide(); - if (currentSide.equals(configuratorSide) && CONSUMER.equals(configuratorSide) && 0 == configuratorUrl.getPort()) { + if (currentSide.equals(configuratorSide) && CONSUMER.equals(configuratorSide)) { url = configureIfMatch(NetUtils.getLocalHost(), url); - } else if (currentSide.equals(configuratorSide) && PROVIDER.equals(configuratorSide) && - url.getPort() == configuratorUrl.getPort()) { + } else if (currentSide.equals(configuratorSide) && PROVIDER.equals(configuratorSide)) { url = configureIfMatch(url.getHost(), url); } } @@ -118,46 +121,112 @@ public abstract class AbstractConfigurator implements Configurator { private URL configureIfMatch(String host, URL url) { if (ANYHOST_VALUE.equals(configuratorUrl.getHost()) || host.equals(configuratorUrl.getHost())) { - // TODO, to support wildcards - String providers = configuratorUrl.getParameter(OVERRIDE_PROVIDERS_KEY); - if (StringUtils.isEmpty(providers) || providers.contains(url.getAddress()) || providers.contains(ANYHOST_VALUE)) { - String configApplication = configuratorUrl.getApplication(configuratorUrl.getUsername()); - String currentApplication = url.getApplication(url.getUsername()); - if (configApplication == null || ANY_VALUE.equals(configApplication) - || configApplication.equals(currentApplication)) { - Set conditionKeys = new HashSet(); - conditionKeys.add(CATEGORY_KEY); - conditionKeys.add(Constants.CHECK_KEY); - conditionKeys.add(DYNAMIC_KEY); - conditionKeys.add(ENABLED_KEY); - conditionKeys.add(GROUP_KEY); - conditionKeys.add(VERSION_KEY); - conditionKeys.add(APPLICATION_KEY); - conditionKeys.add(SIDE_KEY); - conditionKeys.add(CONFIG_VERSION_KEY); - conditionKeys.add(COMPATIBLE_CONFIG_KEY); - conditionKeys.add(INTERFACES); - for (Map.Entry entry : configuratorUrl.getParameters().entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - boolean startWithTilde = startWithTilde(key); - if (startWithTilde || APPLICATION_KEY.equals(key) || SIDE_KEY.equals(key)) { - if (startWithTilde) { - conditionKeys.add(key); - } - if (value != null && !ANY_VALUE.equals(value) - && !value.equals(url.getParameter(startWithTilde ? key.substring(1) : key))) { - return url; - } + if (isV27ConditionMatchOrUnset(url)) { + Set conditionKeys = genConditionKeys(); + String apiVersion = configuratorUrl.getParameter(CONFIG_VERSION_KEY); + if (apiVersion != null && apiVersion.startsWith(RULE_VERSION_V30)) { + ConditionMatch matcher = (ConditionMatch) configuratorUrl.getAttribute(MATCH_CONDITION); + if (matcher != null) { + if (matcher.isMatch(url)) { + return doConfigure(url, configuratorUrl.removeParameters(conditionKeys)); + } else { + logger.debug("Cannot apply configurator rule, param mismatch, current params are " + url + ", params in rule is " + matcher); } + } else { + return doConfigure(url, configuratorUrl.removeParameters(conditionKeys)); } + } else if (isDeprecatedConditionMatch(conditionKeys, url)) { return doConfigure(url, configuratorUrl.removeParameters(conditionKeys)); } } + } else { + logger.debug("Cannot apply configurator rule, host mismatch, current host is " + host + ", host in rule is " + configuratorUrl.getHost()); } return url; } + /** + * Check if v2.7 configurator rule is set and can be matched. + * + * @param url the configurator rule url + * @return true if v2.7 configurator rule is not set or the rule can be matched. + */ + private boolean isV27ConditionMatchOrUnset(URL url) { + String providers = configuratorUrl.getParameter(OVERRIDE_PROVIDERS_KEY); + if (StringUtils.isNotEmpty(providers)) { + boolean match = false; + String[] providerAddresses = providers.split(","); + for (String address : providerAddresses) { + if (address.equals(url.getAddress()) + || address.equals(ANYHOST_VALUE) + || address.equals(ANYHOST_VALUE + ":" + ANY_VALUE) + || address.equals(ANYHOST_VALUE + ":" + url.getPort()) + || address.equals(url.getHost())) { + match = true; + } + } + if (!match) { + logger.debug("Cannot apply configurator rule, provider address mismatch, current address " + url.getAddress() + ", address in rule is " + providers); + return false; + } + } + + String configApplication = configuratorUrl.getApplication(configuratorUrl.getUsername()); + String currentApplication = url.getApplication(url.getUsername()); + if (configApplication != null + && !ANY_VALUE.equals(configApplication) + && !configApplication.equals(currentApplication)) { + logger.debug("Cannot apply configurator rule, application name mismatch, current application is " + currentApplication + ", application in rule is " + configApplication); + return false; + } + + String configServiceKey = configuratorUrl.getServiceKey(); + String currentServiceKey = url.getServiceKey(); + if (!ANY_VALUE.equals(configServiceKey) + && !configServiceKey.equals(currentServiceKey)) { + logger.debug("Cannot apply configurator rule, service mismatch, current service is " + currentServiceKey + ", service in rule is " + configServiceKey); + return false; + } + + return true; + } + + private boolean isDeprecatedConditionMatch(Set conditionKeys, URL url) { + boolean result = true; + for (Map.Entry entry : configuratorUrl.getParameters().entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + boolean startWithTilde = startWithTilde(key); + if (startWithTilde || APPLICATION_KEY.equals(key) || SIDE_KEY.equals(key)) { + if (startWithTilde) { + conditionKeys.add(key); + } + if (value != null && !ANY_VALUE.equals(value) + && !value.equals(url.getParameter(startWithTilde ? key.substring(1) : key))) { + result = false; + break; + } + } + } + return result; + } + + private Set genConditionKeys() { + Set conditionKeys = new HashSet(); + conditionKeys.add(CATEGORY_KEY); + conditionKeys.add(Constants.CHECK_KEY); + conditionKeys.add(DYNAMIC_KEY); + conditionKeys.add(ENABLED_KEY); + conditionKeys.add(GROUP_KEY); + conditionKeys.add(VERSION_KEY); + conditionKeys.add(APPLICATION_KEY); + conditionKeys.add(SIDE_KEY); + conditionKeys.add(CONFIG_VERSION_KEY); + conditionKeys.add(COMPATIBLE_CONFIG_KEY); + conditionKeys.add(INTERFACES); + return conditionKeys; + } + private boolean startWithTilde(String key) { if (StringUtils.isNotEmpty(key) && key.startsWith(TILDE)) { return true; diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfigurator.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfigurator.java index ab44dc497a..a61190d7cd 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfigurator.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfigurator.java @@ -17,12 +17,15 @@ package org.apache.dubbo.rpc.cluster.configurator.override; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.Logger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.rpc.cluster.configurator.AbstractConfigurator; /** * OverrideConfigurator */ public class OverrideConfigurator extends AbstractConfigurator { + public static final Logger logger = LoggerFactory.getLogger(OverrideConfigurator.class); public OverrideConfigurator(URL url) { super(url); @@ -30,6 +33,7 @@ public class OverrideConfigurator extends AbstractConfigurator { @Override public URL doConfigure(URL currentUrl, URL configUrl) { + logger.info("Start overriding url " + currentUrl + " with override url " + configUrl); return currentUrl.addParameters(configUrl.getParameters()); } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java index d0c855db93..2e4d46865a 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java @@ -31,9 +31,11 @@ import java.util.List; import java.util.Map; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; import static org.apache.dubbo.common.constants.RegistryConstants.APP_DYNAMIC_CONFIGURATORS_CATEGORY; import static org.apache.dubbo.common.constants.RegistryConstants.DYNAMIC_CONFIGURATORS_CATEGORY; import static org.apache.dubbo.rpc.cluster.Constants.OVERRIDE_PROVIDERS_KEY; +import static org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig.MATCH_CONDITION; /** * Config parser @@ -59,6 +61,7 @@ public class ConfigParser { // service scope by default. items.forEach(item -> urls.addAll(serviceItemToUrls(item, configuratorConfig))); } + return urls; } @@ -100,10 +103,10 @@ public class ConfigParser { if (CollectionUtils.isNotEmpty(apps)) { apps.forEach(app -> { StringBuilder tmpUrlBuilder = new StringBuilder(urlBuilder); - urls.add(URL.valueOf(tmpUrlBuilder.append("&application=").append(app).toString())); + urls.add(appendMatchCondition(URL.valueOf(tmpUrlBuilder.append("&application=").append(app).toString()), item)); }); } else { - urls.add(URL.valueOf(urlBuilder.toString())); + urls.add(appendMatchCondition(URL.valueOf(urlBuilder.toString()), item)); } }); @@ -135,7 +138,7 @@ public class ConfigParser { tmpUrlBuilder.append("&category=").append(APP_DYNAMIC_CONFIGURATORS_CATEGORY); tmpUrlBuilder.append("&configVersion=").append(config.getConfigVersion()); - urls.add(URL.valueOf(tmpUrlBuilder.toString())); + urls.add(appendMatchCondition(URL.valueOf(tmpUrlBuilder.toString()), item)); } } return urls; @@ -167,6 +170,11 @@ public class ConfigParser { sb.append(OVERRIDE_PROVIDERS_KEY); sb.append('='); sb.append(CollectionUtils.join(item.getProviderAddresses(), ",")); + } else if (PROVIDER.equals(item.getSide())) { + sb.append('&'); + sb.append(OVERRIDE_PROVIDERS_KEY); + sb.append('='); + sb.append(CollectionUtils.join(parseAddresses(item), ",")); } return sb.toString(); @@ -218,4 +226,11 @@ public class ConfigParser { } return addresses; } + + private static URL appendMatchCondition(URL url, ConfigItem item) { + if (item.getMatch() != null) { + url = url.putAttribute(MATCH_CONDITION, item.getMatch()); + } + return url; + } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConditionMatch.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConditionMatch.java new file mode 100644 index 0000000000..b16c2c978a --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConditionMatch.java @@ -0,0 +1,98 @@ +/* + * 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.configurator.parser.model; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match.AddressMatch; +import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match.ListStringMatch; + +import java.util.List; + +import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; + +public class ConditionMatch { + private AddressMatch address; + private ListStringMatch service; + private ListStringMatch app; + private List param; + + public AddressMatch getAddress() { + return address; + } + + public void setAddress(AddressMatch address) { + this.address = address; + } + + public ListStringMatch getService() { + return service; + } + + public void setService(ListStringMatch service) { + this.service = service; + } + + public ListStringMatch getApp() { + return app; + } + + public void setApp(ListStringMatch app) { + this.app = app; + } + + public List getParam() { + return param; + } + + public void setParam(List param) { + this.param = param; + } + + public boolean isMatch(URL url) { + if (getAddress() != null && !getAddress().isMatch(url.getAddress())) { + return false; + } + + if (getService() != null && !getService().isMatch(url.getServiceKey())) { + return false; + } + + if (getApp() != null && !getApp().isMatch(url.getParameter(APPLICATION_KEY))) { + return false; + } + + if (getParam() != null) { + for (ParamMatch match : param) { + if (!match.isMatch(url)) { + return false; + } + } + } + + return true; + } + + @Override + public String toString() { + return "ConditionMatch{" + + "address='" + address + '\'' + + ", service='" + service + '\'' + + ", app='" + app + '\'' + + ", param='" + param + '\'' + + '}'; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfigItem.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfigItem.java index 9f9aadc083..249baeb556 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfigItem.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfigItem.java @@ -16,14 +16,22 @@ */ package org.apache.dubbo.rpc.cluster.configurator.parser.model; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.PojoUtils; + import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_RECEIVE_RULE; + /** * */ public class ConfigItem { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ConfigItem.class); + public static final String GENERAL_TYPE = "general"; public static final String WEIGHT_TYPE = "weight"; public static final String BALANCING_TYPE = "balancing"; @@ -35,6 +43,7 @@ public class ConfigItem { public static final String SERVICES_KEY = "services"; public static final String APPLICATIONS_KEY = "applications"; public static final String PARAMETERS_KEY = "parameters"; + public static final String MATCH_KEY = "match"; public static final String SIDE_KEY = "side"; private String type; @@ -44,6 +53,7 @@ public class ConfigItem { private List services; private List applications; private Map parameters; + private ConditionMatch match; private String side; @SuppressWarnings("unchecked") @@ -77,14 +87,24 @@ public class ConfigItem { Object applications = map.get(APPLICATIONS_KEY); if (applications != null && List.class.isAssignableFrom(applications.getClass())) { configItem.setApplications(((List) applications).stream() - .map(String::valueOf).collect(Collectors.toList())); + .map(String::valueOf).collect(Collectors.toList())); } Object parameters = map.get(PARAMETERS_KEY); if (parameters != null && Map.class.isAssignableFrom(parameters.getClass())) { configItem.setParameters(((Map) parameters).entrySet() - .stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().toString()))); + .stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().toString()))); } + + try { + Object match = map.get(MATCH_KEY); + if (match != null && Map.class.isAssignableFrom(match.getClass())) { + configItem.setMatch(PojoUtils.mapToPojo((Map) match, ConditionMatch.class)); + } + } catch (Throwable t) { + logger.error(CLUSTER_FAILED_RECEIVE_RULE, " Failed to parse dynamic configuration rule", String.valueOf(map.get(MATCH_KEY)), "Error occurred when parsing rule component.", t); + } + configItem.setSide((String) map.get(SIDE_KEY)); return configItem; } @@ -152,4 +172,12 @@ public class ConfigItem { public void setSide(String side) { this.side = side; } + + public ConditionMatch getMatch() { + return match; + } + + public void setMatch(ConditionMatch match) { + this.match = match; + } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfiguratorConfig.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfiguratorConfig.java index d944074624..4a9c8e13a1 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfiguratorConfig.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ConfiguratorConfig.java @@ -24,6 +24,7 @@ import java.util.stream.Collectors; * */ public class ConfiguratorConfig { + public static final String MATCH_CONDITION = "MATCH_CONDITION"; public static final String SCOPE_SERVICE = "service"; public static final String SCOPE_APPLICATION = "application"; public static final String CONFIG_VERSION_KEY = "configVersion"; diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ParamMatch.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ParamMatch.java new file mode 100644 index 0000000000..0f1501cb69 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/model/ParamMatch.java @@ -0,0 +1,58 @@ +/* + * 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.configurator.parser.model; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match.StringMatch; + +public class ParamMatch { + private String key; + private StringMatch value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public StringMatch getValue() { + return value; + } + + public void setValue(StringMatch value) { + this.value = value; + } + + public boolean isMatch(URL url) { + if (key == null) { + return false; + } + + String input = url.getParameter(key); + return input != null && value.isMatch(input); + } + + @Override + public String toString() { + return "ParamMatch{" + + "key='" + key + '\'' + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java index ea65984e8c..3ed98cf0f4 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouterRule.java @@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.router; import java.util.Map; +import static org.apache.dubbo.rpc.cluster.Constants.CONFIG_VERSION_KEY; import static org.apache.dubbo.rpc.cluster.Constants.DYNAMIC_KEY; import static org.apache.dubbo.rpc.cluster.Constants.ENABLED_KEY; import static org.apache.dubbo.rpc.cluster.Constants.FORCE_KEY; @@ -40,6 +41,7 @@ public abstract class AbstractRouterRule { private int priority; private boolean dynamic = false; + private String version; private String scope; private String key; @@ -78,6 +80,7 @@ public abstract class AbstractRouterRule { setScope((String) map.get(SCOPE_KEY)); setKey((String) map.get(KEY_KEY)); + setVersion((String) map.get(CONFIG_VERSION_KEY)); } public String getRawRule() { @@ -151,4 +154,12 @@ public abstract class AbstractRouterRule { public void setKey(String key) { this.key = key; } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouter.java index be4774e429..ddbb1966e6 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouter.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouter.java @@ -23,58 +23,68 @@ import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.Holder; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.common.utils.UrlUtils; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.cluster.Constants; import org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode; -import org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouter; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcher; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern; import org.apache.dubbo.rpc.cluster.router.state.AbstractStateRouter; import org.apache.dubbo.rpc.cluster.router.state.BitList; import java.text.ParseException; import java.util.HashMap; -import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_CONDITIONAL_ROUTE_LIST_EMPTY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_EXEC_CONDITION_ROUTER; -import static org.apache.dubbo.rpc.cluster.Constants.ADDRESS_KEY; import static org.apache.dubbo.rpc.cluster.Constants.FORCE_KEY; import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY; import static org.apache.dubbo.rpc.cluster.Constants.RUNTIME_KEY; /** - * ConditionRouter - * It supports the conditional routing configured by "override://", in 2.6.x, - * refer to https://dubbo.apache.org/en/docs/v2.7/user/examples/routing-rule/ . - * For 2.7.x and later, please refer to {@link org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouter} - * and {@link AppStateRouter} - * refer to https://dubbo.apache.org/zh/docs/v2.7/user/examples/routing-rule/ . + * Condition Router directs traffics matching the 'when condition' to a particular address subset determined by the 'then condition'. + * One typical condition rule is like below, with + * 1. the 'when condition' on the left side of '=>' contains matching rule like 'method=sayHello' and 'method=sayHi' + * 2. the 'then condition' on the right side of '=>' contains matching rule like 'region=hangzhou' and 'address=*:20881' + *

+ * By default, condition router support matching rules like 'foo=bar', 'foo=bar*', 'arguments[0]=bar', 'attachments[foo]=bar', 'attachments[foo]=1~100', etc. + * It's also very easy to add customized matching rules by extending {@link ConditionMatcherFactory} + * and {@link ValuePattern} + *

+ * --- + * scope: service + * force: true + * runtime: true + * enabled: true + * key: org.apache.dubbo.samples.governance.api.DemoService + * conditions: + * - method=sayHello => region=hangzhou + * - method=sayHi => address=*:20881 + * ... */ public class ConditionStateRouter extends AbstractStateRouter { public static final String NAME = "condition"; private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AbstractStateRouter.class); protected static final Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)"); - protected static Pattern ARGUMENTS_PATTERN = Pattern.compile("arguments\\[([0-9]+)\\]"); - protected Map whenCondition; - protected Map thenCondition; + protected Map whenCondition; + protected Map thenCondition; + protected List matcherFactories; - private boolean enabled; + private final boolean enabled; public ConditionStateRouter(URL url, String rule, boolean force, boolean enabled) { super(url); this.setForce(force); this.enabled = enabled; + matcherFactories = moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions(); if (enabled) { this.init(rule); } @@ -84,6 +94,7 @@ public class ConditionStateRouter extends AbstractStateRouter { super(url); this.setUrl(url); this.setForce(url.getParameter(FORCE_KEY, false)); + matcherFactories = moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions(); this.enabled = url.getParameter(ENABLED_KEY, true); if (enabled) { init(url.getParameterAndDecoded(RULE_KEY)); @@ -99,8 +110,8 @@ public class ConditionStateRouter extends AbstractStateRouter { int i = rule.indexOf("=>"); String whenRule = i < 0 ? null : rule.substring(0, i).trim(); String thenRule = i < 0 ? rule.trim() : rule.substring(i + 2).trim(); - Map when = StringUtils.isBlank(whenRule) || "true".equals(whenRule) ? new HashMap() : parseRule(whenRule); - Map then = StringUtils.isBlank(thenRule) || "false".equals(thenRule) ? null : parseRule(thenRule); + Map when = StringUtils.isBlank(whenRule) || "true".equals(whenRule) ? new HashMap<>() : parseRule(whenRule); + Map then = StringUtils.isBlank(thenRule) || "false".equals(thenRule) ? null : parseRule(thenRule); // NOTE: It should be determined on the business level whether the `When condition` can be empty or not. this.whenCondition = when; this.thenCondition = then; @@ -109,14 +120,14 @@ public class ConditionStateRouter extends AbstractStateRouter { } } - private static Map parseRule(String rule) - throws ParseException { - Map condition = new HashMap(); + private Map parseRule(String rule) + throws ParseException { + Map condition = new HashMap<>(); if (StringUtils.isBlank(rule)) { return condition; } // Key-Value pair, stores both match and mismatch conditions - MatchPair pair = null; + ConditionMatcher matcherPair = null; // Multiple values Set values = null; final Matcher matcher = ROUTE_PATTERN.matcher(rule); @@ -125,40 +136,40 @@ public class ConditionStateRouter extends AbstractStateRouter { String content = matcher.group(2); // Start part of the condition expression. if (StringUtils.isEmpty(separator)) { - pair = new MatchPair(); - condition.put(content, pair); + matcherPair = this.getMatcher(content); + condition.put(content, matcherPair); } // The KV part of the condition expression else if ("&".equals(separator)) { if (condition.get(content) == null) { - pair = new MatchPair(); - condition.put(content, pair); + matcherPair = this.getMatcher(content); + condition.put(content, matcherPair); } else { - pair = condition.get(content); + matcherPair = condition.get(content); } } // The Value in the KV part. else if ("=".equals(separator)) { - if (pair == null) { + if (matcherPair == null) { throw new ParseException("Illegal route rule \"" - + rule + "\", The error char '" + separator - + "' at index " + matcher.start() + " before \"" - + content + "\".", matcher.start()); + + rule + "\", The error char '" + separator + + "' at index " + matcher.start() + " before \"" + + content + "\".", matcher.start()); } - values = pair.matches; + values = matcherPair.getMatches(); values.add(content); } // The Value in the KV part. else if ("!=".equals(separator)) { - if (pair == null) { + if (matcherPair == null) { throw new ParseException("Illegal route rule \"" - + rule + "\", The error char '" + separator - + "' at index " + matcher.start() + " before \"" - + content + "\".", matcher.start()); + + rule + "\", The error char '" + separator + + "' at index " + matcher.start() + " before \"" + + content + "\".", matcher.start()); } - values = pair.mismatches; + values = matcherPair.getMismatches(); values.add(content); } // The Value in the KV part, if Value have more than one items. @@ -240,135 +251,39 @@ public class ConditionStateRouter extends AbstractStateRouter { return this.getUrl().getParameter(RUNTIME_KEY, false); } + private ConditionMatcher getMatcher(String key) { + for (ConditionMatcherFactory factory : matcherFactories) { + if (factory.shouldMatch(key)) { + return factory.createMatcher(key, moduleModel); + } + } + return moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getExtension("param").createMatcher(key, moduleModel); + } + boolean matchWhen(URL url, Invocation invocation) { - return CollectionUtils.isEmptyMap(whenCondition) || matchCondition(whenCondition, url, null, invocation); + if (CollectionUtils.isEmptyMap(whenCondition)) { + return true; + } + + return doMatch(url, null, invocation, whenCondition, true); } private boolean matchThen(URL url, URL param) { - return CollectionUtils.isNotEmptyMap(thenCondition) && matchCondition(thenCondition, url, param, null); - } - - private boolean matchCondition(Map condition, URL url, URL param, Invocation invocation) { - Map sample = url.toMap(); - boolean result = false; - for (Map.Entry matchPair : condition.entrySet()) { - String key = matchPair.getKey(); - - if (key.startsWith(Constants.ARGUMENTS)) { - if (!matchArguments(matchPair, invocation)) { - return false; - } else { - result = true; - continue; - } - } - - String sampleValue; - //get real invoked method name from invocation - if (invocation != null && (METHOD_KEY.equals(key) || METHODS_KEY.equals(key))) { - sampleValue = invocation.getMethodName(); - } else if (ADDRESS_KEY.equals(key)) { - sampleValue = url.getAddress(); - } else if (HOST_KEY.equals(key)) { - sampleValue = url.getHost(); - } else { - sampleValue = sample.get(key); - } - if (sampleValue != null) { - if (!matchPair.getValue().isMatch(sampleValue, param)) { - return false; - } else { - result = true; - } - } else { - //not pass the condition - if (!matchPair.getValue().matches.isEmpty()) { - return false; - } else { - result = true; - } - } - } - return result; - } - - /** - * analysis the arguments in the rule. - * Examples would be like this: - * "arguments[0]=1", whenCondition is that the first argument is equal to '1'. - * "arguments[1]=a", whenCondition is that the second argument is equal to 'a'. - * @param matchPair - * @param invocation - * @return - */ - public boolean matchArguments(Map.Entry matchPair, Invocation invocation) { - try { - // split the rule - String key = matchPair.getKey(); - String[] expressArray = key.split("\\."); - String argumentExpress = expressArray[0]; - final Matcher matcher = ARGUMENTS_PATTERN.matcher(argumentExpress); - if (!matcher.find()) { - return false; - } - - //extract the argument index - int index = Integer.parseInt(matcher.group(1)); - if (index < 0 || index > invocation.getArguments().length) { - return false; - } - - //extract the argument value - Object object = invocation.getArguments()[index]; - - if (matchPair.getValue().isMatch(String.valueOf(object), null)) { - return true; - } - } catch (Exception e) { - logger.warn(CLUSTER_FAILED_EXEC_CONDITION_ROUTER,"condition state router arguments match failed","","Arguments match failed, matchPair[]" + matchPair + "] invocation[" + invocation + "]",e); - } - - return false; - } - - protected static final class MatchPair { - final Set matches = new HashSet(); - final Set mismatches = new HashSet(); - - private boolean isMatch(String value, URL param) { - if (!matches.isEmpty() && mismatches.isEmpty()) { - for (String match : matches) { - if (UrlUtils.isMatchGlobPattern(match, value, param)) { - return true; - } - } - return false; - } - - if (!mismatches.isEmpty() && matches.isEmpty()) { - for (String mismatch : mismatches) { - if (UrlUtils.isMatchGlobPattern(mismatch, value, param)) { - return false; - } - } - return true; - } - - if (!matches.isEmpty() && !mismatches.isEmpty()) { - //when both mismatches and matches contain the same value, then using mismatches first - for (String mismatch : mismatches) { - if (UrlUtils.isMatchGlobPattern(mismatch, value, param)) { - return false; - } - } - for (String match : matches) { - if (UrlUtils.isMatchGlobPattern(match, value, param)) { - return true; - } - } - return false; - } + if (CollectionUtils.isEmptyMap(thenCondition)) { return false; } + + return doMatch(url, param, null, thenCondition, false); + } + + private boolean doMatch(URL url, URL param, Invocation invocation, Map conditions, boolean isWhenCondition) { + Map sample = url.toOriginalMap(); + for (Map.Entry entry : conditions.entrySet()) { + ConditionMatcher matchPair = entry.getValue(); + if (!matchPair.isMatch(sample, param, invocation, isWhenCondition)) { + return false; + } + } + return true; } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java index 2348a3e23c..3daf71104e 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java @@ -48,7 +48,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAIL */ public abstract class ListenableStateRouter extends AbstractStateRouter implements ConfigurationListener { public static final String NAME = "LISTENABLE_ROUTER"; - private static final String RULE_SUFFIX = ".condition-router"; + public static final String RULE_SUFFIX = ".condition-router"; private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class); private volatile ConditionRouterRule routerRule; diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java new file mode 100644 index 0000000000..470a4daf06 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java @@ -0,0 +1,77 @@ +/* + * 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.condition.config; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent; +import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.cluster.router.state.BitList; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_TAG_ROUTE_EMPTY; +import static org.apache.dubbo.common.utils.StringUtils.isEmpty; + +/** + * Application level router, "application.condition-router" + */ +public class ProviderAppStateRouter extends ListenableStateRouter { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class); + public static final String NAME = "PROVIDER_APP_ROUTER"; + private String application; + private String currentApplication; + + public ProviderAppStateRouter(URL url) { + super(url, url.getApplication()); + this.currentApplication = url.getApplication(); + } + + @Override + public void notify(BitList> invokers) { + if (CollectionUtils.isEmpty(invokers)) { + return; + } + + Invoker invoker = invokers.get(0); + URL url = invoker.getUrl(); + String providerApplication = url.getRemoteApplication(); + + // provider application is empty or equals with the current application + if (isEmpty(providerApplication) || providerApplication.equals(currentApplication)) { + logger.warn(CLUSTER_TAG_ROUTE_EMPTY, "condition router get providerApplication is empty, will not subscribe to provider app rules.", "", ""); + return; + } + + synchronized (this) { + if (!providerApplication.equals(application)) { + if (StringUtils.isNotEmpty(application)) { + this.getRuleRepository().removeListener(application + RULE_SUFFIX, this); + } + String key = providerApplication + RULE_SUFFIX; + this.getRuleRepository().addListener(key, this); + application = providerApplication; + String rawRule = this.getRuleRepository().getRule(key, DynamicConfiguration.DEFAULT_GROUP); + if (StringUtils.isNotEmpty(rawRule)) { + this.process(new ConfigChangedEvent(key, DynamicConfiguration.DEFAULT_GROUP, rawRule)); + } + } + } + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouterFactory.java new file mode 100644 index 0000000000..5b8a560f07 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouterFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.condition.config; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.cluster.router.state.CacheableStateRouterFactory; +import org.apache.dubbo.rpc.cluster.router.state.StateRouter; + +/** + * Tag router factory + */ +@Activate(order = 145) +public class ProviderAppStateRouterFactory extends CacheableStateRouterFactory { + + public static final String NAME = "provider-app"; + + @Override + protected StateRouter createRouter(Class interfaceClass, URL url) { + return new ProviderAppStateRouter<>(url); + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/AbstractConditionMatcher.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/AbstractConditionMatcher.java new file mode 100644 index 0000000000..1dc8310700 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/AbstractConditionMatcher.java @@ -0,0 +1,138 @@ +/* + * 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.condition.matcher; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern; +import org.apache.dubbo.rpc.model.ModuleModel; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_EXEC_CONDITION_ROUTER; + +/** + * The abstract implementation of ConditionMatcher, records the match and mismatch patterns of this matcher while at the same time + * provides the common match logics. + */ +public abstract class AbstractConditionMatcher implements ConditionMatcher { + public static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AbstractConditionMatcher.class); + public static final String DOES_NOT_FOUND_VALUE = "dubbo_internal_not_found_argument_condition_value"; + final Set matches = new HashSet<>(); + final Set mismatches = new HashSet<>(); + private final ModuleModel model; + private final List valueMatchers; + protected final String key; + + public AbstractConditionMatcher(String key, ModuleModel model) { + this.key = key; + this.model = model; + this.valueMatchers = model.getExtensionLoader(ValuePattern.class).getActivateExtensions(); + } + + public static String getSampleValueFromUrl(String conditionKey, Map sample, URL param, Invocation invocation) { + String sampleValue; + //get real invoked method name from invocation + if (invocation != null && (METHOD_KEY.equals(conditionKey) || METHODS_KEY.equals(conditionKey))) { + sampleValue = invocation.getMethodName(); + } else { + sampleValue = sample.get(conditionKey); + } + + return sampleValue; + } + + public boolean isMatch(Map sample, URL param, Invocation invocation, boolean isWhenCondition) { + String value = getValue(sample, param, invocation); + if (value == null) { + // if key does not present in whichever of url, invocation or attachment based on the matcher type, then return false. + return false; + } + + if (!matches.isEmpty() && mismatches.isEmpty()) { + for (String match : matches) { + if (doPatternMatch(match, value, param, invocation, isWhenCondition)) { + return true; + } + } + return false; + } + + if (!mismatches.isEmpty() && matches.isEmpty()) { + for (String mismatch : mismatches) { + if (doPatternMatch(mismatch, value, param, invocation, isWhenCondition)) { + return false; + } + } + return true; + } + + if (!matches.isEmpty() && !mismatches.isEmpty()) { + //when both mismatches and matches contain the same value, then using mismatches first + for (String mismatch : mismatches) { + if (doPatternMatch(mismatch, value, param, invocation, isWhenCondition)) { + return false; + } + } + for (String match : matches) { + if (doPatternMatch(match, value, param, invocation, isWhenCondition)) { + return true; + } + } + return false; + } + return false; + } + + @Override + public Set getMatches() { + return matches; + } + + @Override + public Set getMismatches() { + return mismatches; + } + + // range, equal or other methods + protected boolean doPatternMatch(String pattern, String value, URL url, Invocation invocation, boolean isWhenCondition) { + for (ValuePattern valueMatcher : valueMatchers) { + if (valueMatcher.shouldMatch(pattern)) { + return valueMatcher.match(pattern, value, url, invocation, isWhenCondition); + } + } + // this should never happen. + logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Executing condition rule value match expression error.", "pattern is " + pattern + ", value is " + value + ", condition type " + (isWhenCondition ? "when" : "then"), "There should at least has one ValueMatcher instance that applies to all patterns, will force to use wildcard matcher now."); + + ValuePattern paramValueMatcher = model.getExtensionLoader(ValuePattern.class).getExtension("wildcard"); + return paramValueMatcher.match(pattern, value, url, invocation, isWhenCondition); + } + + /** + * Used to get value from different places of the request context, for example, url, attachment and invocation. + * This makes condition rule possible to check values in any place of a request. + */ + protected abstract String getValue(Map sample, URL url, Invocation invocation); + +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcher.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcher.java new file mode 100644 index 0000000000..be3a55247a --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcher.java @@ -0,0 +1,61 @@ +/* + * 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.condition.matcher; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.Invocation; + +import java.util.Map; +import java.util.Set; + +/** + * ConditionMatcher represents a specific match condition of a condition rule. + *

+ * The following condition rule '=bar&arguments[0]=hello* => region=hangzhou' consists of three ConditionMatchers: + * 1. UrlParamConditionMatcher represented by 'foo=bar' + * 2. ArgumentsConditionMatcher represented by 'arguments[0]=hello*' + * 3. UrlParamConditionMatcher represented by 'region=hangzhou' + *

+ * It's easy to define your own matcher by extending {@link ConditionMatcherFactory} + */ +public interface ConditionMatcher { + + /** + * Determines if the patterns of this matcher matches with request context. + * + * @param sample request context in provider url + * @param param request context in consumer url + * @param invocation request context in invocation, typically, service, method, arguments and attachments + * @param isWhenCondition condition type + * @return the matching result + */ + boolean isMatch(Map sample, URL param, Invocation invocation, boolean isWhenCondition); + + /** + * match patterns extracted from when condition + * + * @return + */ + Set getMatches(); + + /** + * mismatch patterns extracted from then condition + * + * @return + */ + Set getMismatches(); +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcherFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcherFactory.java new file mode 100644 index 0000000000..9ee338a8e6 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/ConditionMatcherFactory.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.condition.matcher; + +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.rpc.model.ModuleModel; + +/** + * Factory of ConditionMatcher instances. + */ +@SPI +public interface ConditionMatcherFactory { + /** + * Check if the key is of the form of the current matcher type which this factory instance represents.. + * + * @param key the key of a particular form + * @return true if matches, otherwise false + */ + boolean shouldMatch(String key); + + /** + * Create a matcher instance for the key. + * + * @param key the key value conforms to a specific matcher specification + * @param model module model + * @return the specific matcher instance + */ + ConditionMatcher createMatcher(String key, ModuleModel model); +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcher.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcher.java new file mode 100644 index 0000000000..d66bff1f38 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcher.java @@ -0,0 +1,72 @@ +/* + * 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.condition.matcher.argument; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.AbstractConditionMatcher; +import org.apache.dubbo.rpc.model.ModuleModel; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_EXEC_CONDITION_ROUTER; + +/** + * analysis the arguments in the rule. + * Examples would be like this: + * "arguments[0]=1", whenCondition is that the first argument is equal to '1'. + * "arguments[1]=a", whenCondition is that the second argument is equal to 'a'. + */ +@Activate +public class ArgumentConditionMatcher extends AbstractConditionMatcher { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ArgumentConditionMatcher.class); + private static final Pattern ARGUMENTS_PATTERN = Pattern.compile("arguments\\[([0-9]+)\\]"); + + public ArgumentConditionMatcher(String key, ModuleModel model) { + super(key, model); + } + + @Override + public String getValue(Map sample, URL url, Invocation invocation) { + try { + // split the rule + String[] expressArray = key.split("\\."); + String argumentExpress = expressArray[0]; + final Matcher matcher = ARGUMENTS_PATTERN.matcher(argumentExpress); + if (!matcher.find()) { + return DOES_NOT_FOUND_VALUE; + } + + //extract the argument index + int index = Integer.parseInt(matcher.group(1)); + if (index < 0 || index > invocation.getArguments().length) { + return DOES_NOT_FOUND_VALUE; + } + + //extract the argument value + return String.valueOf(invocation.getArguments()[index]); + } catch (Exception e) { + logger.warn(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Parse argument match condition failed", "", "Invalid , will ignore., ", e); + } + return DOES_NOT_FOUND_VALUE; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcherFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcherFactory.java new file mode 100644 index 0000000000..c9fcf5fe58 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/argument/ArgumentConditionMatcherFactory.java @@ -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.condition.matcher.argument; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.cluster.Constants; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcher; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory; +import org.apache.dubbo.rpc.model.ModuleModel; + +@Activate(order = 300) +public class ArgumentConditionMatcherFactory implements ConditionMatcherFactory { + + @Override + public boolean shouldMatch(String key) { + return key.startsWith(Constants.ARGUMENTS); + } + + @Override + public ConditionMatcher createMatcher(String key, ModuleModel model) { + return new ArgumentConditionMatcher(key, model); + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcher.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcher.java new file mode 100644 index 0000000000..c7dc148100 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcher.java @@ -0,0 +1,76 @@ +/* + * 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.condition.matcher.attachment; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.AbstractConditionMatcher; +import org.apache.dubbo.rpc.model.ModuleModel; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_EXEC_CONDITION_ROUTER; + +/** + * analysis the arguments in the rule. + * Examples would be like this: + * "attachments[foo]=bar", whenCondition is that the attachment value of 'foo' is equal to 'bar'. + */ +@Activate +public class AttachmentConditionMatcher extends AbstractConditionMatcher { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AttachmentConditionMatcher.class); + private static final Pattern ATTACHMENTS_PATTERN = Pattern.compile("attachments\\[(.+)\\]"); + + public AttachmentConditionMatcher(String key, ModuleModel model) { + super(key, model); + } + + @Override + protected String getValue(Map sample, URL url, Invocation invocation) { + try { + // split the rule + String[] expressArray = key.split("\\."); + String argumentExpress = expressArray[0]; + final Matcher matcher = ATTACHMENTS_PATTERN.matcher(argumentExpress); + if (!matcher.find()) { + return DOES_NOT_FOUND_VALUE; + } + + //extract the argument index + String attachmentKey = matcher.group(1); + if (StringUtils.isEmpty(attachmentKey)) { + return DOES_NOT_FOUND_VALUE; + } + + //extract the argument value + return invocation.getAttachment(attachmentKey); + } catch (Exception e) { + logger.warn(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, + "condition state router attachment match failed", + "", + "Invalid match condition: " + key, + e); + } + return DOES_NOT_FOUND_VALUE; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcherFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcherFactory.java new file mode 100644 index 0000000000..186510304a --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/attachment/AttachmentConditionMatcherFactory.java @@ -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.condition.matcher.attachment; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcher; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory; +import org.apache.dubbo.rpc.model.ModuleModel; + +@Activate(order = 200) +public class AttachmentConditionMatcherFactory implements ConditionMatcherFactory { + private static final String ATTACHMENTS = "attachments"; + + @Override + public boolean shouldMatch(String key) { + return key.startsWith(ATTACHMENTS); + } + + @Override + public ConditionMatcher createMatcher(String key, ModuleModel model) { + return new AttachmentConditionMatcher(key, model); + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcher.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcher.java new file mode 100644 index 0000000000..b1a8d5ba58 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcher.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.condition.matcher.param; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.AbstractConditionMatcher; +import org.apache.dubbo.rpc.model.ModuleModel; + +import java.util.Map; + +/** + * This instance will be loaded separately to ensure it always gets executed as the last matcher. + * So we don't put Active annotation here. + */ +public class UrlParamConditionMatcher extends AbstractConditionMatcher { + + public UrlParamConditionMatcher(String key, ModuleModel model) { + super(key, model); + } + + @Override + protected String getValue(Map sample, URL url, Invocation invocation) { + return getSampleValueFromUrl(key, sample, url, invocation); + } + +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcherFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcherFactory.java new file mode 100644 index 0000000000..5c216f1743 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/param/UrlParamConditionMatcherFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.condition.matcher.param; + +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcher; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory; +import org.apache.dubbo.rpc.model.ModuleModel; + +// Make sure this is the last matcher being executed. +@Activate(order = Integer.MAX_VALUE) +public class UrlParamConditionMatcherFactory implements ConditionMatcherFactory { + @Override + public boolean shouldMatch(String key) { + return true; + } + + @Override + public ConditionMatcher createMatcher(String key, ModuleModel model) { + return new UrlParamConditionMatcher(key, model); + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/ValuePattern.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/ValuePattern.java new file mode 100644 index 0000000000..82c38a47eb --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/ValuePattern.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.rpc.Invocation; + +/** + * + */ +@SPI +public interface ValuePattern { + /** + * Is the input pattern of a specific form, for example, range pattern '1~100', wildcard pattern 'hello*', etc. + * + * @param pattern the match or mismatch pattern + * @return true or false + */ + boolean shouldMatch(String pattern); + + /** + * Is the pattern matches with the request context + * + * @param pattern pattern value extracted from condition rule + * @param value the real value extracted from request context + * @param url request context in consumer url + * @param invocation request context in invocation + * @param isWhenCondition condition type + * @return true if successfully match + */ + boolean match(String pattern, String value, URL url, Invocation invocation, boolean isWhenCondition); +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/range/RangeValuePattern.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/range/RangeValuePattern.java new file mode 100644 index 0000000000..f876b3b377 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/range/RangeValuePattern.java @@ -0,0 +1,84 @@ +/* + * 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.condition.matcher.pattern.range; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_EXEC_CONDITION_ROUTER; + +/** + * Matches with patterns like 'key=1~100', 'key=~100' or 'key=1~' + */ +@Activate(order = 100) +public class RangeValuePattern implements ValuePattern { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(RangeValuePattern.class); + + @Override + public boolean shouldMatch(String pattern) { + return pattern.contains("~"); + } + + @Override + public boolean match(String pattern, String value, URL url, Invocation invocation, boolean isWhenCondition) { + boolean defaultValue = !isWhenCondition; + try { + int intValue = StringUtils.parseInteger(value); + + String[] arr = pattern.split("~"); + if (arr.length < 2) { + logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "", "", "Invalid condition rule " + pattern + " or value " + value + ", will ignore."); + return defaultValue; + } + + String rawStart = arr[0]; + String rawEnd = arr[1]; + + if (StringUtils.isEmpty(rawStart) && StringUtils.isEmpty(rawEnd)) { + return defaultValue; + } + + if (StringUtils.isEmpty(rawStart)) { + int end = StringUtils.parseInteger(rawEnd); + if (intValue > end) { + return false; + } + } else if (StringUtils.isEmpty(rawEnd)) { + int start = StringUtils.parseInteger(rawStart); + if (intValue < start) { + return false; + } + } else { + int start = StringUtils.parseInteger(rawStart); + int end = StringUtils.parseInteger(rawEnd); + if (intValue < start || intValue > end) { + return false; + } + } + } catch (Exception e) { + logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Parse integer error", "", "Invalid condition rule " + pattern + " or value " + value + ", will ignore.", e); + return defaultValue; + } + + return true; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/wildcard/WildcardValuePattern.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/wildcard/WildcardValuePattern.java new file mode 100644 index 0000000000..d712ad77ff --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/matcher/pattern/wildcard/WildcardValuePattern.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.wildcard; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.utils.UrlUtils; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern; + +/** + * Matches with patterns like 'key=hello', 'key=hello*', 'key=*hello', 'key=h*o' or 'key=*' + *

+ * This pattern evaluator must be the last one being executed. + */ +@Activate(order = Integer.MAX_VALUE) +public class WildcardValuePattern implements ValuePattern { + @Override + public boolean shouldMatch(String key) { + return true; + } + + @Override + public boolean match(String pattern, String value, URL url, Invocation invocation, boolean isWhenCondition) { + return UrlUtils.isMatchGlobPattern(pattern, value, url); + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCache.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCache.java index 499a7ea256..097162e927 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCache.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCache.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.rpc.cluster.router.mesh.route; +import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.Invoker; @@ -109,7 +110,7 @@ public class MeshRuleCache { List> subsetInvokers = subsetMap.computeIfAbsent(subsetName, (k) -> new BitList<>(invokers.getOriginList(), true)); Map labels = subset.getLabels(); - if (containMapKeyValue(invoker.getUrl().getServiceParameters(protocolServiceKey), labels)) { + if (isLabelMatch(invoker.getUrl(), protocolServiceKey, labels)) { subsetInvokers.add(invoker); matched = true; } @@ -133,7 +134,7 @@ public class MeshRuleCache { return new MeshRuleCache<>(Collections.emptyList(), Collections.emptyMap(), Collections.emptyMap(), BitList.emptyList()); } - protected static boolean containMapKeyValue(Map originMap, Map inputMap) { + protected static boolean isLabelMatch(URL url, String protocolServiceKey, Map inputMap) { if (inputMap == null || inputMap.size() == 0) { return true; } @@ -142,7 +143,7 @@ public class MeshRuleCache { String key = entry.getKey(); String value = entry.getValue(); - String originMapValue = originMap.get(key); + String originMapValue = url.getOriginalServiceParameter(protocolServiceKey, key); if (!value.equals(originMapValue)) { return false; } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/AddressMatch.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/AddressMatch.java new file mode 100644 index 0000000000..b8fdc3b578 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/AddressMatch.java @@ -0,0 +1,80 @@ +/* + * 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.rule.virtualservice.match; + +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; + +import java.net.UnknownHostException; + +import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE; +import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_EXEC_CONDITION_ROUTER; +import static org.apache.dubbo.common.utils.NetUtils.matchIpExpression; +import static org.apache.dubbo.common.utils.UrlUtils.isMatchGlobPattern; + +public class AddressMatch { + public static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AddressMatch.class); + private String wildcard; + private String cird; + private String exact; + + public String getWildcard() { + return wildcard; + } + + public void setWildcard(String wildcard) { + this.wildcard = wildcard; + } + + public String getCird() { + return cird; + } + + public void setCird(String cird) { + this.cird = cird; + } + + public String getExact() { + return exact; + } + + public void setExact(String exact) { + this.exact = exact; + } + + public boolean isMatch(String input) { + if (getCird() != null && input != null) { + try { + return input.equals(getCird()) || matchIpExpression(getCird(), input); + } catch (UnknownHostException e) { + logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Executing routing rule match expression error.", "", String.format("Error trying to match cird formatted address %s with input %s in AddressMatch.", getCird(), input), e); + } + } + if (getWildcard() != null && input != null) { + if (ANYHOST_VALUE.equals(getWildcard()) || ANY_VALUE.equals(getWildcard())) { + return true; + } + // FIXME + return isMatchGlobPattern(getWildcard(), input); + } + if (getExact() != null && input != null) { + return input.equals(getExact()); + } + return false; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/StringMatch.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/StringMatch.java index cffe11ca1b..dda2de7df3 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/StringMatch.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mesh/rule/virtualservice/match/StringMatch.java @@ -18,12 +18,15 @@ package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match; +import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE; + public class StringMatch { private String exact; private String prefix; private String regex; private String noempty; private String empty; + private String wildcard; public String getExact() { @@ -66,6 +69,14 @@ public class StringMatch { this.empty = empty; } + public String getWildcard() { + return wildcard; + } + + public void setWildcard(String wildcard) { + this.wildcard = wildcard; + } + public boolean isMatch(String input) { if (getExact() != null && input != null) { return input.equals(getExact()); @@ -73,6 +84,9 @@ public class StringMatch { return input.startsWith(getPrefix()); } else if (getRegex() != null && input != null) { return input.matches(getRegex()); + } else if (getWildcard() != null && input != null) { + // only supports "*" + return input.equals(getWildcard()) || ANY_VALUE.equals(getWildcard()); } else if (getEmpty() != null) { return input == null || "".equals(input); } else if (getNoempty() != null) { @@ -82,7 +96,6 @@ public class StringMatch { } } - @Override public String toString() { return "StringMatch{" + diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptRouterFactory.java new file mode 100644 index 0000000000..52a2b3e693 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptRouterFactory.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.script.config; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.rpc.cluster.router.state.CacheableStateRouterFactory; +import org.apache.dubbo.rpc.cluster.router.state.StateRouter; + +@Activate(order = 200) +public class AppScriptRouterFactory extends CacheableStateRouterFactory { + public static final String NAME = "script"; + + @Override + protected StateRouter createRouter(Class interfaceClass, URL url) { + return new AppScriptStateRouter<>(url); + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouter.java new file mode 100644 index 0000000000..8b158e31fd --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouter.java @@ -0,0 +1,150 @@ +/* + * 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.script.config; + +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.ConfigurationListener; +import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.common.utils.Holder; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.cluster.router.RouterSnapshotNode; +import org.apache.dubbo.rpc.cluster.router.script.ScriptStateRouter; +import org.apache.dubbo.rpc.cluster.router.script.config.model.ScriptRule; +import org.apache.dubbo.rpc.cluster.router.state.AbstractStateRouter; +import org.apache.dubbo.rpc.cluster.router.state.BitList; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_TAG_ROUTE_EMPTY; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_TAG_ROUTE_INVALID; +import static org.apache.dubbo.common.utils.StringUtils.isEmpty; +import static org.apache.dubbo.rpc.cluster.Constants.DEFAULT_SCRIPT_TYPE_KEY; +import static org.apache.dubbo.rpc.cluster.Constants.FORCE_KEY; +import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY; +import static org.apache.dubbo.rpc.cluster.Constants.RUNTIME_KEY; +import static org.apache.dubbo.rpc.cluster.Constants.TYPE_KEY; + +public class AppScriptStateRouter extends AbstractStateRouter implements ConfigurationListener { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AppScriptStateRouter.class); + private static final String RULE_SUFFIX = ".script-router"; + + private ScriptRule scriptRule; + private ScriptStateRouter scriptRouter; + private String application; + + public AppScriptStateRouter(URL url) { + super(url); + } + + @Override + protected BitList> doRoute(BitList> invokers, + URL url, + Invocation invocation, + boolean needToPrintMessage, + Holder> routerSnapshotNodeHolder, + Holder messageHolder) throws RpcException { + if (scriptRouter == null || !scriptRule.isValid() || !scriptRule.isEnabled()) { + if (needToPrintMessage) { + messageHolder.set("Directly return from script router. Reason: Invokers from previous router is empty or script is not enabled. Script rule is: " + (scriptRule == null ? "null" : scriptRule.getRawRule())); + } + return invokers; + } + + invokers = scriptRouter.route(invokers, url, invocation, needToPrintMessage, routerSnapshotNodeHolder); + + if (needToPrintMessage) { + messageHolder.set(messageHolder.get()); + } + + return invokers; + } + + @Override + public synchronized void process(ConfigChangedEvent event) { + if (logger.isDebugEnabled()) { + logger.debug("Notification of script rule change, type is: " + event.getChangeType() + ", raw rule is:\n " + + event.getContent()); + } + + try { + if (event.getChangeType().equals(ConfigChangeType.DELETED)) { + this.scriptRule = null; + } else { + this.scriptRule = ScriptRule.parse(event.getContent()); + URL scriptUrl = getUrl() + .addParameter(TYPE_KEY, isEmpty(scriptRule.getType()) ? DEFAULT_SCRIPT_TYPE_KEY : scriptRule.getType()) + .addParameterAndEncoded(RULE_KEY, scriptRule.getScript()) + .addParameter(FORCE_KEY, scriptRule.isForce()) + .addParameter(RUNTIME_KEY, scriptRule.isRuntime()); + scriptRouter = new ScriptStateRouter<>(scriptUrl); + } + } catch (Exception e) { + logger.error(CLUSTER_TAG_ROUTE_INVALID, "Failed to parse the raw tag router rule", "", "Failed to parse the raw tag router rule and it will not take effect, please check if the " + + "rule matches with the template, the raw rule is:\n ", e); + } + } + + @Override + public void notify(BitList> invokers) { + if (CollectionUtils.isEmpty(invokers)) { + return; + } + + Invoker invoker = invokers.get(0); + URL url = invoker.getUrl(); + String providerApplication = url.getRemoteApplication(); + + if (isEmpty(providerApplication)) { + logger.error(CLUSTER_TAG_ROUTE_EMPTY, "tag router get providerApplication is empty", "", "TagRouter must getConfig from or subscribe to a specific application, but the application " + + "in this TagRouter is not specified."); + return; + } + + synchronized (this) { + if (!providerApplication.equals(application)) { + if (StringUtils.isNotEmpty(application)) { + this.getRuleRepository().removeListener(application + RULE_SUFFIX, this); + } + String key = providerApplication + RULE_SUFFIX; + this.getRuleRepository().addListener(key, this); + application = providerApplication; + String rawRule = this.getRuleRepository().getRule(key, DynamicConfiguration.DEFAULT_GROUP); + if (StringUtils.isNotEmpty(rawRule)) { + this.process(new ConfigChangedEvent(key, DynamicConfiguration.DEFAULT_GROUP, rawRule)); + } + } + } + } + + @Override + public void stop() { + if (StringUtils.isNotEmpty(application)) { + this.getRuleRepository().removeListener(application + RULE_SUFFIX, this); + } + } + + // for testing purpose + public void setScriptRule(ScriptRule scriptRule) { + this.scriptRule = scriptRule; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/model/ScriptRule.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/model/ScriptRule.java new file mode 100644 index 0000000000..5ebf7217ee --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/config/model/ScriptRule.java @@ -0,0 +1,70 @@ +/* + * 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.script.config.model; + +import org.apache.dubbo.rpc.cluster.router.AbstractRouterRule; + +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; + +import java.util.Map; + +public class ScriptRule extends AbstractRouterRule { + private static final String TYPE_KEY = "type"; + private static final String SCRIPT_KEY = "script"; + private String type; + private String script; + + public static ScriptRule parse(String rawRule) { + Yaml yaml = new Yaml(new SafeConstructor()); + Map map = yaml.load(rawRule); + + ScriptRule rule = new ScriptRule(); + rule.parseFromMap0(map); + rule.setRawRule(rawRule); + + Object rawType = map.get(TYPE_KEY); + if (rawType != null) { + rule.setType((String) rawType); + } + + Object rawScript = map.get(SCRIPT_KEY); + if (rawScript != null) { + rule.setScript((String) rawScript); + } else { + rule.setValid(false); + } + + return rule; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getScript() { + return script; + } + + public void setScript(String script) { + this.script = script; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java index 2da97cb2e1..2b25ed5564 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/AbstractStateRouter.java @@ -43,8 +43,10 @@ public abstract class AbstractStateRouter implements StateRouter { */ private final boolean shouldFailFast; + protected ModuleModel moduleModel; + public AbstractStateRouter(URL url) { - ModuleModel moduleModel = url.getOrDefaultModuleModel(); + moduleModel = url.getOrDefaultModuleModel(); this.ruleRepository = moduleModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension(); this.url = url; this.shouldFailFast = Boolean.parseBoolean(ConfigurationUtils.getProperty(moduleModel, Constants.SHOULD_FAIL_FAST_KEY, "true")); diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouter.java index 20aee26407..5b8f9519ea 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouter.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouter.java @@ -36,7 +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.List; +import java.util.Set; import java.util.function.Predicate; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE; @@ -53,8 +53,9 @@ public class TagStateRouter extends AbstractStateRouter implements Configu private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(TagStateRouter.class); private static final String RULE_SUFFIX = ".tag-router"; - private TagRouterRule tagRouterRule; + private volatile TagRouterRule tagRouterRule; private String application; + private volatile BitList> invokers = BitList.emptyList(); public TagStateRouter(URL url) { super(url); @@ -71,7 +72,9 @@ public class TagStateRouter extends AbstractStateRouter implements Configu if (event.getChangeType().equals(ConfigChangeType.DELETED)) { this.tagRouterRule = null; } else { - this.tagRouterRule = TagRuleParser.parse(event.getContent()); + TagRouterRule rule = TagRuleParser.parse(event.getContent()); + rule.init(this); + this.tagRouterRule = rule; } } catch (Exception e) { logger.error(CLUSTER_TAG_ROUTE_INVALID,"Failed to parse the raw tag router rule","","Failed to parse the raw tag router rule and it will not take effect, please check if the " + @@ -103,9 +106,9 @@ public class TagStateRouter extends AbstractStateRouter implements Configu // if we are requesting for a Provider with a specific tag if (StringUtils.isNotEmpty(tag)) { - List addresses = tagRouterRuleCopy.getTagnameToAddresses().get(tag); + Set addresses = tagRouterRuleCopy.getTagnameToAddresses().get(tag); // filter by dynamic tag group first - if (CollectionUtils.isNotEmpty(addresses)) { + if (addresses != null) { // null means tag not set result = filterInvoker(invokers, invoker -> addressMatches(invoker.getUrl(), addresses)); // if result is not null OR it's null but force=true, return result directly if (CollectionUtils.isNotEmpty(result) || tagRouterRuleCopy.isForce()) { @@ -129,8 +132,10 @@ public class TagStateRouter extends AbstractStateRouter implements Configu } // FAILOVER: return all Providers without any tags. else { - BitList> tmp = filterInvoker(invokers, invoker -> addressNotMatches(invoker.getUrl(), - tagRouterRuleCopy.getAddresses())); + BitList> tmp = filterInvoker( + invokers, + invoker -> addressNotMatches(invoker.getUrl(), tagRouterRuleCopy.getAddresses()) + ); if (needToPrintMessage) { messageHolder.set("FAILOVER: return all Providers without any tags"); } @@ -139,7 +144,7 @@ public class TagStateRouter extends AbstractStateRouter implements Configu } else { // List addresses = tagRouterRule.filter(providerApp); // return all addresses in dynamic tag group. - List addresses = tagRouterRuleCopy.getAddresses(); + Set addresses = tagRouterRuleCopy.getAddresses(); if (CollectionUtils.isNotEmpty(addresses)) { result = filterInvoker(invokers, invoker -> addressNotMatches(invoker.getUrl(), addresses)); // 1. all addresses are in dynamic tag group, return empty list. @@ -157,7 +162,7 @@ public class TagStateRouter extends AbstractStateRouter implements Configu } return filterInvoker(result, invoker -> { String localTag = invoker.getUrl().getParameter(TAG_KEY); - return StringUtils.isEmpty(localTag) || !tagRouterRuleCopy.getTagNames().contains(localTag); + return StringUtils.isEmpty(localTag); }); } } @@ -219,15 +224,15 @@ public class TagStateRouter extends AbstractStateRouter implements Configu return newInvokers; } - private boolean addressMatches(URL url, List addresses) { + private boolean addressMatches(URL url, Set addresses) { return addresses != null && checkAddressMatch(addresses, url.getHost(), url.getPort()); } - private boolean addressNotMatches(URL url, List addresses) { + private boolean addressNotMatches(URL url, Set addresses) { return addresses == null || !checkAddressMatch(addresses, url.getHost(), url.getPort()); } - private boolean checkAddressMatch(List addresses, String host, int port) { + private boolean checkAddressMatch(Set addresses, String host, int port) { for (String address : addresses) { try { if (NetUtils.matchIpExpression(address, host, port)) { @@ -237,7 +242,7 @@ public class TagStateRouter extends AbstractStateRouter implements Configu return true; } } catch (Exception e) { - logger.error(CLUSTER_TAG_ROUTE_INVALID,"tag route address is invalid","","The format of ip address is invalid in tag route. Address :" + address,e); + logger.error(CLUSTER_TAG_ROUTE_INVALID, "tag route address is invalid", "", "The format of ip address is invalid in tag route. Address :" + address, e); } } return false; @@ -249,6 +254,7 @@ public class TagStateRouter extends AbstractStateRouter implements Configu @Override public void notify(BitList> invokers) { + this.invokers = invokers; if (CollectionUtils.isEmpty(invokers)) { return; } @@ -275,14 +281,29 @@ public class TagStateRouter extends AbstractStateRouter implements Configu if (StringUtils.isNotEmpty(rawRule)) { this.process(new ConfigChangedEvent(key, DynamicConfiguration.DEFAULT_GROUP, rawRule)); } + } else { + if (this.tagRouterRule != null) { + TagRouterRule newRule = TagRuleParser.parse(this.tagRouterRule.getRawRule()); + newRule.init(this); + this.tagRouterRule = newRule; + } } } } + public BitList> getInvokers() { + return invokers; + } + @Override public void stop() { if (StringUtils.isNotEmpty(application)) { this.getRuleRepository().removeListener(application + RULE_SUFFIX, this); } } + + // for testing purpose + public void setTagRouterRule(TagRouterRule tagRouterRule) { + this.tagRouterRule = tagRouterRule; + } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/ParamMatch.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/ParamMatch.java new file mode 100644 index 0000000000..bef3366e83 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/ParamMatch.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.cluster.router.tag.model; + +import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match.StringMatch; + +public class ParamMatch { + private String key; + private StringMatch value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public StringMatch getValue() { + return value; + } + + public void setValue(StringMatch value) { + this.value = value; + } + + public boolean isMatch(String input) { + if (getValue() != null && input != null) { + return getValue().isMatch(input); + } + return false; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/Tag.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/Tag.java index 706384c3a4..13c94d7911 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/Tag.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/Tag.java @@ -16,19 +16,44 @@ */ package org.apache.dubbo.rpc.cluster.router.tag.model; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.PojoUtils; + import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_RULE_PARSING; +import static org.apache.dubbo.rpc.cluster.Constants.RULE_VERSION_V30; + public class Tag { + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(Tag.class); + private String name; + private List match; private List addresses; @SuppressWarnings("unchecked") - public static Tag parseFromMap(Map map) { + public static Tag parseFromMap(Map map, String version) { Tag tag = new Tag(); tag.setName((String) map.get("name")); + if (version != null && version.startsWith(RULE_VERSION_V30)) { + if (map.get("match") != null) { + tag.setMatch(((List>) map.get("match")).stream().map((objectMap) -> { + try { + return PojoUtils.mapToPojo(objectMap, ParamMatch.class); + } catch (ReflectiveOperationException e) { + logger.error(CLUSTER_FAILED_RULE_PARSING, " Failed to parse tag rule ", String.valueOf(objectMap), "Error occurred when parsing rule component.", e); + } + return null; + }).collect(Collectors.toList())); + } else { + logger.warn(CLUSTER_FAILED_RULE_PARSING, "", String.valueOf(map), "It's recommended to use 'match' instead of 'addresses' for v3.0 tag rule."); + } + } + Object addresses = map.get("addresses"); if (addresses != null && List.class.isAssignableFrom(addresses.getClass())) { tag.setAddresses(((List) addresses).stream().map(String::valueOf).collect(Collectors.toList())); @@ -52,4 +77,13 @@ public class Tag { public void setAddresses(List addresses) { this.addresses = addresses; } + + public List getMatch() { + return match; + } + + public void setMatch(List match) { + this.match = match; + } + } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRouterRule.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRouterRule.java index 113f172dd2..f938a7e800 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRouterRule.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRouterRule.java @@ -17,14 +17,19 @@ package org.apache.dubbo.rpc.cluster.router.tag.model; import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.cluster.router.AbstractRouterRule; +import org.apache.dubbo.rpc.cluster.router.state.BitList; +import org.apache.dubbo.rpc.cluster.router.tag.TagStateRouter; -import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; +import static org.apache.dubbo.rpc.cluster.Constants.RULE_VERSION_V30; import static org.apache.dubbo.rpc.cluster.Constants.TAGS_KEY; /** @@ -45,8 +50,8 @@ import static org.apache.dubbo.rpc.cluster.Constants.TAGS_KEY; public class TagRouterRule extends AbstractRouterRule { private List tags; - private final Map> addressToTagnames = new HashMap<>(); - private final Map> tagnameToAddresses = new HashMap<>(); + private final Map> addressToTagnames = new HashMap<>(); + private final Map> tagnameToAddresses = new HashMap<>(); @SuppressWarnings("unchecked") public static TagRouterRule parseFromMap(Map map) { @@ -56,43 +61,71 @@ public class TagRouterRule extends AbstractRouterRule { Object tags = map.get(TAGS_KEY); if (tags != null && List.class.isAssignableFrom(tags.getClass())) { tagRouterRule.setTags(((List>) tags).stream() - .map(Tag::parseFromMap).collect(Collectors.toList())); + .map(objMap -> Tag.parseFromMap(objMap, tagRouterRule.getVersion())).collect(Collectors.toList())); } return tagRouterRule; } - public void init() { + public void init(TagStateRouter router) { if (!isValid()) { return; } + BitList> invokers = router.getInvokers(); + + // for tags with 'addresses` field set and 'match' field not set tags.stream().filter(tag -> CollectionUtils.isNotEmpty(tag.getAddresses())).forEach(tag -> { - tagnameToAddresses.put(tag.getName(), tag.getAddresses()); + tagnameToAddresses.put(tag.getName(), new HashSet<>(tag.getAddresses())); tag.getAddresses().forEach(addr -> { - List tagNames = addressToTagnames.computeIfAbsent(addr, k -> new ArrayList<>()); + Set tagNames = addressToTagnames.computeIfAbsent(addr, k -> new HashSet<>()); tagNames.add(tag.getName()); }); }); + + if (this.getVersion() != null && this.getVersion().startsWith(RULE_VERSION_V30)) { + // for tags with 'match` field set and 'addresses' field not set + if (CollectionUtils.isNotEmpty(invokers)) { + tags.stream().filter(tag -> CollectionUtils.isEmpty(tag.getAddresses())).forEach(tag -> { + Set addresses = new HashSet<>(); + List paramMatchers = tag.getMatch(); + invokers.forEach(invoker -> { + boolean isMatch = true; + for (ParamMatch matcher : paramMatchers) { + if (!matcher.isMatch(invoker.getUrl().getOriginalParameter(matcher.getKey()))) { + isMatch = false; + break; + } + } + if (isMatch) { + addresses.add(invoker.getUrl().getAddress()); + } + }); + if (CollectionUtils.isNotEmpty(addresses)) {// null means tag not set + tagnameToAddresses.put(tag.getName(), addresses); + } + }); + } + } } - public List getAddresses() { - return tags.stream() - .filter(tag -> CollectionUtils.isNotEmpty(tag.getAddresses())) - .flatMap(tag -> tag.getAddresses().stream()) - .collect(Collectors.toList()); + public Set getAddresses() { + return tagnameToAddresses.entrySet().stream() + .filter(entry -> CollectionUtils.isNotEmpty(entry.getValue())) + .flatMap(entry -> entry.getValue().stream()) + .collect(Collectors.toSet()); } public List getTagNames() { return tags.stream().map(Tag::getName).collect(Collectors.toList()); } - public Map> getAddressToTagnames() { + public Map> getAddressToTagnames() { return addressToTagnames; } - public Map> getTagnameToAddresses() { + public Map> getTagnameToAddresses() { return tagnameToAddresses; } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRuleParser.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRuleParser.java index b4cda311c1..a83d2f5476 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRuleParser.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRuleParser.java @@ -24,7 +24,7 @@ import org.yaml.snakeyaml.constructor.SafeConstructor; import java.util.Map; /** - * + * Parse raw rule into structured tag rule */ public class TagRuleParser { @@ -37,7 +37,6 @@ public class TagRuleParser { rule.setValid(false); } - rule.init(); return rule; } } diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory new file mode 100644 index 0000000000..b900f5b9bf --- /dev/null +++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory @@ -0,0 +1,4 @@ +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 + diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern new file mode 100644 index 0000000000..796249e849 --- /dev/null +++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern @@ -0,0 +1,2 @@ +range=org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.range.RangeValuePattern +wildcard=org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.wildcard.WildcardValuePattern diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory index 90fbccde21..7c6f4b8ce1 100644 --- a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory +++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory @@ -2,5 +2,7 @@ tag=org.apache.dubbo.rpc.cluster.router.tag.TagStateRouterFactory 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 diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/RouterChainTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/RouterChainTest.java index 19409b6602..a905ca90bc 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/RouterChainTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/RouterChainTest.java @@ -59,7 +59,7 @@ class RouterChainTest { void testBuildRouterChain() { RouterChain routerChain = createRouterChanin(); Assertions.assertEquals(0, routerChain.getRouters().size()); - Assertions.assertEquals(5, routerChain.getStateRouters().size()); + Assertions.assertEquals(7, routerChain.getStateRouters().size()); } private RouterChain createRouterChanin() { @@ -158,14 +158,16 @@ class RouterChainTest { 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" + + "[ 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" + - " [ 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"; + " [ 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)); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfiguratorTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfiguratorTest.java index c05238ac67..ea139d0e04 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfiguratorTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/override/OverrideConfiguratorTest.java @@ -20,13 +20,19 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.rpc.cluster.configurator.absent.AbsentConfigurator; import org.apache.dubbo.rpc.cluster.configurator.consts.UrlConstant; +import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConditionMatch; +import org.apache.dubbo.rpc.cluster.configurator.parser.model.ParamMatch; +import org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match.StringMatch; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import static org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig.MATCH_CONDITION; + /** * OverrideConfiguratorTest */ @@ -80,6 +86,7 @@ class OverrideConfiguratorTest { params.put("configVersion", "2.7"); params.put("application", "foo"); params.put("timeout", "10000"); + consumerConfiguratorUrl = consumerConfiguratorUrl.addParameters(params); OverrideConfigurator configurator = new OverrideConfigurator(consumerConfiguratorUrl); @@ -114,4 +121,76 @@ class OverrideConfiguratorTest { } + // Test the version after 2.7 + @Test + void testOverrideForVersion3() { + // match + { + String consumerUrlV3 = "dubbo://172.24.160.179/com.foo.BarService?match_key=value&application=foo&side=consumer&timeout=100"; + + URL consumerConfiguratorUrl = URL.valueOf("override://0.0.0.0/com.foo.BarService"); + Map params = new HashMap<>(); + params.put("side", "consumer"); + params.put("configVersion", "v3.0"); + params.put("application", "foo"); + params.put("timeout", "10000"); + + ConditionMatch matcher = new ConditionMatch(); + ParamMatch paramMatch = new ParamMatch(); + paramMatch.setKey("match_key"); + StringMatch stringMatch = new StringMatch(); + stringMatch.setExact("value"); + paramMatch.setValue(stringMatch); + matcher.setParam(Arrays.asList(paramMatch)); + consumerConfiguratorUrl = consumerConfiguratorUrl.putAttribute(MATCH_CONDITION, matcher); + + consumerConfiguratorUrl = consumerConfiguratorUrl.addParameters(params); + + OverrideConfigurator configurator = new OverrideConfigurator(consumerConfiguratorUrl); + // Meet the configured conditions: + // same side + // The port of configuratorUrl is 0 + // The host of configuratorUrl is 0.0.0.0 or the local address is the same as consumerUrlV27 + // same appName + URL originalURL = URL.valueOf(consumerUrlV3); + Assertions.assertEquals("100", originalURL.getParameter("timeout")); + URL url = configurator.configure(originalURL); + Assertions.assertEquals("10000", url.getParameter("timeout")); + } + + // mismatch + { + String consumerUrlV3 = "dubbo://172.24.160.179/com.foo.BarService?match_key=value&application=foo&side=consumer&timeout=100"; + + URL consumerConfiguratorUrl = URL.valueOf("override://0.0.0.0/com.foo.BarService"); + Map params = new HashMap<>(); + params.put("side", "consumer"); + params.put("configVersion", "v3.0"); + params.put("application", "foo"); + params.put("timeout", "10000"); + + ConditionMatch matcher = new ConditionMatch(); + ParamMatch paramMatch = new ParamMatch(); + paramMatch.setKey("match_key"); + StringMatch stringMatch = new StringMatch(); + stringMatch.setExact("not_match_value"); + paramMatch.setValue(stringMatch); + matcher.setParam(Arrays.asList(paramMatch)); + consumerConfiguratorUrl = consumerConfiguratorUrl.putAttribute(MATCH_CONDITION, matcher); + + consumerConfiguratorUrl = consumerConfiguratorUrl.addParameters(params); + + OverrideConfigurator configurator = new OverrideConfigurator(consumerConfiguratorUrl); + // Meet the configured conditions: + // same side + // The port of configuratorUrl is 0 + // The host of configuratorUrl is 0.0.0.0 or the local address is the same as consumerUrlV27 + // same appName + URL originalURL = URL.valueOf(consumerUrlV3); + Assertions.assertEquals("100", originalURL.getParameter("timeout")); + URL url = configurator.configure(originalURL); + Assertions.assertEquals("100", url.getParameter("timeout")); + } + } + } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParserTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParserTest.java index 897d85ad9c..a7e50304c9 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParserTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParserTest.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.cluster.configurator.parser; import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConditionMatch; import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig; import org.junit.jupiter.api.Assertions; @@ -33,6 +34,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.rpc.cluster.Constants.OVERRIDE_PROVIDERS_KEY; import static org.apache.dubbo.rpc.cluster.Constants.WEIGHT_KEY; +import static org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig.MATCH_CONDITION; /** * @@ -165,6 +167,75 @@ class ConfigParserTest { } } + @Test + void parseProviderConfigurationV3() throws IOException { + try (InputStream yamlStream = this.getClass().getResourceAsStream("/ConfiguratorV3.yml")) { + List urls = ConfigParser.parseConfigurators(streamToString(yamlStream)); + Assertions.assertNotNull(urls); + Assertions.assertEquals(1, urls.size()); + URL url = urls.get(0); + Assertions.assertEquals("0.0.0.0", url.getAddress()); + Assertions.assertEquals("*", url.getServiceInterface()); + Assertions.assertEquals(200, url.getParameter(WEIGHT_KEY, 0)); + Assertions.assertEquals("demo-provider", url.getApplication()); + + URL matchURL1 = URL.valueOf("dubbo://10.0.0.1:20880/DemoService?match_key1=value1"); + URL matchURL2 = URL.valueOf("dubbo://10.0.0.1:20880/DemoService2?match_key1=value1"); + URL notMatchURL1 = URL.valueOf("dubbo://10.0.0.2:20880/DemoService?match_key1=value1");// address not match + URL notMatchURL2 = URL.valueOf("dubbo://10.0.0.1:20880/DemoServiceNotMatch?match_key1=value1");// service not match + URL notMatchURL3 = URL.valueOf("dubbo://10.0.0.1:20880/DemoService?match_key1=value_not_match");// key not match + + ConditionMatch matcher = (ConditionMatch) url.getAttribute(MATCH_CONDITION); + Assertions.assertTrue(matcher.isMatch(matchURL1)); + Assertions.assertTrue(matcher.isMatch(matchURL2)); + Assertions.assertFalse(matcher.isMatch(notMatchURL1)); + Assertions.assertFalse(matcher.isMatch(notMatchURL2)); + Assertions.assertFalse(matcher.isMatch(notMatchURL3)); + } + } + + @Test + void parseProviderConfigurationV3Compatibility() throws IOException { + try (InputStream yamlStream = this.getClass().getResourceAsStream("/ConfiguratorV3Compatibility.yml")) { + List urls = ConfigParser.parseConfigurators(streamToString(yamlStream)); + Assertions.assertNotNull(urls); + Assertions.assertEquals(1, urls.size()); + URL url = urls.get(0); + Assertions.assertEquals("10.0.0.1:20880", url.getAddress()); + Assertions.assertEquals("DemoService", url.getServiceInterface()); + Assertions.assertEquals(200, url.getParameter(WEIGHT_KEY, 0)); + Assertions.assertEquals("demo-provider", url.getApplication()); + + URL matchURL = URL.valueOf("dubbo://10.0.0.1:20880/DemoService?match_key1=value1"); + URL notMatchURL = URL.valueOf("dubbo://10.0.0.1:20880/DemoService?match_key1=value_not_match");// key not match + + ConditionMatch matcher = (ConditionMatch) url.getAttribute(MATCH_CONDITION); + Assertions.assertTrue(matcher.isMatch(matchURL)); + Assertions.assertFalse(matcher.isMatch(notMatchURL)); + } + } + + @Test + void parseProviderConfigurationV3Conflict() throws IOException { + try (InputStream yamlStream = this.getClass().getResourceAsStream("/ConfiguratorV3Duplicate.yml")) { + List urls = ConfigParser.parseConfigurators(streamToString(yamlStream)); + Assertions.assertNotNull(urls); + Assertions.assertEquals(1, urls.size()); + URL url = urls.get(0); + Assertions.assertEquals("10.0.0.1:20880", url.getAddress()); + Assertions.assertEquals("DemoService", url.getServiceInterface()); + Assertions.assertEquals(200, url.getParameter(WEIGHT_KEY, 0)); + Assertions.assertEquals("demo-provider", url.getApplication()); + + URL matchURL = URL.valueOf("dubbo://10.0.0.1:20880/DemoService?match_key1=value1"); + URL notMatchURL = URL.valueOf("dubbo://10.0.0.1:20880/DemoService?match_key1=value_not_match");// key not match + + ConditionMatch matcher = (ConditionMatch) url.getAttribute(MATCH_CONDITION); + Assertions.assertTrue(matcher.isMatch(matchURL)); + Assertions.assertFalse(matcher.isMatch(notMatchURL)); + } + } + @Test void parseURLJsonArrayCompatible() { diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/RouterSnapshotFilterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/RouterSnapshotFilterTest.java index 76a01d87eb..4dd245f1f3 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/RouterSnapshotFilterTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/RouterSnapshotFilterTest.java @@ -23,11 +23,17 @@ import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ServiceModel; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.Mockito; class RouterSnapshotFilterTest { + @BeforeAll + static void setUp() { + RpcContext.getServiceContext().setNeedPrintRouterSnapshot(false); + } + @Test void test() { FrameworkModel frameworkModel = new FrameworkModel(); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java index 0f01f0381d..4735e7970b 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouterTest.java @@ -369,4 +369,124 @@ class ConditionStateRouterTest { fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); Assertions.assertEquals(0, fileredInvokers.size()); } + + @Test + void testRoute_Attachments() { + StateRouter router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("attachments[foo] = a " + " => " + " host = 1.2.3.4").addParameter(FORCE_KEY, String.valueOf(true))); + List> originInvokers = new ArrayList<>(); + Invoker invoker1 = new MockInvoker<>(URL.valueOf("dubbo://10.20.3.3:20880/com.foo.BarService?region=hangzhou")); + Invoker invoker2 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + Invoker invoker3 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + originInvokers.add(invoker3); + BitList> invokers = new BitList<>(originInvokers); + + RpcInvocation invocation = new RpcInvocation(); + List> fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + + invocation.setAttachment("foo", "a"); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(0, fileredInvokers.size()); + + router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("attachments = a " + " => " + " host = 1.2.3.4").addParameter(FORCE_KEY, String.valueOf(true))); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + + router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("attachments[foo] = a " + " => " + " region = hangzhou").addParameter(FORCE_KEY, String.valueOf(true))); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(1, fileredInvokers.size()); + } + + @Test + void testRoute_Range_Pattern() { + StateRouter router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("attachments[user_id] = 1~100 " + " => " + " region=hangzhou").addParameter(FORCE_KEY, String.valueOf(true))); + List> originInvokers = new ArrayList<>(); + Invoker invoker1 = new MockInvoker<>(URL.valueOf("dubbo://10.20.3.3:20880/com.foo.BarService?region=hangzhou")); + Invoker invoker2 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + Invoker invoker3 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + originInvokers.add(invoker3); + BitList> invokers = new BitList<>(originInvokers); + + RpcInvocation invocation = new RpcInvocation(); + List> fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + + invocation.setAttachment("user_id", "80"); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(1, fileredInvokers.size()); + + invocation.setAttachment("user_id", "101"); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + + router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("attachments[user_id] = ~100 " + " => " + " region = hangzhou").addParameter(FORCE_KEY, String.valueOf(true))); + invocation.setAttachment("user_id", "1"); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(1, fileredInvokers.size()); + + router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("attachments[user_id] = ~100 " + " => " + " region = hangzhou").addParameter(FORCE_KEY, String.valueOf(true))); + invocation.setAttachment("user_id", "101"); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + + router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("attachments[user_id] = ~100 " + " => " + " region = hangzhou").addParameter(FORCE_KEY, String.valueOf(true))); + fileredInvokers = router.route(invokers.clone(), URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService"), invocation, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + } + + @Test + void testRoute_Key_Not_Exist() { + StateRouter router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("when_key=a " + " => " + " not_exist_then_key = any_value").addParameter(FORCE_KEY, String.valueOf(true))); + List> originInvokers = new ArrayList<>(); + Invoker invoker1 = new MockInvoker<>(URL.valueOf("dubbo://10.20.3.3:20880/com.foo.BarService?then_key=a")); + Invoker invoker2 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + Invoker invoker3 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + originInvokers.add(invoker3); + BitList> invokers = new BitList<>(originInvokers); + + URL consumer = URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService?when_key=a"); + + List> fileredInvokers = router.route(invokers.clone(), consumer, null, false, new Holder<>()); + Assertions.assertEquals(0, fileredInvokers.size()); + + router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("not_exist_when_key=a " + " => " + " then_key = a").addParameter(FORCE_KEY, String.valueOf(true))); + fileredInvokers = router.route(invokers, consumer, null, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + } + + @Test + void testRoute_Multiple_Conditions() { + List> originInvokers = new ArrayList<>(); + Invoker invoker1 = new MockInvoker<>(URL.valueOf("dubbo://10.20.3.3:20880/com.foo.BarService")); + Invoker invoker2 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + Invoker invoker3 = new MockInvoker<>(URL.valueOf("dubbo://" + LOCAL_HOST + ":20880/com.foo.BarService")); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + originInvokers.add(invoker3); + BitList> invokers = new BitList<>(originInvokers); + + + RpcInvocation invocation = new RpcInvocation(); + String p = "a"; + invocation.setArguments(new Object[]{p}); + + // all conditions match + URL consumer1 = URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService?application=consumer_app"); + StateRouter router = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("application=consumer_app&arguments[0]=a" + " => " + " host = " + LOCAL_HOST).addParameter(FORCE_KEY, String.valueOf(true))); + List> fileredInvokers = router.route(invokers.clone(), consumer1, invocation, false, new Holder<>()); + Assertions.assertEquals(2, fileredInvokers.size()); + + // one of the conditions does not match + URL consume2 = URL.valueOf("consumer://" + LOCAL_HOST + "/com.foo.BarService?application=another_consumer_app"); + StateRouter router2 = new ConditionStateRouterFactory().getRouter(String.class, getRouteUrl("application=consumer_app&arguments[0]=a" + " => " + " host = " + LOCAL_HOST).addParameter(FORCE_KEY, String.valueOf(true))); + fileredInvokers = router2.route(invokers.clone(), consume2, invocation, false, new Holder<>()); + Assertions.assertEquals(3, fileredInvokers.size()); + + } } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppConditionStateRouterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppConditionStateRouterTest.java new file mode 100644 index 0000000000..975a78bceb --- /dev/null +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppConditionStateRouterTest.java @@ -0,0 +1,97 @@ +/* + * 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.condition.config; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; +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.governance.GovernanceRuleRepository; +import org.apache.dubbo.rpc.cluster.router.MockInvoker; +import org.apache.dubbo.rpc.cluster.router.state.BitList; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.List; + +import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY; + +public class ProviderAppConditionStateRouterTest { + private static final String LOCAL_HOST = "127.0.0.1"; + private static final String RULE_SUFFIX = ".condition-router"; + + private static GovernanceRuleRepository ruleRepository; + private URL url = URL.valueOf("consumer://1.1.1.1/com.foo.BarService"); + private String rawRule = "---\n" + + "configVersion: v3.0\n" + + "scope: application\n" + + "force: true\n" + + "runtime: false\n" + + "enabled: true\n" + + "priority: 1\n" + + "key: demo-provider\n" + + "conditions:\n" + + "- method=sayHello => region=hangzhou\n" + + "..."; + + @BeforeAll + public static void setUpBeforeClass() throws Exception { + ruleRepository = Mockito.mock(GovernanceRuleRepository.class); + } + + @Test + void test() { + ProviderAppStateRouter router = new ProviderAppStateRouter<>(url); + router = Mockito.spy(router); + Mockito.when(router.getRuleRepository()).thenReturn(ruleRepository); + Mockito.when(ruleRepository.getRule("demo-provider" + RULE_SUFFIX, DynamicConfiguration.DEFAULT_GROUP)).thenReturn(rawRule); +// Mockito.when(ruleRepository.addListener()).thenReturn(); + + BitList> invokers = getInvokers(); + router.notify(invokers); + + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("sayHello"); + List> result = router.route(invokers.clone(), url, invocation, false, new Holder<>()); + Assertions.assertEquals(1, result.size()); + + invocation.setMethodName("sayHi"); + result = router.route(invokers.clone(), url, invocation, false, new Holder<>()); + Assertions.assertEquals(3, result.size()); + } + + private BitList> getInvokers() { + List> originInvokers = new ArrayList>(); + Invoker invoker1 = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?" + REMOTE_APPLICATION_KEY + "=demo-provider")); + Invoker invoker2 = new MockInvoker(URL.valueOf("dubbo://" + LOCAL_HOST + + ":20880/com.foo.BarService?" + REMOTE_APPLICATION_KEY + "=demo-provider®ion=hangzhou")); + Invoker invoker3 = new MockInvoker(URL.valueOf("dubbo://" + LOCAL_HOST + + ":20880/com.foo.BarService?" + REMOTE_APPLICATION_KEY + "=demo-provider")); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + originInvokers.add(invoker3); + BitList> invokers = new BitList<>(originInvokers); + return invokers; + } + +} diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCacheTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCacheTest.java index 0740faaa44..a1fbb39959 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCacheTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mesh/route/MeshRuleCacheTest.java @@ -34,7 +34,6 @@ import java.util.HashMap; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -51,7 +50,11 @@ class MeshRuleCacheTest { @Test void containMapKeyValue() { URL url = mock(URL.class); - when(url.getServiceKey()).thenReturn("test"); + when(url.getOriginalServiceParameter("test", "key1")).thenReturn("value1"); + when(url.getOriginalServiceParameter("test", "key2")).thenReturn("value2"); + when(url.getOriginalServiceParameter("test", "key3")).thenReturn("value3"); + when(url.getOriginalServiceParameter("test", "key4")).thenReturn("value4"); + Map originMap = new HashMap<>(); @@ -64,14 +67,10 @@ class MeshRuleCacheTest { inputMap.put("key1", "value1"); inputMap.put("key2", "value2"); - assertTrue(MeshRuleCache.containMapKeyValue(originMap, inputMap)); + assertTrue(MeshRuleCache.isLabelMatch(url, "test", inputMap)); inputMap.put("key4", "value4"); - assertFalse(MeshRuleCache.containMapKeyValue(originMap, inputMap)); - - - assertTrue(MeshRuleCache.containMapKeyValue(originMap, null)); - assertTrue(MeshRuleCache.containMapKeyValue(originMap, new HashMap<>())); + assertTrue(MeshRuleCache.isLabelMatch(url, "test", inputMap)); } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouterTest.java new file mode 100644 index 0000000000..00e59d5ff8 --- /dev/null +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/script/config/AppScriptStateRouterTest.java @@ -0,0 +1,100 @@ +/* + * 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.script.config; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; +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.governance.GovernanceRuleRepository; +import org.apache.dubbo.rpc.cluster.router.MockInvoker; +import org.apache.dubbo.rpc.cluster.router.state.BitList; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledForJreRange; +import org.junit.jupiter.api.condition.JRE; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.List; + +import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY; + +@DisabledForJreRange(min = JRE.JAVA_16) +public class AppScriptStateRouterTest { + private static final String LOCAL_HOST = "127.0.0.1"; + private static final String RULE_SUFFIX = ".script-router"; + + private static GovernanceRuleRepository ruleRepository; + private URL url = URL.valueOf("dubbo://1.1.1.1/com.foo.BarService"); + private String rawRule = "---\n" + + "configVersion: v3.0\n" + + "key: demo-provider\n" + + "type: javascript\n" + + "script: |\n" + + " (function route(invokers,invocation,context) {\n" + + " var result = new java.util.ArrayList(invokers.size());\n" + + " for (i = 0; i < invokers.size(); i ++) {\n" + + " if (\"10.20.3.3\".equals(invokers.get(i).getUrl().getHost())) {\n" + + " result.add(invokers.get(i));\n" + + " }\n" + + " }\n" + + " return result;\n" + + " } (invokers, invocation, context)); // 表示立即执行方法\n" + + "..."; + + @BeforeAll + public static void setUpBeforeClass() throws Exception { + ruleRepository = Mockito.mock(GovernanceRuleRepository.class); + } + + @Test + void testConfigScriptRoute() { + AppScriptStateRouter router = new AppScriptStateRouter<>(url); + router = Mockito.spy(router); + Mockito.when(router.getRuleRepository()).thenReturn(ruleRepository); + Mockito.when(ruleRepository.getRule("demo-provider" + RULE_SUFFIX, DynamicConfiguration.DEFAULT_GROUP)).thenReturn(rawRule); +// Mockito.when(ruleRepository.addListener()).thenReturn(); + + BitList> invokers = getInvokers(); + router.notify(invokers); + + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("sayHello"); + List> result = router.route(invokers.clone(), url, invocation, false, new Holder<>()); + Assertions.assertEquals(1, result.size()); + } + + private BitList> getInvokers() { + List> originInvokers = new ArrayList>(); + Invoker invoker1 = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?" + REMOTE_APPLICATION_KEY + "=demo-provider")); + Invoker invoker2 = new MockInvoker(URL.valueOf("dubbo://" + LOCAL_HOST + + ":20880/com.foo.BarService?" + REMOTE_APPLICATION_KEY + "=demo-provider")); + Invoker invoker3 = new MockInvoker(URL.valueOf("dubbo://" + LOCAL_HOST + + ":20880/com.foo.BarService?" + REMOTE_APPLICATION_KEY + "=demo-provider")); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + originInvokers.add(invoker3); + BitList> invokers = new BitList<>(originInvokers); + return invokers; + } + +} diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java index 09258d4055..d5d7746303 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagStateRouterTest.java @@ -94,6 +94,35 @@ class TagStateRouterTest { Assertions.assertEquals(invoker1, filteredInvokers.get(0)); } + @Test + void testTagRouteWithDynamicRuleV3() { + TagStateRouter router = (TagStateRouter) new TagStateRouterFactory().getRouter(TagRouterRule.class, url); + router = Mockito.spy(router); + + List> originInvokers = new ArrayList<>(); + + URL url1 = URL.valueOf("test://127.0.0.1:7777/DemoInterface?application=foo&dubbo.tag=tag2&match_key=value").setScopeModel(moduleModel); + URL url2 = URL.valueOf("test://127.0.0.1:7778/DemoInterface?application=foo&match_key=value").setScopeModel(moduleModel); + URL url3 = URL.valueOf("test://127.0.0.1:7779/DemoInterface?application=foo").setScopeModel(moduleModel); + Invoker invoker1 = new MockInvoker<>(url1, true); + Invoker invoker2 = new MockInvoker<>(url2, true); + Invoker invoker3 = new MockInvoker<>(url3, true); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + originInvokers.add(invoker3); + BitList> invokers = new BitList<>(originInvokers); + + RpcInvocation invocation = new RpcInvocation(); + invocation.setAttachment(TAG_KEY, "tag2"); + TagRouterRule rule = getTagRule(); + Mockito.when(router.getInvokers()).thenReturn(invokers); + rule.init(router); + router.setTagRouterRule(rule); + List> filteredInvokers = router.route(invokers, invokers.get(0).getUrl(), invocation, false, new Holder<>()); + Assertions.assertEquals(2, filteredInvokers.size()); +// Assertions.(invoker1, filteredInvokers.get(0)); + } + /** * TagRouterRule parse test when the tags addresses is null * @@ -122,6 +151,9 @@ class TagStateRouterTest { "..."; TagRouterRule tagRouterRule = TagRuleParser.parse(tagRouterRuleConfig); + TagStateRouter router = Mockito.mock(TagStateRouter.class); + Mockito.when(router.getInvokers()).thenReturn(BitList.emptyList()); + tagRouterRule.init(router); // assert tags assert tagRouterRule.getKey().equals("demo-provider"); @@ -138,4 +170,99 @@ class TagStateRouterTest { assert tagRouterRule.getTagnameToAddresses().get("tag4") == null; assert tagRouterRule.getAddresses().size() == 1; } + + + @Test + void tagRouterRuleParseTestV3() { + String tagRouterRuleConfig = "---\n" + + "configVersion: v3.0\n" + + "force: false\n" + + "runtime: true\n" + + "enabled: true\n" + + "priority: 1\n" + + "key: demo-provider\n" + + "tags:\n" + + " - name: tag1\n" + + " match:\n" + + " - key: match_key1\n" + + " value:\n" + + " exact: value1\n" + + " - name: tag2\n" + + " addresses:\n" + + " - \"10.20.3.3:20880\"\n" + + " - \"10.20.3.4:20880\"\n" + + " match:\n" + + " - key: match_key2\n" + + " value:\n" + + " exact: value2\n" + + " - name: tag3\n" + + " match:\n" + + " - key: match_key2\n" + + " value:\n" + + " exact: value2\n" + + " - name: tag4\n" + + " match:\n" + + " - key: not_exist\n" + + " value:\n" + + " exact: not_exist\n" + + " - name: tag5\n" + + " match:\n" + + " - key: match_key2\n" + + " value:\n" + + " wildcard: \"*\"\n" + + "..."; + + TagRouterRule tagRouterRule = TagRuleParser.parse(tagRouterRuleConfig); + TagStateRouter router = Mockito.mock(TagStateRouter.class); + Mockito.when(router.getInvokers()).thenReturn(getInvokers()); + tagRouterRule.init(router); + + // assert tags + assert tagRouterRule.getKey().equals("demo-provider"); + assert tagRouterRule.getPriority() == 1; + assert tagRouterRule.getTagNames().contains("tag1"); + assert tagRouterRule.getTagNames().contains("tag2"); + assert tagRouterRule.getTagNames().contains("tag3"); + assert tagRouterRule.getTagNames().contains("tag4"); + // assert addresses + assert tagRouterRule.getAddresses().size() == 2; + assert tagRouterRule.getAddresses().contains("10.20.3.3:20880"); + assert tagRouterRule.getTagnameToAddresses().get("tag1").size() == 2; + assert tagRouterRule.getTagnameToAddresses().get("tag2").size() == 2; + assert tagRouterRule.getTagnameToAddresses().get("tag3").size() == 1; + assert tagRouterRule.getTagnameToAddresses().get("tag5").size() == 1; + assert tagRouterRule.getTagnameToAddresses().get("tag4") == null; + + } + + public BitList> getInvokers() { + List> originInvokers = new ArrayList>(); + Invoker invoker1 = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?match_key1=value1&match_key2=value2")); + Invoker invoker2 = new MockInvoker(URL.valueOf("dubbo://10.20.3.4:20880/com.foo.BarService?match_key1=value1")); + originInvokers.add(invoker1); + originInvokers.add(invoker2); + BitList> invokers = new BitList<>(originInvokers); + return invokers; + } + + private TagRouterRule getTagRule() { + String tagRouterRuleConfig = "---\n" + + "configVersion: v3.0\n" + + "force: false\n" + + "runtime: true\n" + + "enabled: true\n" + + "priority: 1\n" + + "key: demo-provider\n" + + "tags:\n" + + " - name: tag2\n" + + " match:\n" + + " - key: match_key\n" + + " value:\n" + + " exact: value\n" + + "..."; + + TagRouterRule tagRouterRule = TagRuleParser.parse(tagRouterRuleConfig); + return tagRouterRule; + } } diff --git a/dubbo-cluster/src/test/resources/AppAnyServices.yml b/dubbo-cluster/src/test/resources/AppAnyServices.yml index e1b401cbf5..aa1b158bb8 100644 --- a/dubbo-cluster/src/test/resources/AppAnyServices.yml +++ b/dubbo-cluster/src/test/resources/AppAnyServices.yml @@ -29,4 +29,4 @@ configs: loadbalance: random cluster: failfast timeout: 6666 -... \ No newline at end of file +... diff --git a/dubbo-cluster/src/test/resources/ConfiguratorV3.yml b/dubbo-cluster/src/test/resources/ConfiguratorV3.yml new file mode 100644 index 0000000000..f54383b849 --- /dev/null +++ b/dubbo-cluster/src/test/resources/ConfiguratorV3.yml @@ -0,0 +1,40 @@ +# +# +# 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. +# +# + +# Application scope, apply to all services. +--- +configVersion: v3.0 +scope: application +key: demo-provider +configs: + - match: + address: + wildcard: "10.0.0.1:20880" + service: + oneof: + - exact: "DemoService" + - exact: "DemoService2" + param: + - key: match_key1 + value: + exact: value1 + side: provider + parameters: + weight: 200 +... diff --git a/dubbo-cluster/src/test/resources/ConfiguratorV3Compatibility.yml b/dubbo-cluster/src/test/resources/ConfiguratorV3Compatibility.yml new file mode 100644 index 0000000000..550b8eaaf5 --- /dev/null +++ b/dubbo-cluster/src/test/resources/ConfiguratorV3Compatibility.yml @@ -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. +# +# + +# Application scope, apply to all services. +--- +configVersion: v3.0 +scope: application +key: demo-provider +configs: + - addresses: + - "10.0.0.1:20880" # compatibility test + services: + - "DemoService" # compatibility test + match: + param: + - key: match_key1 + value: + exact: value1 + side: provider + parameters: + weight: 200 +... diff --git a/dubbo-cluster/src/test/resources/ConfiguratorV3Duplicate.yml b/dubbo-cluster/src/test/resources/ConfiguratorV3Duplicate.yml new file mode 100644 index 0000000000..bdea803ee5 --- /dev/null +++ b/dubbo-cluster/src/test/resources/ConfiguratorV3Duplicate.yml @@ -0,0 +1,43 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +# Application scope, apply to all services. +--- +configVersion: v3.0 +scope: application +key: demo-provider +configs: + - addresses: + - "10.0.0.1:20880" # duplicate test + services: [ "DemoService" ] # duplicate test + match: + address: + wildcard: "10.0.0.1:20880" + service: + oneof: + - exact: "DemoService" + - exact: "DemoService2" + param: + - key: match_key1 + value: + exact: value1 + side: provider + parameters: + weight: 200 +... diff --git a/dubbo-cluster/src/test/resources/ScriptRule.yaml b/dubbo-cluster/src/test/resources/ScriptRule.yaml new file mode 100644 index 0000000000..54de6d0152 --- /dev/null +++ b/dubbo-cluster/src/test/resources/ScriptRule.yaml @@ -0,0 +1,35 @@ +# +# +# 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. +# +# + +# Application scope, no service means apply to all +--- +configVersion: v3.0 +key: demo-provider +type: javascript +script: | + (function route(invokers) { + var result = new java.util.ArrayList(invokers.size()); + for (i = 0; i < invokers.size(); i ++) { + if ("10.20.153.10".equals(invokers.get(i).getUrl().getHost())) { + result.add(invokers.get(i)); + } + } + return result; + } (invokers)); // 表示立即执行方法 +... diff --git a/dubbo-cluster/src/test/resources/log4j.xml b/dubbo-cluster/src/test/resources/log4j.xml index 10680a3ed0..7a8fc9e55b 100644 --- a/dubbo-cluster/src/test/resources/log4j.xml +++ b/dubbo-cluster/src/test/resources/log4j.xml @@ -23,8 +23,16 @@ + + + + + + + + - \ No newline at end of file + diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java index f689cf25b9..164bbb6575 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java @@ -57,6 +57,7 @@ import java.util.TreeMap; import java.util.function.Predicate; import static org.apache.dubbo.common.BaseServiceMetadata.COLON_SEPARATOR; +import static org.apache.dubbo.common.constants.CommonConstants.ADDRESS_KEY; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE; import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; @@ -532,6 +533,10 @@ class URL implements Serializable { return path; } + public Map getOriginalParameters() { + return this.getParameters(); + } + public Map getParameters() { return urlParam.getParameters(); } @@ -566,6 +571,10 @@ class URL implements Serializable { return decode(getParameter(key, defaultValue)); } + public String getOriginalParameter(String key) { + return getParameter(key); + } + public String getParameter(String key) { return urlParam.getParameter(key); } @@ -1097,8 +1106,17 @@ class URL implements Serializable { return urlParam.getParameter(key); } + public Map toOriginalMap() { + Map map = new HashMap<>(getOriginalParameters()); + return addSpecialKeys(map); + } + public Map toMap() { Map map = new HashMap<>(getParameters()); + return addSpecialKeys(map); + } + + private Map addSpecialKeys(Map map) { if (getProtocol() != null) { map.put(PROTOCOL_KEY, getProtocol()); } @@ -1117,6 +1135,9 @@ class URL implements Serializable { if (getPath() != null) { map.put(PATH_KEY, getPath()); } + if (getAddress() != null) { + map.put(ADDRESS_KEY, getAddress()); + } return map; } @@ -1596,10 +1617,18 @@ class URL implements Serializable { } /* add service scope operations, see InstanceAddressURL */ + public Map getOriginalServiceParameters(String service) { + return getServiceParameters(service); + } + public Map getServiceParameters(String service) { return getParameters(); } + public String getOriginalServiceParameter(String service, String key) { + return this.getServiceParameter(service, key); + } + public String getServiceParameter(String service, String key) { return getParameter(key); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java index 0bd58098eb..a356b4cae6 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java @@ -213,6 +213,8 @@ public interface CommonConstants { String PATH_KEY = "path"; + String ADDRESS_KEY = "address"; + String INTERFACE_KEY = "interface"; String FILE_KEY = "file"; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java index 506ddadd32..e8f142b7eb 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java @@ -90,6 +90,9 @@ public interface LoggerCodeConstants { String COMMON_ISOLATED_EXECUTOR_CONFIGURATION_ERROR = "0-27"; + String VULNERABILITY_WARNING = "0-28"; + + // Registry module String REGISTRY_ADDRESS_INVALID = "1-1"; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/infra/support/EnvironmentAdapter.java b/dubbo-common/src/main/java/org/apache/dubbo/common/infra/support/EnvironmentAdapter.java index e7b509ca58..0ef472af61 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/infra/support/EnvironmentAdapter.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/infra/support/EnvironmentAdapter.java @@ -45,6 +45,8 @@ public class EnvironmentAdapter implements InfraAdapter, ScopeModelAware { /** * 1. OS Environment: DUBBO_LABELS=tag=pre;key=value * 2. JVM Options: -Denv_keys = DUBBO_KEY1, DUBBO_KEY2 + * + * @param params information of this Dubbo process, currently includes application name and host address. */ @Override public Map getExtraAttributes(Map params) { @@ -67,6 +69,9 @@ public class EnvironmentAdapter implements InfraAdapter, ScopeModelAware { for (String key : keys) { String value = ConfigurationUtils.getProperty(applicationModel, key); if (value != null) { + // since 3.2 + parameters.put(key.toLowerCase(), value); + // upper-case key kept for compatibility parameters.put(key, value); } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j/Log4jLogger.java b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j/Log4jLogger.java index db87391d9f..8007c981e3 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j/Log4jLogger.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/log4j/Log4jLogger.java @@ -131,4 +131,8 @@ public class Log4jLogger implements Logger { return logger.isEnabledFor(Level.ERROR); } + // test purpose only + public org.apache.log4j.Logger getLogger() { + return logger; + } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/ServiceAddressURL.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/ServiceAddressURL.java index d4da73e673..cfef522832 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/ServiceAddressURL.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/ServiceAddressURL.java @@ -92,6 +92,23 @@ public abstract class ServiceAddressURL extends URL { return super.getParameter(VERSION_KEY); } + @Override + public String getOriginalParameter(String key) { + // call corresponding methods directly, then we can remove the following if branches. + if (GROUP_KEY.equals(key)) { + return getGroup(); + } else if (VERSION_KEY.equals(key)) { + return getVersion(); + } else if (APPLICATION_KEY.equals(key)) { + return getRemoteApplication(); + } else if (SIDE_KEY.equals(key)) { + return getSide(); + } else if (CATEGORY_KEY.equals(key)) { + return getCategory(); + } + return super.getParameter(key); + } + @Override public String getParameter(String key) { // call corresponding methods directly, then we can remove the following if branches. diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java index 28c4fb9f4e..58f902f599 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java @@ -679,7 +679,26 @@ public final class NetUtils { } } - public static boolean matchIpExpression(String pattern, String host, int port) throws UnknownHostException { + /** + * Check if address matches with specified pattern, currently only supports ipv4, use {@link this#matchIpExpression(String, String, int)} for ipv6 addresses. + * + * @param pattern cird pattern + * @param address 'ip:port' + * @return true if address matches with the pattern + */ + public static boolean matchIpExpression(String pattern, String address) throws UnknownHostException { + if (address == null) { + return false; + } + + String host = address; + int port = 0; + // only works for ipv4 address with 'ip:port' format + if (address.endsWith(":")) { + String[] hostPort = address.split(":"); + host = hostPort[0]; + port = StringUtils.parseInteger(hostPort[1]); + } // if the pattern is subnet format, it will not be allowed to config port param in pattern. if (pattern.contains("/")) { @@ -687,6 +706,16 @@ public final class NetUtils { return utils.isInRange(host); } + return matchIpRange(pattern, host, port); + } + + public static boolean matchIpExpression(String pattern, String host, int port) throws UnknownHostException { + + // if the pattern is subnet format, it will not be allowed to config port param in pattern. + if (pattern.contains("/")) { + CIDRUtils utils = new CIDRUtils(pattern); + return utils.isInRange(host); + } return matchIpRange(pattern, host, port); } diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index 5e47b22074..d958e70657 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -1156,6 +1156,18 @@ META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory + + + META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern + + + + + META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory + + diff --git a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json index 816a1aff40..112737d01c 100644 --- a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json +++ b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json @@ -2240,7 +2240,14 @@ ] }, { - "name": "org.apache.dubbo.rpc.filter.AccessLogFilter" + "name": "org.apache.dubbo.rpc.filter.AccessLogFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] }, { "name": "org.apache.dubbo.rpc.filter.ClassLoaderFilter", @@ -2900,6 +2907,76 @@ } ] }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.attachment.AttachmentConditionMatcherFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.argument.ArgumentConditionMatcherFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.param.UrlParamConditionMatcherFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.range.RangeValuePattern", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.wildcard.WildcardValuePattern", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.config.ProviderAppStateRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.script.config.AppScriptRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, { "name": "com.alibaba.fastjson.JSON", "allPublicMethods": true diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java index 3708991dc2..ff41fa05f2 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/InstanceAddressURL.java @@ -187,6 +187,27 @@ public class InstanceAddressURL extends URL { return serviceInfo.getPath(); } + @Override + public String getOriginalParameter(String key) { + if (VERSION_KEY.equals(key)) { + return getVersion(); + } else if (GROUP_KEY.equals(key)) { + return getGroup(); + } else if (INTERFACE_KEY.equals(key)) { + return getServiceInterface(); + } else if (REMOTE_APPLICATION_KEY.equals(key)) { + return instance.getServiceName(); + } else if (SIDE_KEY.equals(key)) { + return getSide(); + } + + String protocolServiceKey = getProtocolServiceKey(); + if (isEmpty(protocolServiceKey)) { + return getInstanceParameter(key); + } + return getServiceParameter(protocolServiceKey, key); + } + @Override public String getParameter(String key) { if (VERSION_KEY.equals(key)) { @@ -218,6 +239,18 @@ public class InstanceAddressURL extends URL { return getServiceParameter(protocolServiceKey, key); } + @Override + public String getOriginalServiceParameter(String service, String key) { + if (metadataInfo != null) { + String value = metadataInfo.getParameter(key, service); + if (StringUtils.isNotEmpty(value)) { + return value; + } + } + + return getInstanceParameter(key); + } + @Override public String getServiceParameter(String service, String key) { if (consumerParamFirst(key)) { @@ -393,6 +426,24 @@ public class InstanceAddressURL extends URL { return hasServiceMethodParameter(protocolServiceKey, method); } + @Override + public Map getOriginalServiceParameters(String protocolServiceKey) { + Map instanceParams = getInstance().getAllParams(); + Map metadataParams = (metadataInfo == null ? new HashMap<>() : metadataInfo.getParameters(protocolServiceKey)); + int i = instanceParams == null ? 0 : instanceParams.size(); + int j = metadataParams == null ? 0 : metadataParams.size(); + Map params = new HashMap<>((int) ((i + j) / 0.75) + 1); + if (instanceParams != null) { + params.putAll(instanceParams); + } + if (metadataParams != null) { + params.putAll(metadataParams); + } + + return params; + } + + /** * Avoid calling this method in RPC call. * @@ -423,6 +474,15 @@ public class InstanceAddressURL extends URL { return params; } + @Override + public Map getOriginalParameters() { + String protocolServiceKey = getProtocolServiceKey(); + if (isEmpty(protocolServiceKey)) { + return getInstance().getAllParams(); + } + return getOriginalServiceParameters(protocolServiceKey); + } + @Override public Map getParameters() { String protocolServiceKey = getProtocolServiceKey(); diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java index c39176bfc6..eac73aec83 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryDirectory.java @@ -16,26 +16,16 @@ */ package org.apache.dubbo.registry.client; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.stream.Collectors; - import org.apache.dubbo.common.ProtocolServiceKey; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.URLBuilder; import org.apache.dubbo.common.config.configcenter.DynamicConfiguration; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.url.component.DubboServiceAddressURL; +import org.apache.dubbo.common.url.component.ServiceConfigURL; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; @@ -60,9 +50,24 @@ import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; import org.apache.dubbo.rpc.cluster.router.state.BitList; import org.apache.dubbo.rpc.model.ModuleModel; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; + +import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY; import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_DESTROY_INVOKER; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_REFER_INVOKER; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNSUPPORTED; @@ -179,12 +184,57 @@ public class ServiceDiscoveryRegistryDirectory extends DynamicDirectory { } // RefreshOverrideAndInvoker will be executed by registryCenter and configCenter, so it should be synchronized. - private synchronized void refreshOverrideAndInvoker(List instanceUrls) { + @Override + protected synchronized void refreshOverrideAndInvoker(List instanceUrls) { // mock zookeeper://xxx?mock=return null + this.directoryUrl = overrideDirectoryWithConfigurator(getOriginalConsumerUrl()); refreshInvoker(instanceUrls); } - private InstanceAddressURL overrideWithConfigurator(InstanceAddressURL providerUrl) { + + protected URL overrideDirectoryWithConfigurator(URL url) { + // override url with configurator from "app-name.configurators" + url = overrideWithConfigurators(getConsumerConfigurationListener(moduleModel).getConfigurators(), url); + + // override url with configurator from configurators from "service-name.configurators" + if (referenceConfigurationListener != null) { + url = overrideWithConfigurators(referenceConfigurationListener.getConfigurators(), url); + } + + return url; + } + + private URL overrideWithConfigurators(List configurators, URL url) { + if (CollectionUtils.isNotEmpty(configurators)) { + if (url instanceof DubboServiceAddressURL) { + DubboServiceAddressURL interfaceAddressURL = (DubboServiceAddressURL) url; + URL overriddenURL = interfaceAddressURL.getOverrideURL(); + if (overriddenURL == null) { + String appName = interfaceAddressURL.getApplication(); + String side = interfaceAddressURL.getSide(); + overriddenURL = URLBuilder.from(interfaceAddressURL) + .clearParameters() + .addParameter(APPLICATION_KEY, appName) + .addParameter(SIDE_KEY, side).build(); + } + for (Configurator configurator : configurators) { + overriddenURL = configurator.configure(overriddenURL); + } + url = new DubboServiceAddressURL( + interfaceAddressURL.getUrlAddress(), + interfaceAddressURL.getUrlParam(), + interfaceAddressURL.getConsumerURL(), + (ServiceConfigURL) overriddenURL); + } else { + for (Configurator configurator : configurators) { + url = configurator.configure(url); + } + } + } + return url; + } + + protected InstanceAddressURL overrideWithConfigurator(InstanceAddressURL providerUrl) { // override url with configurator from "app-name.configurators" providerUrl = overrideWithConfigurators(getConsumerConfigurationListener(moduleModel).getConfigurators(), providerUrl); diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java index 75dbd7d12f..5d01197275 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java @@ -36,7 +36,7 @@ import java.util.Set; import java.util.stream.Collectors; import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_PARSE_DYNAMIC_CONFIG; -import static org.apache.dubbo.rpc.Constants.ACCESS_LOG_KEY; +import static org.apache.dubbo.rpc.Constants.ACCESS_LOG_FIXED_PATH_KEY; import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY; import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY; import static org.apache.dubbo.rpc.cluster.Constants.RUNTIME_KEY; @@ -63,8 +63,8 @@ public abstract class AbstractConfiguratorListener implements ConfigurationListe } private void initSecurityKey() { - // accessLogKey and FileRouterFactory key - securityKey.add(ACCESS_LOG_KEY); + // FileRouterFactory key + securityKey.add(ACCESS_LOG_FIXED_PATH_KEY); securityKey.add(ROUTER_KEY); securityKey.add(RULE_KEY); securityKey.add(RUNTIME_KEY); diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/DynamicDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/DynamicDirectory.java index 12f2dcef34..c171b9b5b0 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/DynamicDirectory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/DynamicDirectory.java @@ -16,8 +16,6 @@ */ package org.apache.dubbo.registry.integration; -import java.util.List; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.Version; import org.apache.dubbo.common.config.ConfigurationUtils; @@ -46,6 +44,8 @@ import org.apache.dubbo.rpc.cluster.directory.AbstractDirectory; import org.apache.dubbo.rpc.cluster.router.state.BitList; import org.apache.dubbo.rpc.model.ModuleModel; +import java.util.List; + import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_SITE_SELECTION; import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_DESTROY_SERVICE; @@ -82,7 +82,7 @@ public abstract class DynamicDirectory extends AbstractDirectory implement /** * Initialization at construction time, assertion not null, and always assign non-null value */ - protected final URL directoryUrl; + protected volatile URL directoryUrl; protected final boolean multiGroup; /** @@ -234,7 +234,7 @@ public abstract class DynamicDirectory extends AbstractDirectory implement */ @Override public URL getConsumerUrl() { - return this.consumerUrl; + return this.directoryUrl; } /** @@ -376,4 +376,7 @@ public abstract class DynamicDirectory extends AbstractDirectory implement } protected abstract void destroyAllInvokers(); + + protected abstract void refreshOverrideAndInvoker(List urls); + } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java index 65c8ef3190..fe85a484ab 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java @@ -208,8 +208,10 @@ public class RegistryDirectory extends DynamicDirectory { } // RefreshOverrideAndInvoker will be executed by registryCenter and configCenter, so it should be synchronized. - private synchronized void refreshOverrideAndInvoker(List urls) { + @Override + protected synchronized void refreshOverrideAndInvoker(List urls) { // mock zookeeper://xxx?mock=return null + this.directoryUrl = overrideWithConfigurator(getOriginalConsumerUrl()); refreshInvoker(urls); } @@ -510,7 +512,7 @@ public class RegistryDirectory extends DynamicDirectory { return providerUrl; } - private URL overrideWithConfigurator(URL providerUrl) { + protected URL overrideWithConfigurator(URL providerUrl) { // override url with configurator from "override://" URL for dubbo 2.6 and before providerUrl = overrideWithConfigurators(this.configurators, providerUrl); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/DynamicDirectoryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/DynamicDirectoryTest.java index f181de31b2..8253614c6c 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/DynamicDirectoryTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/DynamicDirectoryTest.java @@ -161,6 +161,11 @@ class DynamicDirectoryTest { } + @Override + protected void refreshOverrideAndInvoker(List urls) { + + } + @Override public boolean isAvailable() { return false; diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java index b1ae50e380..1cdb86d347 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java @@ -63,6 +63,8 @@ public interface Constants { String ACCESS_LOG_KEY = "accesslog"; + String ACCESS_LOG_FIXED_PATH_KEY = "accesslog.fixed.path"; + String ACTIVES_KEY = "actives"; String ID_KEY = "id"; diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java index ffcf65b3d8..0ad448d487 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java @@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.common.utils.ConfigUtils; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.Constants; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; @@ -42,12 +43,14 @@ import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FILTER_VALIDATION_EXCEPTION; -import static org.apache.dubbo.rpc.Constants.ACCESS_LOG_KEY; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.VULNERABILITY_WARNING; +import static org.apache.dubbo.rpc.Constants.ACCESS_LOG_FIXED_PATH_KEY; /** * Record access log for the service. @@ -63,16 +66,16 @@ import static org.apache.dubbo.rpc.Constants.ACCESS_LOG_KEY; * </logger> * */ -@Activate(group = PROVIDER, value = ACCESS_LOG_KEY) +@Activate(group = PROVIDER) public class AccessLogFilter implements Filter { - private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AccessLogFilter.class); + public static ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AccessLogFilter.class); private static final String LOG_KEY = "dubbo.accesslog"; private static final int LOG_MAX_BUFFER = 5000; - private static final long LOG_OUTPUT_INTERVAL = 5000; + private static long LOG_OUTPUT_INTERVAL = 5000; private static final String FILE_DATE_FORMAT = "yyyyMMdd"; @@ -82,6 +85,7 @@ public class AccessLogFilter implements Filter { private final ConcurrentMap> logEntries = new ConcurrentHashMap<>(); private final AtomicBoolean scheduled = new AtomicBoolean(); + private ScheduledFuture future; private static final String LINE_SEPARATOR = "line.separator"; @@ -102,18 +106,27 @@ public class AccessLogFilter implements Filter { */ @Override public Result invoke(Invoker invoker, Invocation inv) throws RpcException { + String accessLogKey = invoker.getUrl().getParameter(Constants.ACCESS_LOG_KEY); + boolean isFixedPath = invoker.getUrl().getParameter(ACCESS_LOG_FIXED_PATH_KEY, true); + if (StringUtils.isEmpty(accessLogKey)) { + // Notice that disable accesslog of one service may cause the whole application to stop collecting accesslog. + // It's recommended to use application level configuration to enable or disable accesslog if dynamically configuration is needed . + if (future != null && !future.isCancelled()) { + future.cancel(true); + logger.info("Access log task cancelled ..."); + } + return invoker.invoke(inv); + } + if (scheduled.compareAndSet(false, true)) { - inv.getModuleModel().getApplicationModel().getFrameworkModel().getBeanFactory() + future = inv.getModuleModel().getApplicationModel().getFrameworkModel().getBeanFactory() .getBean(FrameworkExecutorRepository.class).getSharedScheduledExecutor() - .scheduleWithFixedDelay(this::writeLogToFile, LOG_OUTPUT_INTERVAL, LOG_OUTPUT_INTERVAL, TimeUnit.MILLISECONDS); + .scheduleWithFixedDelay(new AccesslogRefreshTask(isFixedPath), LOG_OUTPUT_INTERVAL, LOG_OUTPUT_INTERVAL, TimeUnit.MILLISECONDS); + logger.info("Access log task started ..."); } Optional optionalAccessLogData = Optional.empty(); - String accessLogKey = null; try { - accessLogKey = invoker.getUrl().getParameter(Constants.ACCESS_LOG_KEY); - if (ConfigUtils.isNotEmpty(accessLogKey)) { - optionalAccessLogData = Optional.of(buildAccessLogData(invoker, inv)); - } + optionalAccessLogData = Optional.of(buildAccessLogData(invoker, inv)); } catch (Throwable t) { logger.warn(CONFIG_FILTER_VALIDATION_EXCEPTION, "", "", "Exception in AccessLogFilter of service(" + invoker + " -> " + inv + ")", t); } @@ -123,12 +136,12 @@ public class AccessLogFilter implements Filter { String finalAccessLogKey = accessLogKey; optionalAccessLogData.ifPresent(logData -> { logData.setOutTime(new Date()); - log(finalAccessLogKey, logData); + log(finalAccessLogKey, logData, isFixedPath); }); } } - private void log(String accessLog, AccessLogData accessLogData) { + private void log(String accessLog, AccessLogData accessLogData, boolean isFixedPath) { Queue logQueue = ConcurrentHashMapUtils.computeIfAbsent(logEntries, accessLog, k -> new ConcurrentLinkedQueue<>()); if (logQueue.size() < LOG_MAX_BUFFER) { @@ -136,40 +149,39 @@ public class AccessLogFilter implements Filter { } else { logger.warn(CONFIG_FILTER_VALIDATION_EXCEPTION, "", "", "AccessLog buffer is full. Do a force writing to file to clear buffer."); //just write current logSet to file. - writeLogSetToFile(accessLog, logQueue); + writeLogSetToFile(accessLog, logQueue, isFixedPath); //after force writing, add accessLogData to current logSet logQueue.add(accessLogData); } } - private void writeLogSetToFile(String accessLog, Queue logSet) { + private void writeLogSetToFile(String accessLog, Queue logSet, boolean isFixedPath) { try { if (ConfigUtils.isDefault(accessLog)) { processWithServiceLogger(logSet); } else { - File file = new File(accessLog); - createIfLogDirAbsent(file); - if (logger.isDebugEnabled()) { - logger.debug("Append log to " + accessLog); + if (isFixedPath) { + logger.warn(VULNERABILITY_WARNING, "Change of accesslog file path not allowed. ", "", "Will write to the default location, \" +\n" + + " \"please enable this feature by setting 'accesslog.fixed.path=true' and restart the process. \" +\n" + + " \"We highly recommend to not enable this feature in production for security concerns, \" +\n" + + " \"please be fully aware of the potential risks before doing so!"); + processWithServiceLogger(logSet); + } else { + logger.warn(VULNERABILITY_WARNING, "Accesslog file path changed to " + accessLog + ", be aware of possible vulnerabilities!", "", ""); + File file = new File(accessLog); + createIfLogDirAbsent(file); + if (logger.isDebugEnabled()) { + logger.debug("Append log to " + accessLog); + } + renameFile(file); + processWithAccessKeyLogger(logSet, file); } - renameFile(file); - processWithAccessKeyLogger(logSet, file); } } catch (Exception e) { logger.error(CONFIG_FILTER_VALIDATION_EXCEPTION, "", "", e.getMessage(), e); } } - private void writeLogToFile() { - if (!logEntries.isEmpty()) { - for (Map.Entry> entry : logEntries.entrySet()) { - String accessLog = entry.getKey(); - Queue logSet = entry.getValue(); - writeLogSetToFile(accessLog, logSet); - } - } - } - private void processWithAccessKeyLogger(Queue logQueue, File file) throws IOException { FileWriter writer = new FileWriter(file, true); try { @@ -219,4 +231,38 @@ public class AccessLogFilter implements Filter { } } } + + class AccesslogRefreshTask implements Runnable { + private final boolean isFixedPath; + + public AccesslogRefreshTask(boolean isFixedPath) { + this.isFixedPath = isFixedPath; + } + + @Override + public void run() { + if (!AccessLogFilter.this.logEntries.isEmpty()) { + for (Map.Entry> entry : AccessLogFilter.this.logEntries.entrySet()) { + String accessLog = entry.getKey(); + Queue logSet = entry.getValue(); + writeLogSetToFile(accessLog, logSet, isFixedPath); + } + } + } + } + + // test purpose only + public static void setInterval(long interval) { + LOG_OUTPUT_INTERVAL = interval; + } + + // test purpose only + public static long getInterval() { + return LOG_OUTPUT_INTERVAL; + } + + // test purpose only + public void destroy() { + future.cancel(true); + } } diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/AccessLogFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/AccessLogFilterTest.java index 390f5d837e..570522af78 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/AccessLogFilterTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/AccessLogFilterTest.java @@ -17,16 +17,22 @@ package org.apache.dubbo.rpc.filter; import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.utils.DubboAppender; -import org.apache.dubbo.common.utils.LogUtil; -import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.logger.log4j.Log4jLogger; +import org.apache.dubbo.common.logger.support.FailsafeLogger; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.support.AccessLogData; import org.apache.dubbo.rpc.support.MockInvocation; import org.apache.dubbo.rpc.support.MyInvoker; +import org.apache.log4j.Appender; +import org.apache.log4j.Level; +import org.apache.log4j.spi.LoggingEvent; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import java.lang.reflect.Field; import java.util.Map; @@ -35,26 +41,27 @@ import java.util.Queue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; /** * AccessLogFilterTest.java */ class AccessLogFilterTest { - Filter accessLogFilter = new AccessLogFilter(); + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger("mock.dubbo.access.log"); + private static org.apache.log4j.Logger realLogger; - // Test filter won't throw an exception - @Test - void testInvokeException() { - Invoker invoker = new MyInvoker(null); - Invocation invocation = new MockInvocation(); - LogUtil.start(); - accessLogFilter.invoke(invoker, invocation); - assertEquals(1, LogUtil.findMessage("Exception in AccessLogFilter of service")); - LogUtil.stop(); - DubboAppender.clear(); + @BeforeAll + public static void setupLogger() { + FailsafeLogger failsafeLogger = (FailsafeLogger) logger; + Log4jLogger log4j2Logger = (Log4jLogger) failsafeLogger.getLogger(); + realLogger = log4j2Logger.getLogger(); } + AccessLogFilter accessLogFilter = new AccessLogFilter(); + // TODO how to assert thread action @Test @SuppressWarnings("unchecked") @@ -78,10 +85,60 @@ class AccessLogFilterTest { @Test void testCustom() { - URL url = URL.valueOf("test://test:11/test?accesslog=custom-access.log"); - Invoker invoker = new MyInvoker(url); - Invocation invocation = new MockInvocation(); - accessLogFilter.invoke(invoker, invocation); + ErrorTypeAwareLogger originalLogger = AccessLogFilter.logger; + long originalInterval = AccessLogFilter.getInterval(); + + Appender appender = mock(Appender.class); + AccessLogFilter.setInterval(500); + AccessLogFilter.logger = logger; + AccessLogFilter customAccessLogFilter = new AccessLogFilter(); + try { + realLogger.addAppender(appender); + URL url = URL.valueOf("test://test:11/test?accesslog=custom-access.log"); + Invoker invoker = new MyInvoker<>(url); + Invocation invocation = new MockInvocation(); + customAccessLogFilter.invoke(invoker, invocation); + sleep(); + ArgumentCaptor argument = ArgumentCaptor.forClass(LoggingEvent.class); + verify(appender, times(2)).doAppend(argument.capture()); + assertEquals(Level.WARN, argument.getAllValues().get(1).getLevel()); + assertTrue(argument.getAllValues().get(1).getRenderedMessage().contains("Change of accesslog file path not allowed")); + } finally { + customAccessLogFilter.destroy(); + realLogger.removeAppender(appender); + AccessLogFilter.logger = originalLogger; + AccessLogFilter.setInterval(originalInterval); + } + + Appender appender2 = mock(Appender.class); + AccessLogFilter.setInterval(500); + AccessLogFilter.logger = logger; + AccessLogFilter customAccessLogFilter2 = new AccessLogFilter(); + try { + realLogger.addAppender(appender2); + URL url2 = URL.valueOf("test://test:11/test?accesslog=custom-access.log&accesslog.fixed.path=false"); + Invoker invoker = new MyInvoker<>(url2); + Invocation invocation = new MockInvocation(); + customAccessLogFilter2.invoke(invoker, invocation); + sleep(); + ArgumentCaptor argument = ArgumentCaptor.forClass(LoggingEvent.class); + verify(appender2, times(2)).doAppend(argument.capture()); + assertEquals(Level.WARN, argument.getAllValues().get(1).getLevel()); + assertTrue(argument.getAllValues().get(1).getRenderedMessage().contains("Accesslog file path changed to")); + } finally { + customAccessLogFilter2.destroy(); + realLogger.removeAppender(appender2); + AccessLogFilter.logger = originalLogger; + AccessLogFilter.setInterval(originalInterval); + } + } + + private void sleep() { + try { + Thread.sleep(600); + } catch (InterruptedException e) { + e.printStackTrace(); + } } } diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/resources/log4j.xml b/dubbo-rpc/dubbo-rpc-api/src/test/resources/log4j.xml index e0eda90175..eb01deaffe 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/resources/log4j.xml +++ b/dubbo-rpc/dubbo-rpc-api/src/test/resources/log4j.xml @@ -31,8 +31,16 @@ --> + + + + + + + + - \ No newline at end of file + From a1dea63969d66129de4fdaec54bfbcc535e7ea1f Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sun, 26 Feb 2023 16:43:30 +0800 Subject: [PATCH 034/144] Fix license check --- .licenserc.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.licenserc.yaml b/.licenserc.yaml index 9b593b5e53..8d0f30f4c5 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -186,6 +186,12 @@ dependency: license: Apache-2.0 - name: org.slf4j:jul-to-slf4j license: Apache-2.0 + - name: org.codehaus.plexus:plexus-interpolation + license: Apache-2.0 + - name: org.sonatype.plexus:plexus-sec-dispatcher + license: Apache-2.0 + - name: org.sonatype.plexus:plexus-cipher + license: Apache-2.0 # multi license - name: org.javassist:javassist license: Apache-2.0 From 57c58de0adeab8f3717ac78e69a9470060df748c Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sun, 26 Feb 2023 18:30:32 +0800 Subject: [PATCH 035/144] Fix qos command remote check (#11506) * Fix qos command remote check * update * Fix NPE --- .../dubbo/qos/command/CommandContext.java | 8 +- .../dubbo/qos/common/QosConfiguration.java | 33 ++++++++ ...faultAnonymousAccessPermissionChecker.java | 27 +++++- .../handler/ForeignHostPermitHandler.java | 36 +++----- ...tAnonymousAccessPermissionCheckerTest.java | 83 +++++++++++++++++++ 5 files changed, 156 insertions(+), 31 deletions(-) create mode 100644 dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContext.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContext.java index a45560becd..fdd92514b1 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContext.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContext.java @@ -16,10 +16,10 @@ */ package org.apache.dubbo.qos.command; -import io.netty.channel.Channel; -import org.apache.dubbo.qos.permission.PermissionLevel; import org.apache.dubbo.qos.common.QosConfiguration; +import io.netty.channel.Channel; + public class CommandContext { private String commandName; @@ -93,8 +93,8 @@ public class CommandContext { this.qosConfiguration = qosConfiguration; } - public boolean hasPermission(PermissionLevel cmdRequiredPermissionLevel) { - return cmdRequiredPermissionLevel.getLevel() <= qosConfiguration.getAnonymousAccessPermissionLevel().getLevel(); + public QosConfiguration getQosConfiguration() { + return qosConfiguration; } public boolean isAllowAnonymousAccess(){ diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/common/QosConfiguration.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/common/QosConfiguration.java index fee7486913..915022c2df 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/common/QosConfiguration.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/common/QosConfiguration.java @@ -16,6 +16,12 @@ */ package org.apache.dubbo.qos.common; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.function.Predicate; + +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.qos.permission.PermissionLevel; public class QosConfiguration { @@ -26,6 +32,8 @@ public class QosConfiguration { // support specific ip and an ip range from CIDR specification private String acceptForeignIpWhitelist; + private Predicate acceptForeignIpWhitelistPredicate; + // this permission level for anonymous access, it will ignore the acceptForeignIp and acceptForeignIpWhitelist configurations // Access permission depends on the config anonymousAccessPermissionLevel and the cmd required permission level // the default value is Cmd.PermissionLevel.PUBLIC, can only access PUBLIC level cmd @@ -39,6 +47,27 @@ public class QosConfiguration { this.acceptForeignIp = builder.isAcceptForeignIp(); this.acceptForeignIpWhitelist = builder.getAcceptForeignIpWhitelist(); this.anonymousAccessPermissionLevel = builder.getAnonymousAccessPermissionLevel(); + buildPredicate(); + } + + private void buildPredicate() { + if (StringUtils.isNotEmpty(acceptForeignIpWhitelist)) { + this.acceptForeignIpWhitelistPredicate = Arrays.stream(acceptForeignIpWhitelist.split(",")) + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .map(foreignIpPattern -> (Predicate) foreignIp -> { + try { + // hard code port to -1 + return NetUtils.matchIpExpression(foreignIpPattern, foreignIp, -1); + } catch (UnknownHostException ignore) { + // ignore illegal CIDR specification + } + return false; + }) + .reduce(Predicate::or).orElse(s -> false); + } else { + this.acceptForeignIpWhitelistPredicate = foreignIp -> false; + } } public boolean isAllowAnonymousAccess() { @@ -57,6 +86,10 @@ public class QosConfiguration { return acceptForeignIpWhitelist; } + public Predicate getAcceptForeignIpWhitelistPredicate() { + return acceptForeignIpWhitelistPredicate; + } + public boolean isAcceptForeignIp() { return acceptForeignIp; } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java index ab5aa79e7b..02c5781a7e 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java @@ -17,12 +17,37 @@ package org.apache.dubbo.qos.permission; import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.common.QosConfiguration; + +import io.netty.channel.Channel; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.Optional; public class DefaultAnonymousAccessPermissionChecker implements PermissionChecker { public static final DefaultAnonymousAccessPermissionChecker INSTANCE = new DefaultAnonymousAccessPermissionChecker(); @Override public boolean access(CommandContext commandContext, PermissionLevel defaultCmdRequiredPermissionLevel) { - return commandContext.hasPermission(defaultCmdRequiredPermissionLevel); + final InetAddress inetAddress = Optional.ofNullable(commandContext.getRemote()) + .map(Channel::remoteAddress) + .map(InetSocketAddress.class::cast) + .map(InetSocketAddress::getAddress) + .orElse(null); + + QosConfiguration qosConfiguration = commandContext.getQosConfiguration(); + PermissionLevel currentLevel = qosConfiguration.getAnonymousAccessPermissionLevel(); + + // Local has private permission + if (inetAddress != null && inetAddress.isLoopbackAddress()) { + currentLevel = PermissionLevel.PRIVATE; + } else if (inetAddress != null && + qosConfiguration.getAcceptForeignIpWhitelistPredicate() + .test(inetAddress.getHostAddress())) { + currentLevel = PermissionLevel.PROTECTED; + } + + return currentLevel.getLevel() >= defaultCmdRequiredPermissionLevel.getLevel(); } } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java index e385c4d6aa..b5b63f35ac 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java @@ -16,21 +16,19 @@ */ package org.apache.dubbo.qos.server.handler; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.function.Predicate; + +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.common.QosConstants; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; -import org.apache.dubbo.common.utils.NetUtils; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.common.QosConstants; -import org.apache.dubbo.qos.common.QosConfiguration; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.function.Predicate; public class ForeignHostPermitHandler extends ChannelHandlerAdapter { @@ -40,7 +38,7 @@ public class ForeignHostPermitHandler extends ChannelHandlerAdapter { // the whitelist of foreign IP when acceptForeignIp = false, the delimiter is colon(,) // support specific ip and an ip range from CIDR specification private final String acceptForeignIpWhitelist; - private Predicate whitelistPredicate = foreignIp -> false; + private Predicate whitelistPredicate; private final QosConfiguration qosConfiguration; @@ -48,21 +46,7 @@ public class ForeignHostPermitHandler extends ChannelHandlerAdapter { this.qosConfiguration = qosConfiguration; this.acceptForeignIp = qosConfiguration.isAcceptForeignIp(); this.acceptForeignIpWhitelist = qosConfiguration.getAcceptForeignIpWhitelist(); - if (StringUtils.isNotEmpty(acceptForeignIpWhitelist)) { - whitelistPredicate = Arrays.stream(acceptForeignIpWhitelist.split(",")) - .map(String::trim) - .filter(StringUtils::isNotEmpty) - .map(foreignIpPattern -> (Predicate) foreignIp -> { - try { - // hard code port to -1 - return NetUtils.matchIpExpression(foreignIpPattern, foreignIp, -1); - } catch (UnknownHostException ignore) { - // ignore illegal CIDR specification - } - return false; - }) - .reduce(Predicate::or).orElse(s -> false); - } + this.whitelistPredicate = qosConfiguration.getAcceptForeignIpWhitelistPredicate(); } @Override diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java new file mode 100644 index 0000000000..bb6c80caec --- /dev/null +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.qos.permission; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; + +import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.common.QosConfiguration; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import io.netty.channel.Channel; + +class DefaultAnonymousAccessPermissionCheckerTest { + @Test + void testPermission() throws UnknownHostException { + InetAddress inetAddress = InetAddress.getByName("127.0.0.1"); + + InetSocketAddress socketAddress = Mockito.mock(InetSocketAddress.class); + Mockito.when(socketAddress.getAddress()).thenReturn(inetAddress); + Channel channel = Mockito.mock(Channel.class); + Mockito.when(channel.remoteAddress()).thenReturn(socketAddress); + CommandContext commandContext = Mockito.mock(CommandContext.class); + Mockito.when(commandContext.getRemote()).thenReturn(channel); + + QosConfiguration qosConfiguration = Mockito.mock(QosConfiguration.class); + Mockito.when(qosConfiguration.getAnonymousAccessPermissionLevel()).thenReturn(PermissionLevel.PUBLIC); + Mockito.when(qosConfiguration.getAcceptForeignIpWhitelistPredicate()).thenReturn(ip -> false); + + Mockito.when(commandContext.getQosConfiguration()).thenReturn(qosConfiguration); + + DefaultAnonymousAccessPermissionChecker checker = new DefaultAnonymousAccessPermissionChecker(); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.NONE)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PUBLIC)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PROTECTED)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PRIVATE)); + + inetAddress = InetAddress.getByName("1.1.1.1"); + Mockito.when(socketAddress.getAddress()).thenReturn(inetAddress); + + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.NONE)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PUBLIC)); + Assertions.assertFalse(checker.access(commandContext, PermissionLevel.PROTECTED)); + Assertions.assertFalse(checker.access(commandContext, PermissionLevel.PRIVATE)); + + Mockito.when(qosConfiguration.getAnonymousAccessPermissionLevel()).thenReturn(PermissionLevel.PROTECTED); + + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.NONE)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PUBLIC)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PROTECTED)); + Assertions.assertFalse(checker.access(commandContext, PermissionLevel.PRIVATE)); + + Mockito.when(qosConfiguration.getAnonymousAccessPermissionLevel()).thenReturn(PermissionLevel.NONE); + + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.NONE)); + Assertions.assertFalse(checker.access(commandContext, PermissionLevel.PUBLIC)); + Assertions.assertFalse(checker.access(commandContext, PermissionLevel.PROTECTED)); + Assertions.assertFalse(checker.access(commandContext, PermissionLevel.PRIVATE)); + + Mockito.when(qosConfiguration.getAcceptForeignIpWhitelistPredicate()).thenReturn(ip -> true); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.NONE)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PUBLIC)); + Assertions.assertTrue(checker.access(commandContext, PermissionLevel.PROTECTED)); + Assertions.assertFalse(checker.access(commandContext, PermissionLevel.PRIVATE)); + } +} From f501be8cec698606fbe9ca3ced7a8820263c0aac Mon Sep 17 00:00:00 2001 From: huazhongming Date: Mon, 27 Feb 2023 10:48:12 +0800 Subject: [PATCH 036/144] sync reflect config (#11668) --- .../META-INF/native-image/reflect-config.json | 139 ++++++++++++++---- 1 file changed, 108 insertions(+), 31 deletions(-) diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json index 64b4fd5431..b70a14a2f0 100644 --- a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json +++ b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json @@ -1205,9 +1205,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ApplicationModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] }, @@ -1436,9 +1434,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ApplicationModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] }, @@ -1589,9 +1585,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ApplicationModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] }, @@ -2116,6 +2110,16 @@ } ] }, + { + "name": "org.apache.dubbo.metrics.MetricsScopeModelInitializer", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, { "name": "org.apache.dubbo.rpc.cluster.ConfiguratorFactory", "allPublicMethods": true @@ -2183,9 +2187,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ApplicationModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] }, @@ -2238,7 +2240,14 @@ ] }, { - "name": "org.apache.dubbo.rpc.filter.AccessLogFilter" + "name": "org.apache.dubbo.rpc.filter.AccessLogFilter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] }, { "name": "org.apache.dubbo.rpc.filter.ClassLoaderFilter", @@ -2259,9 +2268,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ApplicationModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] }, @@ -2545,9 +2552,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.FrameworkModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] } ] }, @@ -2704,9 +2709,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.zookeeper.client.ZKClientConfig" - ] + "parameterTypes": ["org.apache.zookeeper.client.ZKClientConfig"] }, { "name": "", @@ -2850,9 +2853,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.FrameworkModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] } ] }, @@ -2862,9 +2863,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ModuleModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.ModuleModel"] } ] }, @@ -2874,9 +2873,7 @@ "methods": [ { "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ModuleModel" - ] + "parameterTypes": ["org.apache.dubbo.rpc.model.ModuleModel"] } ] }, @@ -2910,6 +2907,76 @@ } ] }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.attachment.AttachmentConditionMatcherFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.argument.ArgumentConditionMatcherFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.param.UrlParamConditionMatcherFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.range.RangeValuePattern", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.wildcard.WildcardValuePattern", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.condition.config.ProviderAppStateRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.script.config.AppScriptRouterFactory", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, { "name": "com.alibaba.fastjson.JSON", "allPublicMethods": true @@ -2921,5 +2988,15 @@ { "name": "java.util.Collections$UnmodifiableCollection", "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] + } + ] } ] From c4d6f94b2ce16ead95880265749b2ffb9701ecc3 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Mon, 27 Feb 2023 12:33:04 +0800 Subject: [PATCH 037/144] Introduce getConfig QoS Command (#11664) * Introduce getConfig QoS Command * Fix NPE * Fix NPE --- .../apache/dubbo/config/AbstractConfig.java | 6 + .../dubbo/config/AbstractInterfaceConfig.java | 23 +- .../dubbo/config/AbstractMethodConfig.java | 4 + .../dubbo/config/AbstractServiceConfig.java | 2 + .../dubbo/config/ReferenceConfigBase.java | 3 + .../dubbo/config/ServiceConfigBase.java | 6 +- .../org/apache/dubbo/config/SslConfig.java | 7 + .../config/nested/AggregationConfig.java | 4 +- .../dubbo/config/nested/PrometheusConfig.java | 8 +- .../apache/dubbo/config/ReferenceConfig.java | 4 + .../apache/dubbo/config/ServiceConfig.java | 2 + .../dubbo/qos/command/impl/GetConfig.java | 200 ++++++++++++++++++ .../org.apache.dubbo.qos.command.BaseCommand | 1 + .../dubbo/qos/command/impl/GetConfigTest.java | 140 ++++++++++++ .../qos/command/util/CommandHelperTest.java | 9 +- 15 files changed, 401 insertions(+), 18 deletions(-) create mode 100644 dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java create mode 100644 dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java index 01108fadb1..6247a02bd4 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java @@ -539,10 +539,12 @@ public abstract class AbstractConfig implements Serializable { * @see AbstractConfig#checkDefault() * @see AbstractConfig#appendParameters(Map, Object, String) */ + @Transient public Map getMetaData() { return getMetaData(null); } + @Transient public Map getMetaData(String prefix) { Map metaData = new HashMap<>(); appendAttributes(metaData, this, prefix); @@ -569,6 +571,7 @@ public abstract class AbstractConfig implements Serializable { } @Parameter(excluded = true, attribute = false) + @Transient public List getPrefixes() { List prefixes = new ArrayList<>(); if (StringUtils.hasText(this.getId())) { @@ -595,6 +598,7 @@ public abstract class AbstractConfig implements Serializable { return CommonConstants.DUBBO + "." + getTagName(cls); } + @Transient public ConfigMode getConfigMode() { return getApplicationModel().getApplicationConfigManager().getConfigMode(); } @@ -1030,6 +1034,7 @@ public abstract class AbstractConfig implements Serializable { return hashCode; } + @Transient private List getAttributedMethods() { Class cls = this.getClass(); return ConcurrentHashMapUtils.computeIfAbsent(attributedMethodCache, cls, (key) -> computeAttributedMethods()); @@ -1063,6 +1068,7 @@ public abstract class AbstractConfig implements Serializable { return methods; } + @Transient protected ConfigManager getConfigManager() { return getApplicationModel().getApplicationConfigManager(); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java index 3993ad7ea2..6fd828d998 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java @@ -16,15 +16,6 @@ */ package org.apache.dubbo.config; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.Version; import org.apache.dubbo.common.config.ConfigurationUtils; @@ -43,6 +34,16 @@ import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ScopeModelUtil; import org.apache.dubbo.rpc.model.ServiceMetadata; +import java.beans.Transient; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY; @@ -207,8 +208,9 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig { /** * The url of the reference service */ - protected final List urls = new ArrayList(); + protected transient final List urls = new ArrayList(); + @Transient public List getExportedUrls() { return urls; } @@ -903,6 +905,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig { this.interfaceName = interfaceName; } + @Transient public ClassLoader getInterfaceClassLoader() { return interfaceClassLoader; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java index bfbce7c244..d1978f62c4 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java @@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.model.ScopeModel; +import java.beans.Transient; import java.util.Map; /** @@ -108,11 +109,13 @@ public abstract class AbstractMethodConfig extends AbstractConfig { } @Override + @Transient public ModuleModel getScopeModel() { return (ModuleModel) super.getScopeModel(); } @Override + @Transient protected ScopeModel getDefaultModel() { return ApplicationModel.defaultModel().getDefaultModule(); } @@ -127,6 +130,7 @@ public abstract class AbstractMethodConfig extends AbstractConfig { } } + @Transient protected ModuleConfigManager getModuleConfigManager() { return getScopeModel().getConfigManager(); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java index 1f2ae28a72..474c362cfe 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.support.Parameter; import org.apache.dubbo.rpc.model.ModuleModel; +import java.beans.Transient; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -371,6 +372,7 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig { } @Parameter(key = SERVICE_EXECUTOR) + @Transient public Executor getExecutor() { return executor; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java index 4ef903f395..867e195561 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java @@ -29,6 +29,7 @@ import org.apache.dubbo.rpc.model.ServiceMetadata; import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.support.ProtocolUtils; +import java.beans.Transient; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -294,6 +295,7 @@ public abstract class ReferenceConfigBase extends AbstractReferenceConfig { this.unloadClusterRelated = unloadClusterRelated; } + @Transient public ServiceMetadata getServiceMetadata() { return serviceMetadata; } @@ -365,6 +367,7 @@ public abstract class ReferenceConfigBase extends AbstractReferenceConfig { return shouldReferAsync; } + @Transient public abstract T get(); public void destroy() { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java index d80b008d90..57f850c18c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java @@ -28,6 +28,7 @@ import org.apache.dubbo.rpc.model.ServiceMetadata; import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.support.ProtocolUtils; +import java.beans.Transient; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -59,7 +60,7 @@ public abstract class ServiceConfigBase extends AbstractServiceConfig { /** * The reference of the interface implementation */ - protected T ref; + protected transient T ref; /** * The service name @@ -296,6 +297,7 @@ public abstract class ServiceConfigBase extends AbstractServiceConfig { } } + @Transient public T getRef() { return ref; } @@ -346,11 +348,13 @@ public abstract class ServiceConfigBase extends AbstractServiceConfig { } } + @Transient public ServiceMetadata getServiceMetadata() { return serviceMetadata; } @Override + @Transient @Parameter(excluded = true, attribute = false) public List getPrefixes() { List prefixes = new ArrayList<>(); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java index 62e03edbce..0dc9557246 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java @@ -22,6 +22,7 @@ import org.apache.dubbo.common.utils.IOUtils; import org.apache.dubbo.config.support.Parameter; import org.apache.dubbo.rpc.model.ApplicationModel; +import java.beans.Transient; import java.io.IOException; import java.io.InputStream; @@ -142,6 +143,7 @@ public class SslConfig extends AbstractConfig { this.clientTrustCertCollectionPath = clientTrustCertCollectionPath; } + @Transient public InputStream getServerKeyCertChainPathStream() throws IOException { if (serverKeyCertChainPath != null) { serverKeyCertChainPathStream = IOUtils.getURL(serverKeyCertChainPath).openStream(); @@ -153,6 +155,7 @@ public class SslConfig extends AbstractConfig { this.serverKeyCertChainPathStream = serverKeyCertChainPathStream; } + @Transient public InputStream getServerPrivateKeyPathStream() throws IOException { if (serverPrivateKeyPath != null) { serverPrivateKeyPathStream = IOUtils.getURL(serverPrivateKeyPath).openStream(); @@ -164,6 +167,7 @@ public class SslConfig extends AbstractConfig { this.serverPrivateKeyPathStream = serverPrivateKeyPathStream; } + @Transient public InputStream getServerTrustCertCollectionPathStream() throws IOException { if (serverTrustCertCollectionPath != null) { serverTrustCertCollectionPathStream = IOUtils.getURL(serverTrustCertCollectionPath).openStream(); @@ -175,6 +179,7 @@ public class SslConfig extends AbstractConfig { this.serverTrustCertCollectionPathStream = serverTrustCertCollectionPathStream; } + @Transient public InputStream getClientKeyCertChainPathStream() throws IOException { if (clientKeyCertChainPath != null) { clientKeyCertChainPathStream = IOUtils.getURL(clientKeyCertChainPath).openStream(); @@ -186,6 +191,7 @@ public class SslConfig extends AbstractConfig { this.clientKeyCertChainPathStream = clientKeyCertChainPathStream; } + @Transient public InputStream getClientPrivateKeyPathStream() throws IOException { if (clientPrivateKeyPath != null) { clientPrivateKeyPathStream = IOUtils.getURL(clientPrivateKeyPath).openStream(); @@ -197,6 +203,7 @@ public class SslConfig extends AbstractConfig { this.clientPrivateKeyPathStream = clientPrivateKeyPathStream; } + @Transient public InputStream getClientTrustCertCollectionPathStream() throws IOException { if (clientTrustCertCollectionPath != null) { clientTrustCertCollectionPathStream = IOUtils.getURL(clientTrustCertCollectionPath).openStream(); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java index da0a6ce94e..81a767d1a1 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java @@ -16,7 +16,9 @@ */ package org.apache.dubbo.config.nested; -public class AggregationConfig { +import java.io.Serializable; + +public class AggregationConfig implements Serializable { /** * Enable local aggregation or not diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java index 98da33cbd4..70310a7bba 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java @@ -18,7 +18,9 @@ package org.apache.dubbo.config.nested; import org.apache.dubbo.config.support.Nested; -public class PrometheusConfig { +import java.io.Serializable; + +public class PrometheusConfig implements Serializable { /** * Prometheus exporter configuration @@ -48,7 +50,7 @@ public class PrometheusConfig { this.pushgateway = pushgateway; } - public static class Exporter { + public static class Exporter implements Serializable { /** * Enable prometheus exporter @@ -116,7 +118,7 @@ public class PrometheusConfig { } } - public static class Pushgateway { + public static class Pushgateway implements Serializable { /** * Enable publishing via a Prometheus Pushgateway diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java index e48caf5ffb..86796a9139 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java @@ -52,6 +52,7 @@ import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.stub.StubSuppliers; import org.apache.dubbo.rpc.support.ProtocolUtils; +import java.beans.Transient; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -217,6 +218,7 @@ public class ReferenceConfig extends ReferenceConfigBase { } @Override + @Transient public T get() { if (destroyed) { throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!"); @@ -765,10 +767,12 @@ public class ReferenceConfig extends ReferenceConfigBase { * @return */ @Deprecated + @Transient public Invoker getInvoker() { return invoker; } + @Transient public Runnable getDestroyRunner() { return this::destroy; } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java index 473fd988e5..204d09777d 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java @@ -50,6 +50,7 @@ import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ServiceDescriptor; import org.apache.dubbo.rpc.service.GenericService; +import java.beans.Transient; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -927,6 +928,7 @@ public class ServiceConfig extends ServiceConfigBase { } } + @Transient public Runnable getDestroyRunner() { return this::unexport; } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java new file mode 100644 index 0000000000..0fa00839f7 --- /dev/null +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java @@ -0,0 +1,200 @@ +/* + * 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.qos.command.impl; + +import org.apache.dubbo.common.utils.JsonUtils; +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.ConfigCenterConfig; +import org.apache.dubbo.config.ConsumerConfig; +import org.apache.dubbo.config.MetadataReportConfig; +import org.apache.dubbo.config.MetricsConfig; +import org.apache.dubbo.config.ModuleConfig; +import org.apache.dubbo.config.MonitorConfig; +import org.apache.dubbo.config.ProtocolConfig; +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.ReferenceConfigBase; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.ServiceConfigBase; +import org.apache.dubbo.config.SslConfig; +import org.apache.dubbo.config.context.ConfigManager; +import org.apache.dubbo.config.context.ModuleConfigManager; +import org.apache.dubbo.qos.command.BaseCommand; +import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.model.ModuleModel; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@Cmd(name = "getConfig", + summary = "Get current running config.", + example = {"getConfig ReferenceConfig com.example.DemoService", "getConfig ApplicationConfig"}, + requiredPermissionLevel = PermissionLevel.PRIVATE) +public class GetConfig implements BaseCommand { + private final FrameworkModel frameworkModel; + + public GetConfig(FrameworkModel frameworkModel) { + this.frameworkModel = frameworkModel; + } + + @Override + public String execute(CommandContext commandContext, String[] args) { + boolean http = commandContext.isHttp(); + StringBuilder plainOutput = new StringBuilder(); + Map frameworkMap = new HashMap<>(); + + appendFrameworkConfig(args, plainOutput, frameworkMap); + + if (http) { + return JsonUtils.getJson().toJson(frameworkMap); + } else { + return plainOutput.toString(); + } + } + + private void appendFrameworkConfig(String[] args, StringBuilder plainOutput, Map frameworkMap) { + for (ApplicationModel applicationModel : frameworkModel.getApplicationModels()) { + Map applicationMap = new HashMap<>(); + frameworkMap.put(applicationModel.getDesc(), applicationMap); + plainOutput.append("ApplicationModel: ") + .append(applicationModel.getDesc()) + .append("\n"); + + ConfigManager configManager = applicationModel.getApplicationConfigManager(); + + appendApplicationConfigs(args, plainOutput, applicationModel, applicationMap, configManager); + } + } + + private static void appendApplicationConfigs(String[] args, StringBuilder plainOutput, ApplicationModel applicationModel, Map applicationMap, ConfigManager configManager) { + Optional applicationConfig = configManager.getApplication(); + applicationConfig.ifPresent(config -> appendConfig("ApplicationConfig", config.getName(), config, plainOutput, applicationMap, args)); + + for (ProtocolConfig protocol : configManager.getProtocols()) { + appendConfigs("ProtocolConfig", protocol.getName(), protocol, plainOutput, applicationMap, args); + } + + for (RegistryConfig registry : configManager.getRegistries()) { + appendConfigs("RegistryConfig", registry.getId(), registry, plainOutput, applicationMap, args); + } + + for (MetadataReportConfig metadataConfig : configManager.getMetadataConfigs()) { + appendConfigs("MetadataReportConfig", metadataConfig.getId(), metadataConfig, plainOutput, applicationMap, args); + } + + for (ConfigCenterConfig configCenter : configManager.getConfigCenters()) { + appendConfigs("ConfigCenterConfig", configCenter.getId(), configCenter, plainOutput, applicationMap, args); + } + + Optional metricsConfig = configManager.getMetrics(); + metricsConfig.ifPresent(config -> appendConfig("MetricsConfig", config.getId(), config, plainOutput, applicationMap, args)); + + Optional monitorConfig = configManager.getMonitor(); + monitorConfig.ifPresent(config -> appendConfig("MonitorConfig", config.getId(), config, plainOutput, applicationMap, args)); + + Optional sslConfig = configManager.getSsl(); + sslConfig.ifPresent(config -> appendConfig("SslConfig", config.getId(), config, plainOutput, applicationMap, args)); + + for (ModuleModel moduleModel : applicationModel.getModuleModels()) { + Map moduleMap = new HashMap<>(); + applicationMap.put(moduleModel.getDesc(), moduleMap); + plainOutput.append("ModuleModel: ") + .append(moduleModel.getDesc()) + .append("\n"); + + ModuleConfigManager moduleConfigManager = moduleModel.getConfigManager(); + + appendModuleConfigs(args, plainOutput, moduleMap, moduleConfigManager); + } + } + + private static void appendModuleConfigs(String[] args, StringBuilder plainOutput, Map moduleMap, ModuleConfigManager moduleConfigManager) { + for (ProviderConfig provider : moduleConfigManager.getProviders()) { + appendConfigs("ProviderConfig", provider.getId(), provider, plainOutput, moduleMap, args); + } + + for (ConsumerConfig consumer : moduleConfigManager.getConsumers()) { + appendConfigs("ConsumerConfig", consumer.getId(), consumer, plainOutput, moduleMap, args); + } + + Optional moduleConfig = moduleConfigManager.getModule(); + moduleConfig.ifPresent(config -> appendConfig("ModuleConfig", config.getId(), config, plainOutput, moduleMap, args)); + + for (ServiceConfigBase service : moduleConfigManager.getServices()) { + appendConfigs("ServiceConfig", service.getUniqueServiceName(), service, plainOutput, moduleMap, args); + } + + for (ReferenceConfigBase reference : moduleConfigManager.getReferences()) { + appendConfigs("ReferenceConfig", reference.getUniqueServiceName(), reference, plainOutput, moduleMap, args); + } + } + + @SuppressWarnings("unchecked") + private static void appendConfigs(String type, String id, Object config, StringBuilder plainOutput, Map map, String[] args) { + if (!isMatch(type, id, args)) { + return; + } + + plainOutput.append(type).append(": ") + .append(id) + .append("\n") + .append(config) + .append("\n\n"); + + Map typeMap = (Map) map.computeIfAbsent(type, k -> new HashMap()); + typeMap.put(id, config); + } + + private static void appendConfig(String type, String id, Object config, StringBuilder plainOutput, Map map, String[] args) { + if (!isMatch(type, id, args)) { + return; + } + + plainOutput.append(type).append(": ") + .append(id) + .append("\n") + .append(config) + .append("\n\n"); + + map.put(type, config); + } + + private static boolean isMatch(String type, String id, String[] args) { + if (args == null) { + return true; + } + switch (args.length) { + case 1: + if (!Objects.equals(args[0], type)) { + return false; + } + break; + case 2: + if (!Objects.equals(args[0], type) || !Objects.equals(args[1], id)) { + return false; + } + break; + default: + } + return true; + } +} diff --git a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand index aec45f93ac..c28bf0d97b 100644 --- a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand +++ b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand @@ -34,3 +34,4 @@ switchLogger=org.apache.dubbo.qos.command.impl.SwitchLogger switchLogLevel=org.apache.dubbo.qos.command.impl.SwitchLogLevel serializeCheckStatus=org.apache.dubbo.qos.command.impl.SerializeCheckStatus serializeWarnedClasses=org.apache.dubbo.qos.command.impl.SerializeWarnedClasses +getConfig=org.apache.dubbo.qos.command.impl.GetConfig diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java new file mode 100644 index 0000000000..bbdc5c255a --- /dev/null +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java @@ -0,0 +1,140 @@ +/* + * 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.qos.command.impl; + +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.ConfigCenterConfig; +import org.apache.dubbo.config.ConsumerConfig; +import org.apache.dubbo.config.MetadataReportConfig; +import org.apache.dubbo.config.MetricsConfig; +import org.apache.dubbo.config.ModuleConfig; +import org.apache.dubbo.config.MonitorConfig; +import org.apache.dubbo.config.ProtocolConfig; +import org.apache.dubbo.config.ProviderConfig; +import org.apache.dubbo.config.ReferenceConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.ServiceConfig; +import org.apache.dubbo.config.SslConfig; +import org.apache.dubbo.metadata.MetadataService; +import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.model.ModuleModel; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class GetConfigTest { + @Test + void testAll(){ + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel1 = frameworkModel.newApplication(); + + applicationModel1.getApplicationConfigManager().setApplication(new ApplicationConfig("app1")); + applicationModel1.getApplicationConfigManager().addProtocol(new ProtocolConfig("dubbo", 12345)); + applicationModel1.getApplicationConfigManager().addRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); + applicationModel1.getApplicationConfigManager().addMetadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181")); + ConfigCenterConfig configCenterConfig = new ConfigCenterConfig(); + configCenterConfig.setAddress("zookeeper://127.0.0.1:2181"); + applicationModel1.getApplicationConfigManager().addConfigCenter(configCenterConfig); + applicationModel1.getApplicationConfigManager().setMetrics(new MetricsConfig()); + applicationModel1.getApplicationConfigManager().setMonitor(new MonitorConfig()); + applicationModel1.getApplicationConfigManager().setSsl(new SslConfig()); + + ModuleModel moduleModel = applicationModel1.newModule(); + moduleModel.getConfigManager().setModule(new ModuleConfig()); + moduleModel.getConfigManager().addConsumer(new ConsumerConfig()); + moduleModel.getConfigManager().addProvider(new ProviderConfig()); + ReferenceConfig referenceConfig = new ReferenceConfig<>(); + referenceConfig.setInterface(MetadataService.class); + moduleModel.getConfigManager().addReference(referenceConfig); + ServiceConfig serviceConfig = new ServiceConfig<>(); + serviceConfig.setInterface(MetadataService.class); + moduleModel.getConfigManager().addService(serviceConfig); + + CommandContext commandContext = new CommandContext("getConfig"); + commandContext.setHttp(true); + + Assertions.assertNotNull(new GetConfig(frameworkModel).execute(commandContext, null)); + } + + @Test + void testFilter1(){ + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel1 = frameworkModel.newApplication(); + + applicationModel1.getApplicationConfigManager().setApplication(new ApplicationConfig("app1")); + applicationModel1.getApplicationConfigManager().addProtocol(new ProtocolConfig("dubbo", 12345)); + applicationModel1.getApplicationConfigManager().addRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); + applicationModel1.getApplicationConfigManager().addMetadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181")); + ConfigCenterConfig configCenterConfig = new ConfigCenterConfig(); + configCenterConfig.setAddress("zookeeper://127.0.0.1:2181"); + applicationModel1.getApplicationConfigManager().addConfigCenter(configCenterConfig); + applicationModel1.getApplicationConfigManager().setMetrics(new MetricsConfig()); + applicationModel1.getApplicationConfigManager().setMonitor(new MonitorConfig()); + applicationModel1.getApplicationConfigManager().setSsl(new SslConfig()); + + ModuleModel moduleModel = applicationModel1.newModule(); + moduleModel.getConfigManager().setModule(new ModuleConfig()); + moduleModel.getConfigManager().addConsumer(new ConsumerConfig()); + moduleModel.getConfigManager().addProvider(new ProviderConfig()); + ReferenceConfig referenceConfig = new ReferenceConfig<>(); + referenceConfig.setInterface(MetadataService.class); + moduleModel.getConfigManager().addReference(referenceConfig); + ServiceConfig serviceConfig = new ServiceConfig<>(); + serviceConfig.setInterface(MetadataService.class); + moduleModel.getConfigManager().addService(serviceConfig); + + CommandContext commandContext = new CommandContext("getConfig"); + commandContext.setHttp(true); + + Assertions.assertNotNull(new GetConfig(frameworkModel).execute(commandContext, new String[]{"ApplicationConfig"})); + } + + @Test + void testFilter2(){ + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel1 = frameworkModel.newApplication(); + + applicationModel1.getApplicationConfigManager().setApplication(new ApplicationConfig("app1")); + applicationModel1.getApplicationConfigManager().addProtocol(new ProtocolConfig("dubbo", 12345)); + applicationModel1.getApplicationConfigManager().addRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); + applicationModel1.getApplicationConfigManager().addMetadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181")); + ConfigCenterConfig configCenterConfig = new ConfigCenterConfig(); + configCenterConfig.setAddress("zookeeper://127.0.0.1:2181"); + applicationModel1.getApplicationConfigManager().addConfigCenter(configCenterConfig); + applicationModel1.getApplicationConfigManager().setMetrics(new MetricsConfig()); + applicationModel1.getApplicationConfigManager().setMonitor(new MonitorConfig()); + applicationModel1.getApplicationConfigManager().setSsl(new SslConfig()); + + ModuleModel moduleModel = applicationModel1.newModule(); + moduleModel.getConfigManager().setModule(new ModuleConfig()); + moduleModel.getConfigManager().addConsumer(new ConsumerConfig()); + moduleModel.getConfigManager().addProvider(new ProviderConfig()); + ReferenceConfig referenceConfig = new ReferenceConfig<>(); + referenceConfig.setInterface(MetadataService.class); + moduleModel.getConfigManager().addReference(referenceConfig); + ServiceConfig serviceConfig = new ServiceConfig<>(); + serviceConfig.setInterface(MetadataService.class); + moduleModel.getConfigManager().addService(serviceConfig); + + CommandContext commandContext = new CommandContext("getConfig"); + commandContext.setHttp(true); + + Assertions.assertNotNull(new GetConfig(frameworkModel).execute(commandContext, new String[]{"ProtocolConfig", "dubbo"})); + } +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java index 92c4fdea1c..a98333af29 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java @@ -16,9 +16,6 @@ */ package org.apache.dubbo.qos.command.util; -import java.util.LinkedList; -import java.util.List; - import org.apache.dubbo.qos.command.GreetingCommand; import org.apache.dubbo.qos.command.impl.ChangeTelnet; import org.apache.dubbo.qos.command.impl.CountTelnet; @@ -28,6 +25,7 @@ import org.apache.dubbo.qos.command.impl.DisableSimpleProfiler; import org.apache.dubbo.qos.command.impl.EnableDetailProfiler; import org.apache.dubbo.qos.command.impl.EnableRouterSnapshot; import org.apache.dubbo.qos.command.impl.EnableSimpleProfiler; +import org.apache.dubbo.qos.command.impl.GetConfig; import org.apache.dubbo.qos.command.impl.GetEnabledRouterSnapshot; import org.apache.dubbo.qos.command.impl.GetRecentRouterSnapshot; import org.apache.dubbo.qos.command.impl.GetRouterSnapshot; @@ -57,8 +55,12 @@ import org.apache.dubbo.qos.command.impl.SwitchLogLevel; import org.apache.dubbo.qos.command.impl.SwitchLogger; import org.apache.dubbo.qos.command.impl.Version; import org.apache.dubbo.rpc.model.FrameworkModel; + import org.junit.jupiter.api.Test; +import java.util.LinkedList; +import java.util.List; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; @@ -118,6 +120,7 @@ class CommandHelperTest { expectedClasses.add(SwitchLogLevel.class); expectedClasses.add(SerializeCheckStatus.class); expectedClasses.add(SerializeWarnedClasses.class); + expectedClasses.add(GetConfig.class); assertThat(classes, containsInAnyOrder(expectedClasses.toArray(new Class[0]))); } From a70cc277008edeba7c5b800a66addfa8afb5f436 Mon Sep 17 00:00:00 2001 From: aamingaa <49740762+aamingaa@users.noreply.github.com> Date: Mon, 27 Feb 2023 13:09:10 +0800 Subject: [PATCH 038/144] feat: optimize code (#11671) --- .../org/apache/dubbo/rpc/cluster/ConfiguratorFactory.java | 3 ++- .../java/org/apache/dubbo/rpc/cluster/RouterFactory.java | 3 ++- .../dubbo/rpc/cluster/router/state/StateRouterFactory.java | 3 ++- .../dubbo/common/extension/AdaptiveClassCodeGenerator.java | 7 ++++--- .../com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java | 3 ++- .../dubbo/metrics/report/MetricsReporterFactory.java | 3 ++- .../main/java/org/apache/dubbo/monitor/MonitorFactory.java | 3 ++- 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory.java index 8b2722c29f..031f597dc0 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/ConfiguratorFactory.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.cluster; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.common.extension.SPI; @@ -33,7 +34,7 @@ public interface ConfiguratorFactory { * @param url - configurator url. * @return configurator instance. */ - @Adaptive("protocol") + @Adaptive(CommonConstants.PROTOCOL_KEY) Configurator getConfigurator(URL url); } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory.java index 3a98a587a3..c84a27c2f4 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterFactory.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.cluster; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.common.extension.SPI; @@ -42,6 +43,6 @@ public interface RouterFactory { * @param url url * @return router instance */ - @Adaptive("protocol") + @Adaptive(CommonConstants.PROTOCOL_KEY) Router getRouter(URL url); } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory.java index 7f61f36d1f..5a7b779422 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.cluster.router.state; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.common.extension.SPI; @@ -29,6 +30,6 @@ public interface StateRouterFactory { * @return router instance * @since 3.0 */ - @Adaptive("protocol") + @Adaptive(CommonConstants.PROTOCOL_KEY) StateRouter getRouter(Class interfaceClass, URL url); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java index 1a4e1f88e2..514ba91407 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java @@ -17,6 +17,7 @@ package org.apache.dubbo.common.extension; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.StringUtils; @@ -268,7 +269,7 @@ public class AdaptiveClassCodeGenerator { for (int i = value.length - 1; i >= 0; --i) { if (i == value.length - 1) { if (null != defaultExtName) { - if (!"protocol".equals(value[i])) { + if (!CommonConstants.PROTOCOL_KEY.equals(value[i])) { if (hasInvocation) { getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName); } else { @@ -278,7 +279,7 @@ public class AdaptiveClassCodeGenerator { getNameCode = String.format("( url.getProtocol() == null ? \"%s\" : url.getProtocol() )", defaultExtName); } } else { - if (!"protocol".equals(value[i])) { + if (!CommonConstants.PROTOCOL_KEY.equals(value[i])) { if (hasInvocation) { getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName); } else { @@ -289,7 +290,7 @@ public class AdaptiveClassCodeGenerator { } } } else { - if (!"protocol".equals(value[i])) { + if (!CommonConstants.PROTOCOL_KEY.equals(value[i])) { if (hasInvocation) { getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName); } else { diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java index 094a4d7c72..087f8c6e8d 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java @@ -17,12 +17,13 @@ package com.alibaba.dubbo.rpc.cluster; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.rpc.cluster.Configurator; @Deprecated public interface ConfiguratorFactory extends org.apache.dubbo.rpc.cluster.ConfiguratorFactory { - @Adaptive("protocol") + @Adaptive(CommonConstants.PROTOCOL_KEY) com.alibaba.dubbo.rpc.cluster.Configurator getConfigurator(com.alibaba.dubbo.common.URL url); @Override diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/report/MetricsReporterFactory.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/report/MetricsReporterFactory.java index 4f6066e1f3..21efe4762f 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/report/MetricsReporterFactory.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/report/MetricsReporterFactory.java @@ -18,6 +18,7 @@ package org.apache.dubbo.metrics.report; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.common.extension.ExtensionScope; import org.apache.dubbo.common.extension.SPI; @@ -34,6 +35,6 @@ public interface MetricsReporterFactory { * @param url URL * @return Metrics reporter implementation. */ - @Adaptive({"protocol"}) + @Adaptive({CommonConstants.PROTOCOL_KEY}) MetricsReporter createMetricsReporter(URL url); } diff --git a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorFactory.java b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorFactory.java index 3e13196ff4..0571d97323 100644 --- a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorFactory.java +++ b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorFactory.java @@ -17,6 +17,7 @@ package org.apache.dubbo.monitor; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.common.extension.SPI; @@ -32,7 +33,7 @@ public interface MonitorFactory { * @param url * @return monitor */ - @Adaptive("protocol") + @Adaptive(CommonConstants.PROTOCOL_KEY) Monitor getMonitor(URL url); } From 4be3c796cc0be52daa21b70c4cbb48413f3fe481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=AA=E4=B8=8D=E7=9F=A5=E5=90=8D=E7=9A=84Java?= =?UTF-8?q?=E9=9D=93=E4=BB=94?= Date: Mon, 27 Feb 2023 14:25:39 +0800 Subject: [PATCH 039/144] optimize the multi params request performance of triple in wrap mode (#11672) --- .../dubbo/rpc/protocol/tri/ReflectionPackableMethod.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java index 8667beb87a..52e6afc01f 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java @@ -390,11 +390,12 @@ public class ReflectionPackableMethod implements PackableMethod { for (String type : argumentsType) { builder.addArgTypes(type); } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); for (int i = 0; i < arguments.length; i++) { Object argument = arguments[i]; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); multipleSerialization.serialize(url, serialize, actualRequestTypes[i], argument, bos); builder.addArgs(bos.toByteArray()); + bos.reset(); } return builder.build().toByteArray(); } From f8f89f2a712b8cc61f542c19f24e410e650eb8da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=AA=E4=B8=8D=E7=9F=A5=E5=90=8D=E7=9A=84Java?= =?UTF-8?q?=E9=9D=93=E4=BB=94?= Date: Mon, 27 Feb 2023 14:38:57 +0800 Subject: [PATCH 040/144] replaced with EN assert (#11670) --- .../dubbo/rpc/protocol/tri/TripleCustomerProtocolWapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleCustomerProtocolWapper.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleCustomerProtocolWapper.java index 78eb166f60..e9479375f3 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleCustomerProtocolWapper.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleCustomerProtocolWapper.java @@ -344,7 +344,7 @@ public class TripleCustomerProtocolWapper { } public Builder addArgTypes(String argsType) { - Assert.notEmptyString(argsType, "argsType不能为空"); + Assert.notEmptyString(argsType, "argsType cannot be empty."); argTypes.add(argsType); return this; } From e74c6381fb9ac676607d8495e4e3d98c828344d1 Mon Sep 17 00:00:00 2001 From: songxiaosheng <81170548+songxiaosheng@users.noreply.github.com> Date: Mon, 27 Feb 2023 19:32:53 +0800 Subject: [PATCH 041/144] :recycle:refact metrics key and meter unit (#11661) --- .../dubbo/metrics/model/MetricsKey.java | 27 ++++++------------- .../collector/stat/MetadataStatComposite.java | 12 ++++----- .../MetadataMetricsCollectorTest.java | 22 +++++++-------- .../collector/stat/RegistryStatComposite.java | 12 ++++----- .../RegistryMetricsCollectorTest.java | 10 +++---- .../collector/RegistryMetricsSampleTest.java | 10 +++---- 6 files changed, 40 insertions(+), 53 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java index 39cecbfe49..0e3e160a1b 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java @@ -38,26 +38,15 @@ public enum MetricsKey { METRIC_REQUESTS_LIMIT_AGG("dubbo.%s.requests.limit.aggregate", "Aggregated limit Requests"), METRIC_REQUESTS_TOTAL_FAILED_AGG("dubbo.%s.requests.failed.total.aggregate", "Aggregated failed total Requests"), - METRIC_QPS("dubbo.%s.qps.seconds", "Query Per Seconds"), - METRIC_RT_LAST("dubbo.%s.rt.seconds.last", "Last Response Time"), - METRIC_RT_MIN("dubbo.%s.rt.seconds.min", "Min Response Time"), - METRIC_RT_MAX("dubbo.%s.rt.seconds.max", "Max Response Time"), - METRIC_RT_SUM("dubbo.%s.rt.seconds.sum", "Sum Response Time"), - METRIC_RT_AVG("dubbo.%s.rt.seconds.avg", "Average Response Time"), - METRIC_RT_P99("dubbo.%s.rt.seconds.p99", "Response Time P99"), - METRIC_RT_P95("dubbo.%s.rt.seconds.p95", "Response Time P95"), + METRIC_QPS("dubbo.%s.qps.total", "Query Per Seconds"), + METRIC_RT_LAST("dubbo.%s.rt.milliseconds.last", "Last Response Time"), + METRIC_RT_MIN("dubbo.%s.rt.milliseconds.min", "Min Response Time"), + METRIC_RT_MAX("dubbo.%s.rt.milliseconds.max", "Max Response Time"), + METRIC_RT_SUM("dubbo.%s.rt.milliseconds.sum", "Sum Response Time"), + METRIC_RT_AVG("dubbo.%s.rt.milliseconds.avg", "Average Response Time"), + METRIC_RT_P99("dubbo.%s.rt.milliseconds.p99", "Response Time P99"), + METRIC_RT_P95("dubbo.%s.rt.milliseconds.p95", "Response Time P95"), - GENERIC_METRIC_REQUESTS("dubbo.%s.requests.total", "Total %s Requests"), - GENERIC_METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Succeed %s Requests"), - GENERIC_METRIC_REQUESTS_FAILED("dubbo.%s.requests.failed.total", "Failed %s Requests"), - - GENERIC_METRIC_RT_LAST("dubbo.%s.rt.seconds.last", "Last Response Time"), - GENERIC_METRIC_RT_MIN("dubbo.%s.rt.seconds.min", "Min Response Time"), - GENERIC_METRIC_RT_MAX("dubbo.%s.rt.seconds.max", "Max Response Time"), - GENERIC_METRIC_RT_SUM("dubbo.%s.rt.seconds.sum", "Sum Response Time"), - GENERIC_METRIC_RT_AVG("dubbo.%s.rt.seconds.avg", "Average Response Time"), - GENERIC_METRIC_RT_P99("dubbo.%s.rt.seconds.p99", "Response Time P99"), - GENERIC_METRIC_RT_P95("dubbo.%s.rt.seconds.p95", "Response Time P95"), // register metrics key REGISTER_METRIC_REQUESTS("dubbo.registry.register.requests.total", "Total Register Requests"), diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java index 83cdbb855c..c017565158 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java @@ -62,14 +62,14 @@ public class MetadataStatComposite implements MetricsExport { private List> initStats(String registryOpType) { List> singleRtStats = new ArrayList<>(); - singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_LAST))); - singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MIN), new LongAccumulator(Long::min, Long.MAX_VALUE))); - singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MAX), new LongAccumulator(Long::max, Long.MIN_VALUE))); - singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_SUM), (responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime))); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_LAST))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MIN), new LongAccumulator(Long::min, Long.MAX_VALUE))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MAX), new LongAccumulator(Long::max, Long.MIN_VALUE))); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_SUM), (responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime))); // AvgContainer is a special counter that stores the number of times but outputs function of sum/times - AtomicLongContainer avgContainer = new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_AVG), (k, v) -> v.incrementAndGet()); + AtomicLongContainer avgContainer = new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_AVG), (k, v) -> v.incrementAndGet()); avgContainer.setValueSupplier(applicationName -> { - LongContainer totalContainer = rtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.GENERIC_METRIC_RT_SUM, registryOpType)).findFirst().get(); + LongContainer totalContainer = rtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.METRIC_RT_SUM, registryOpType)).findFirst().get(); AtomicLong totalRtTimes = avgContainer.get(applicationName); AtomicLong totalRtSum = (AtomicLong) totalContainer.get(applicationName); return totalRtSum.get() / totalRtTimes.get(); diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java index a07712bccd..bf4cfcbdb6 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java @@ -17,8 +17,6 @@ package metrics.metrics.collector; -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.metrics.metadata.collector.MetadataMetricsCollector; @@ -107,11 +105,11 @@ class MetadataMetricsCollectorTest { return number.longValue(); })); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc()); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), c1 + c2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.METRIC_RT_LAST).targetKey()), lastTimePair.calc()); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.METRIC_RT_SUM).targetKey()), c1 + c2); } @Test @@ -157,11 +155,11 @@ class MetadataMetricsCollectorTest { return number.longValue(); })); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc()); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), c1 + c2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.METRIC_RT_LAST).targetKey()), lastTimePair.calc()); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.METRIC_RT_SUM).targetKey()), c1 + c2); } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java index 1d955cd7a7..16ad947a92 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java @@ -65,14 +65,14 @@ public class RegistryStatComposite implements MetricsExport { private List> initStats(String registryOpType) { List> singleRtStats = new ArrayList<>(); - singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_LAST))); - singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MIN), new LongAccumulator(Long::min, Long.MAX_VALUE))); - singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_MAX), new LongAccumulator(Long::max, Long.MIN_VALUE))); - singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_SUM), (responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime))); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_LAST))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MIN), new LongAccumulator(Long::min, Long.MAX_VALUE))); + singleRtStats.add(new LongAccumulatorContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_MAX), new LongAccumulator(Long::max, Long.MIN_VALUE))); + singleRtStats.add(new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_SUM), (responseTime, longAccumulator) -> longAccumulator.addAndGet(responseTime))); // AvgContainer is a special counter that stores the number of times but outputs function of sum/times - AtomicLongContainer avgContainer = new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.GENERIC_METRIC_RT_AVG), (k, v) -> v.incrementAndGet()); + AtomicLongContainer avgContainer = new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_AVG), (k, v) -> v.incrementAndGet()); avgContainer.setValueSupplier(applicationName -> { - LongContainer totalContainer = rtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.GENERIC_METRIC_RT_SUM, registryOpType)).findFirst().get(); + LongContainer totalContainer = rtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.METRIC_RT_SUM, registryOpType)).findFirst().get(); AtomicLong totalRtTimes = avgContainer.get(applicationName); AtomicLong totalRtSum = (AtomicLong) totalContainer.get(applicationName); return totalRtSum.get() / totalRtTimes.get(); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java index d4e8f34cec..2789758812 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java @@ -103,11 +103,11 @@ class RegistryMetricsCollectorTest { return number.longValue(); })); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), lastTimePair.calc()); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), c1 + c2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_LAST).targetKey()), lastTimePair.calc()); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_MAX).targetKey()), Math.max(c1, c2)); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_AVG).targetKey()), (c1 + c2) / 2); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_SUM).targetKey()), c1 + c2); } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java index 92025d71c9..87c89ec4f2 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java @@ -79,11 +79,11 @@ class RegistryMetricsSampleTest { return number.longValue(); })); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_LAST).targetKey()), 0L); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MIN).targetKey()), 0L); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_MAX).targetKey()), 10L); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_AVG).targetKey()), 5L); - Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.GENERIC_METRIC_RT_SUM).targetKey()), 10L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.METRIC_RT_LAST).targetKey()), 0L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.METRIC_RT_MIN).targetKey()), 0L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.METRIC_RT_MAX).targetKey()), 10L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.METRIC_RT_AVG).targetKey()), 5L); + Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.METRIC_RT_SUM).targetKey()), 10L); } @Test From 7e51047cb084a9f9b09d934cf058074c534503f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=94=E7=AD=89=E5=90=8C=E5=AD=A6?= <37730787+erdengk@users.noreply.github.com> Date: Mon, 27 Feb 2023 20:09:15 +0800 Subject: [PATCH 042/144] delete never thrown exception (#11674) --- .../filter/DefaultFilterChainBuilderTest.java | 6 +-- .../support/AbstractClusterInvokerTest.java | 8 ++-- .../rpc/cluster/support/ClusterUtilsTest.java | 2 +- .../DefaultProviderURLMergeProcessorTest.java | 2 +- .../dubbo/common/bytecode/MixinTest.java | 4 +- .../support/JavassistCompilerTest.java | 4 +- .../compiler/support/JdkCompilerTest.java | 10 ++--- .../AbstractDynamicConfigurationTest.java | 14 +++---- .../org/apache/dubbo/common/io/BytesTest.java | 6 +-- .../GlobalResourcesRepositoryTest.java | 4 +- .../status/support/LoadStatusCheckerTest.java | 4 +- .../support/MemoryStatusCheckerTest.java | 4 +- .../threadlocal/InternalThreadLocalTest.java | 8 ++-- .../MemoryLimitedLinkedBlockingQueueTest.java | 4 +- .../MemorySafeLinkedBlockingQueueTest.java | 4 +- .../support/AbortPolicyWithReportTest.java | 8 ++-- .../support/cached/CachedThreadPoolTest.java | 4 +- .../eager/EagerThreadPoolExecutorTest.java | 6 +-- .../support/eager/EagerThreadPoolTest.java | 4 +- .../limited/LimitedThreadPoolTest.java | 4 +- .../common/utils/AnnotationUtilsTest.java | 4 +- .../dubbo/common/utils/ArrayUtilsTest.java | 6 +-- .../utils/AtomicPositiveIntegerTest.java | 22 +++++----- .../dubbo/common/utils/ClassUtilsTest.java | 14 +++---- .../common/utils/CollectionUtilsTest.java | 28 ++++++------- .../dubbo/common/utils/LFUCacheTest.java | 10 ++--- .../dubbo/common/utils/LRU2CacheTest.java | 6 +-- .../dubbo/common/utils/LogHelperTest.java | 12 +++--- .../apache/dubbo/common/utils/LogTest.java | 10 ++--- .../dubbo/common/utils/LogUtilTest.java | 18 ++++---- .../dubbo/common/utils/MemberUtilsTest.java | 2 +- .../dubbo/common/utils/NetUtilsTest.java | 42 +++++++++---------- .../dubbo/common/utils/ParametersTest.java | 4 +- .../dubbo/config/ApplicationConfigTest.java | 32 +++++++------- .../dubbo/config/ArgumentConfigTest.java | 8 ++-- .../apache/dubbo/config/MethodConfigTest.java | 30 ++++++------- .../dubbo/config/AbstractConfigTest.java | 34 +++++++-------- .../config/AbstractMethodConfigTest.java | 24 +++++------ .../config/AbstractReferenceConfigTest.java | 32 +++++++------- .../config/AbstractServiceConfigTest.java | 40 +++++++++--------- .../dubbo/config/ApplicationConfigTest.java | 30 ++++++------- .../dubbo/config/ArgumentConfigTest.java | 10 ++--- .../apache/dubbo/config/cache/CacheTest.java | 4 +- .../DelegateProviderMetaDataInvokerTest.java | 4 +- .../issues/issue6000/Issue6000Test.java | 4 +- .../issues/issue6252/Issue6252Test.java | 4 +- .../issues/issue7003/Issue7003Test.java | 4 +- .../support/jcache/JCacheFactoryTest.java | 4 +- .../KubernetesServiceDiscoveryTest.java | 4 +- .../AbstractServiceNameMappingTest.java | 2 +- .../support/AbstractMetadataReportTest.java | 14 +++---- .../AbstractAnnotationProcessingTest.java | 2 +- .../store/nacos/MockConfigService.java | 16 +++---- .../store/redis/RedisMetadataReportTest.java | 2 +- .../ObservationReceiverFilterTest.java | 2 +- .../ObservationSenderFilterTest.java | 2 +- .../dubbo/monitor/dubbo/DubboMonitorTest.java | 4 +- .../monitor/dubbo/MetricsFilterTest.java | 6 +-- .../command/CommandContextFactoryTest.java | 4 +- .../command/DefaultCommandExecutorTest.java | 6 +-- .../decoder/HttpCommandDecoderTest.java | 6 +-- .../dubbo/qos/command/impl/HelpTest.java | 6 +-- .../MetadataServiceNameMappingTest.java | 2 +- .../migration/MigrationRuleListenerTest.java | 4 +- .../support/AbstractRegistryFactoryTest.java | 6 +-- .../support/AbstractRegistryTest.java | 3 +- .../exchange/support/DefaultFutureTest.java | 2 +- .../remoting/transport/AbstractCodecTest.java | 4 +- .../transport/netty/ClientToServerTest.java | 2 +- .../transport/netty/NettyStringTest.java | 4 +- .../AbstractZookeeperTransporterTest.java | 10 ++--- .../curator/CuratorZookeeperClientTest.java | 10 ++--- .../AbstractZookeeperTransporterTest.java | 10 ++--- .../rpc/filter/ActiveLimitFilterTest.java | 4 +- .../rpc/filter/tps/DefaultTPSLimiterTest.java | 8 ++-- .../dubbo/rpc/proxy/AbstractProxyTest.java | 4 +- .../protocol/dubbo/ArgumentCallbackTest.java | 6 +-- .../dubbo/DubboInvokerAvailableTest.java | 4 +- .../rpc/protocol/dubbo/DubboProtocolTest.java | 10 ++--- .../rpc/protocol/injvm/InjvmProtocolTest.java | 6 +-- .../xds/util/bootstrap/BootstrapperTest.java | 2 +- 81 files changed, 364 insertions(+), 365 deletions(-) diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java index a07a4157be..afe93b7a2a 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java @@ -43,7 +43,7 @@ class DefaultFilterChainBuilderTest { urlWithoutFilter = urlWithoutFilter.setScopeModel(ApplicationModel.defaultModel()); AbstractInvoker invokerWithoutFilter = new AbstractInvoker(DemoService.class, urlWithoutFilter) { @Override - protected Result doInvoke(Invocation invocation) throws Throwable { + protected Result doInvoke(Invocation invocation) { return null; } }; @@ -58,7 +58,7 @@ class DefaultFilterChainBuilderTest { urlWithFilter = urlWithFilter.setScopeModel(ApplicationModel.defaultModel()); AbstractInvoker invokerWithFilter = new AbstractInvoker(DemoService.class, urlWithFilter) { @Override - protected Result doInvoke(Invocation invocation) throws Throwable { + protected Result doInvoke(Invocation invocation) { return null; } }; @@ -93,7 +93,7 @@ class DefaultFilterChainBuilderTest { urlWithFilter = urlWithFilter.setScopeModel(ApplicationModel.defaultModel()); AbstractInvoker invokerWithFilter = new AbstractInvoker(DemoService.class, urlWithFilter) { @Override - protected Result doInvoke(Invocation invocation) throws Throwable { + protected Result doInvoke(Invocation invocation) { return null; } }; diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java index 9028114aab..acf4804583 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java @@ -194,7 +194,7 @@ class AbstractClusterInvokerTest { } @Test - void testSelect_Invokersize0() throws Exception { + void testSelect_Invokersize0() { LoadBalance l = cluster.initLoadBalance(invokers, invocation); Assertions.assertNotNull(l,"cluster.initLoadBalance returns null!"); { @@ -228,7 +228,7 @@ class AbstractClusterInvokerTest { } @Test - void testSelect_Invokersize1() throws Exception { + void testSelect_Invokersize1() { invokers.clear(); invokers.add(invoker1); LoadBalance l = cluster.initLoadBalance(invokers, invocation); @@ -238,7 +238,7 @@ class AbstractClusterInvokerTest { } @Test - void testSelect_Invokersize2AndselectNotNull() throws Exception { + void testSelect_Invokersize2AndselectNotNull() { invokers.clear(); invokers.add(invoker2); invokers.add(invoker4); @@ -412,7 +412,7 @@ class AbstractClusterInvokerTest { } - public void testSelect_multiInvokers(String lbname) throws Exception { + public void testSelect_multiInvokers(String lbname) { int min = 100, max = 500; Double d = (Math.random() * (max - min + 1) + min); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ClusterUtilsTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ClusterUtilsTest.java index b8a5838c79..2f3bbe0e41 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ClusterUtilsTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ClusterUtilsTest.java @@ -55,7 +55,7 @@ class ClusterUtilsTest { } @Test - void testMergeUrl() throws Exception { + void testMergeUrl() { URL providerURL = URL.valueOf("dubbo://localhost:55555"); providerURL = providerURL.setPath("path") .setUsername("username") diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/merger/DefaultProviderURLMergeProcessorTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/merger/DefaultProviderURLMergeProcessorTest.java index 7b2a9abee3..9d3ce74e36 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/merger/DefaultProviderURLMergeProcessorTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/merger/DefaultProviderURLMergeProcessorTest.java @@ -57,7 +57,7 @@ class DefaultProviderURLMergeProcessorTest { } @Test - void testMergeUrl() throws Exception { + void testMergeUrl() { URL providerURL = URL.valueOf("dubbo://localhost:55555"); providerURL = providerURL.setPath("path") .setUsername("username") diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/MixinTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/MixinTest.java index 64cc7fc28f..2ad7ab35ae 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/MixinTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/MixinTest.java @@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class MixinTest { @Test - void testMain() throws Exception { + void testMain() { Mixin mixin = Mixin.mixin(new Class[]{I1.class, I2.class, I3.class}, new Class[]{C1.class, C2.class}); Object o = mixin.newInstance(new Object[]{new C1(), new C2()}); assertTrue(o instanceof I1); @@ -69,4 +69,4 @@ class MixinTest { System.out.println("setMixinInstance:" + mi); } } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java index 37c60165a7..7d03b57ad4 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java @@ -55,7 +55,7 @@ class JavassistCompilerTest extends JavaCodeTest { } @Test - void testCompileJavaClass1() throws Exception { + void testCompileJavaClass1() { Assertions.assertThrows(IllegalStateException.class, () -> { JavassistCompiler compiler = new JavassistCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax0(), JavassistCompiler.class.getClassLoader()); @@ -82,4 +82,4 @@ class JavassistCompilerTest extends JavaCodeTest { Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world3!", sayHello.invoke(instance)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java index 99633b1210..1f330ffb81 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java @@ -33,7 +33,7 @@ class JdkCompilerTest extends JavaCodeTest { } @Test - void test_compileJavaClass0() throws Exception { + void test_compileJavaClass0() { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader()); @@ -44,7 +44,7 @@ class JdkCompilerTest extends JavaCodeTest { } @Test - void test_compileJavaClass1() throws Exception { + void test_compileJavaClass1() { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader()); @@ -64,7 +64,7 @@ class JdkCompilerTest extends JavaCodeTest { } @Test - void test_compileJavaClass0_java8() throws Exception { + void test_compileJavaClass0_java8() { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler("1.8"); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader()); @@ -75,7 +75,7 @@ class JdkCompilerTest extends JavaCodeTest { } @Test - void test_compileJavaClass1_java8() throws Exception { + void test_compileJavaClass1_java8() { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler("1.8"); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader()); @@ -84,4 +84,4 @@ class JdkCompilerTest extends JavaCodeTest { Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); }); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java index 08afb8d05f..15367ec83c 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java @@ -52,17 +52,17 @@ class AbstractDynamicConfigurationTest { public void init() { configuration = new AbstractDynamicConfiguration(null) { @Override - protected String doGetConfig(String key, String group) throws Exception { + protected String doGetConfig(String key, String group) { return null; } @Override - protected void doClose() throws Exception { + protected void doClose() { } @Override - protected boolean doRemoveConfig(String key, String group) throws Exception { + protected boolean doRemoveConfig(String key, String group) { return false; } }; @@ -93,17 +93,17 @@ class AbstractDynamicConfigurationTest { AbstractDynamicConfiguration configuration = new AbstractDynamicConfiguration(url) { @Override - protected String doGetConfig(String key, String group) throws Exception { + protected String doGetConfig(String key, String group) { return null; } @Override - protected void doClose() throws Exception { + protected void doClose() { } @Override - protected boolean doRemoveConfig(String key, String group) throws Exception { + protected boolean doRemoveConfig(String key, String group) { return false; } }; @@ -202,4 +202,4 @@ class AbstractDynamicConfigurationTest { assertEquals(configuration.removeConfig(key, group), configuration.doRemoveConfig(key, group)); assertFalse(configuration.removeConfig(key, group)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/io/BytesTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/io/BytesTest.java index b57e1cb1c3..eb075f65ab 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/io/BytesTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/io/BytesTest.java @@ -32,7 +32,7 @@ class BytesTest { private byte[] bytes2 = {3, 12, 14, 41, 12, 2, 3, 12, 4, 67}; @Test - void testMain() throws Exception { + void testMain() { short s = (short) 0xabcd; assertThat(s, is(Bytes.bytes2short(Bytes.short2bytes(s)))); @@ -86,7 +86,7 @@ class BytesTest { } @Test - void testBase64S2b2sFailCaseLog() throws Exception { + void testBase64S2b2sFailCaseLog() { String s1 = Bytes.bytes2base64(bytes1); byte[] out1 = Bytes.base642bytes(s1); assertThat(bytes1, is(out1)); @@ -161,4 +161,4 @@ class BytesTest { bb[7] = (byte) (x >> 0); return bb; } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/resource/GlobalResourcesRepositoryTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/resource/GlobalResourcesRepositoryTest.java index c19a21b65f..e163dfbde1 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/resource/GlobalResourcesRepositoryTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/resource/GlobalResourcesRepositoryTest.java @@ -27,7 +27,7 @@ import java.util.concurrent.ExecutorService; class GlobalResourcesRepositoryTest { @Test - void test() throws NoSuchFieldException { + void test() { GlobalResourcesRepository repository = GlobalResourcesRepository.getInstance(); ExecutorService globalExecutorService = GlobalResourcesRepository.getGlobalExecutorService(); @@ -74,4 +74,4 @@ class GlobalResourcesRepositoryTest { return destroyed; } } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/LoadStatusCheckerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/LoadStatusCheckerTest.java index ebf87859b6..4d34e69a65 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/LoadStatusCheckerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/LoadStatusCheckerTest.java @@ -30,11 +30,11 @@ class LoadStatusCheckerTest { private static Logger logger = LoggerFactory.getLogger(LoadStatusCheckerTest.class); @Test - void test() throws Exception { + void test() { LoadStatusChecker statusChecker = new LoadStatusChecker(); Status status = statusChecker.check(); assertThat(status, notNullValue()); logger.info("load status level: " + status.getLevel()); logger.info("load status message: " + status.getMessage()); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/MemoryStatusCheckerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/MemoryStatusCheckerTest.java index ca624a9cd8..951cae0cc9 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/MemoryStatusCheckerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/status/support/MemoryStatusCheckerTest.java @@ -33,11 +33,11 @@ class MemoryStatusCheckerTest { private static final Logger logger = LoggerFactory.getLogger(MemoryStatusCheckerTest.class); @Test - void test() throws Exception { + void test() { MemoryStatusChecker statusChecker = new MemoryStatusChecker(); Status status = statusChecker.check(); assertThat(status.getLevel(), anyOf(is(OK), is(WARN))); logger.info("memory status level: " + status.getLevel()); logger.info("memory status message: " + status.getMessage()); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadlocal/InternalThreadLocalTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadlocal/InternalThreadLocalTest.java index 88960e6daf..5be0f0b579 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadlocal/InternalThreadLocalTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadlocal/InternalThreadLocalTest.java @@ -49,7 +49,7 @@ class InternalThreadLocalTest { } @Test - void testInternalThreadLocal() throws InterruptedException { + void testInternalThreadLocal() { final AtomicInteger index = new AtomicInteger(0); final InternalThreadLocal internalThreadLocal = new InternalThreadLocal() { @@ -71,7 +71,7 @@ class InternalThreadLocalTest { } @Test - void testRemoveAll() throws InterruptedException { + void testRemoveAll() { final InternalThreadLocal internalThreadLocal = new InternalThreadLocal(); internalThreadLocal.set(1); Assertions.assertEquals(1, (int)internalThreadLocal.get(), "set failed"); @@ -86,7 +86,7 @@ class InternalThreadLocalTest { } @Test - void testSize() throws InterruptedException { + void testSize() { final InternalThreadLocal internalThreadLocal = new InternalThreadLocal(); internalThreadLocal.set(1); Assertions.assertEquals(1, InternalThreadLocal.size(), "size method is wrong!"); @@ -120,7 +120,7 @@ class InternalThreadLocalTest { final Integer[] valueToRemove = {null}; final InternalThreadLocal internalThreadLocal = new InternalThreadLocal() { @Override - protected void onRemoval(Integer value) throws Exception { + protected void onRemoval(Integer value) { //value calculate valueToRemove[0] = value + 1; } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemoryLimitedLinkedBlockingQueueTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemoryLimitedLinkedBlockingQueueTest.java index 1196e5993d..5b5405f535 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemoryLimitedLinkedBlockingQueueTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemoryLimitedLinkedBlockingQueueTest.java @@ -27,7 +27,7 @@ import static org.hamcrest.Matchers.is; class MemoryLimitedLinkedBlockingQueueTest { @Test - void test() throws Exception { + void test() { ByteBuddyAgent.install(); final Instrumentation instrumentation = ByteBuddyAgent.getInstrumentation(); MemoryLimitedLinkedBlockingQueue queue = new MemoryLimitedLinkedBlockingQueue<>(1, instrumentation); @@ -38,4 +38,4 @@ class MemoryLimitedLinkedBlockingQueueTest { queue.setMemoryLimit(Integer.MAX_VALUE); assertThat(queue.offer(() -> System.out.println("add success")), is(true)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemorySafeLinkedBlockingQueueTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemorySafeLinkedBlockingQueueTest.java index c8203e090c..e678cbd14b 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemorySafeLinkedBlockingQueueTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/MemorySafeLinkedBlockingQueueTest.java @@ -31,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; class MemorySafeLinkedBlockingQueueTest { @Test - void test() throws Exception { + void test() { ByteBuddyAgent.install(); final Instrumentation instrumentation = ByteBuddyAgent.getInstrumentation(); final long objectSize = instrumentation.getObjectSize((Runnable) () -> { @@ -49,7 +49,7 @@ class MemorySafeLinkedBlockingQueueTest { } @Test - void testCustomReject() throws Exception { + void testCustomReject() { MemorySafeLinkedBlockingQueue queue = new MemorySafeLinkedBlockingQueue<>(Integer.MAX_VALUE); queue.setRejector(new AbortPolicy<>()); assertThrows(RejectException.class, () -> queue.offer(() -> { diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/AbortPolicyWithReportTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/AbortPolicyWithReportTest.java index b8a0ab630d..1bf52c2f02 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/AbortPolicyWithReportTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/AbortPolicyWithReportTest.java @@ -38,13 +38,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class AbortPolicyWithReportTest { @Test - void jStackDumpTest() throws InterruptedException { + void jStackDumpTest() { URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?dump.directory=/tmp&version=1.0.0&application=morgan&noValue="); AtomicReference fileOutputStream = new AtomicReference<>(); AbortPolicyWithReport abortPolicyWithReport = new AbortPolicyWithReport("Test", url) { @Override - protected void jstack(FileOutputStream jStackStream) throws Exception { + protected void jstack(FileOutputStream jStackStream) { fileOutputStream.set(jStackStream); } }; @@ -59,7 +59,7 @@ class AbortPolicyWithReportTest { } @Test - void jStackDumpTest_dumpDirectoryNotExists_cannotBeCreatedTakeUserHome() throws InterruptedException { + void jStackDumpTest_dumpDirectoryNotExists_cannotBeCreatedTakeUserHome() { final String dumpDirectory = dumpDirectoryCannotBeCreated(); URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?dump.directory=" @@ -81,7 +81,7 @@ class AbortPolicyWithReportTest { } @Test - void jStackDumpTest_dumpDirectoryNotExists_canBeCreated() throws InterruptedException { + void jStackDumpTest_dumpDirectoryNotExists_canBeCreated() { final String dumpDirectory = UUID.randomUUID().toString(); URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?dump.directory=" diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/cached/CachedThreadPoolTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/cached/CachedThreadPoolTest.java index 91267b1768..e85bb6c0c6 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/cached/CachedThreadPoolTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/cached/CachedThreadPoolTest.java @@ -72,10 +72,10 @@ class CachedThreadPoolTest { } @Test - void getExecutor2() throws Exception { + void getExecutor2() { URL url = URL.valueOf("dubbo://10.20.130.230:20880/context/path?" + QUEUES_KEY + "=1"); ThreadPool threadPool = new CachedThreadPool(); ThreadPoolExecutor executor = (ThreadPoolExecutor) threadPool.getExecutor(url); assertThat(executor.getQueue(), Matchers.>instanceOf(LinkedBlockingQueue.class)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolExecutorTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolExecutorTest.java index 5e38e76eac..68b3735ff7 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolExecutorTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolExecutorTest.java @@ -101,7 +101,7 @@ class EagerThreadPoolExecutorTest { } @Test - void testEagerThreadPoolFast() throws Exception { + void testEagerThreadPoolFast() { String name = "eager-tf"; int queues = 5; int cores = 5; @@ -171,7 +171,7 @@ class EagerThreadPoolExecutorTest { } @Test - void testEagerThreadPool_rejectExecution1() throws Exception { + void testEagerThreadPool_rejectExecution1() { String name = "eager-tf"; int cores = 1; int threads = 3; @@ -213,7 +213,7 @@ class EagerThreadPoolExecutorTest { @Test - void testEagerThreadPool_rejectExecution2() throws Exception { + void testEagerThreadPool_rejectExecution2() { String name = "eager-tf"; int cores = 1; int threads = 3; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolTest.java index 7c5f9e450f..440d0156e6 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/eager/EagerThreadPoolTest.java @@ -74,11 +74,11 @@ class EagerThreadPoolTest { } @Test - void getExecutor2() throws Exception { + void getExecutor2() { URL url = URL.valueOf("dubbo://10.20.130.230:20880/context/path?" + QUEUES_KEY + "=2"); ThreadPool threadPool = new EagerThreadPool(); ThreadPoolExecutor executor = (ThreadPoolExecutor) threadPool.getExecutor(url); assertThat(executor.getQueue().remainingCapacity(), is(2)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/limited/LimitedThreadPoolTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/limited/LimitedThreadPoolTest.java index 0f44e65082..66ef2cac84 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/limited/LimitedThreadPoolTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/threadpool/support/limited/LimitedThreadPoolTest.java @@ -73,10 +73,10 @@ class LimitedThreadPoolTest { } @Test - void getExecutor2() throws Exception { + void getExecutor2() { URL url = URL.valueOf("dubbo://10.20.130.230:20880/context/path?" + QUEUES_KEY + "=1"); ThreadPool threadPool = new LimitedThreadPool(); ThreadPoolExecutor executor = (ThreadPoolExecutor) threadPool.getExecutor(url); assertThat(executor.getQueue(), Matchers.>instanceOf(LinkedBlockingQueue.class)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AnnotationUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AnnotationUtilsTest.java index 84c1f6906d..26b1960f35 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AnnotationUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AnnotationUtilsTest.java @@ -69,7 +69,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class AnnotationUtilsTest { @Test - void testIsType() throws NoSuchMethodException { + void testIsType() { // null checking assertFalse(isType(null)); // Method checking @@ -390,4 +390,4 @@ class AnnotationUtilsTest { } assertTrue(apacheServiceFound && alibabaServiceFound && adaptiveFound); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ArrayUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ArrayUtilsTest.java index fd0ae90b66..164329bea0 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ArrayUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ArrayUtilsTest.java @@ -25,17 +25,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class ArrayUtilsTest { @Test - void isEmpty() throws Exception { + void isEmpty() { assertTrue(ArrayUtils.isEmpty(null)); assertTrue(ArrayUtils.isEmpty(new Object[0])); assertFalse(ArrayUtils.isEmpty(new Object[]{"abc"})); } @Test - void isNotEmpty() throws Exception { + void isNotEmpty() { assertFalse(ArrayUtils.isNotEmpty(null)); assertFalse(ArrayUtils.isNotEmpty(new Object[0])); assertTrue(ArrayUtils.isNotEmpty(new Object[]{"abc"})); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AtomicPositiveIntegerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AtomicPositiveIntegerTest.java index 1c2880ff03..bc7b23fca8 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AtomicPositiveIntegerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/AtomicPositiveIntegerTest.java @@ -35,14 +35,14 @@ class AtomicPositiveIntegerTest { private AtomicPositiveInteger i3 = new AtomicPositiveInteger(Integer.MAX_VALUE); @Test - void testGet() throws Exception { + void testGet() { assertEquals(0, i1.get()); assertEquals(127, i2.get()); assertEquals(Integer.MAX_VALUE, i3.get()); } @Test - void testSet() throws Exception { + void testSet() { i1.set(100); assertEquals(100, i1.get()); @@ -56,7 +56,7 @@ class AtomicPositiveIntegerTest { } @Test - void testGetAndIncrement() throws Exception { + void testGetAndIncrement() { int get = i1.getAndIncrement(); assertEquals(0, get); assertEquals(1, i1.get()); @@ -71,7 +71,7 @@ class AtomicPositiveIntegerTest { } @Test - void testGetAndDecrement() throws Exception { + void testGetAndDecrement() { int get = i1.getAndDecrement(); assertEquals(0, get); assertEquals(Integer.MAX_VALUE, i1.get()); @@ -86,7 +86,7 @@ class AtomicPositiveIntegerTest { } @Test - void testIncrementAndGet() throws Exception { + void testIncrementAndGet() { int get = i1.incrementAndGet(); assertEquals(1, get); assertEquals(1, i1.get()); @@ -101,7 +101,7 @@ class AtomicPositiveIntegerTest { } @Test - void testDecrementAndGet() throws Exception { + void testDecrementAndGet() { int get = i1.decrementAndGet(); assertEquals(Integer.MAX_VALUE, get); assertEquals(Integer.MAX_VALUE, i1.get()); @@ -116,7 +116,7 @@ class AtomicPositiveIntegerTest { } @Test - void testGetAndSet() throws Exception { + void testGetAndSet() { int get = i1.getAndSet(100); assertEquals(0, get); assertEquals(100, i1.get()); @@ -130,7 +130,7 @@ class AtomicPositiveIntegerTest { } @Test - void testGetAndAnd() throws Exception { + void testGetAndAnd() { int get = i1.getAndAdd(3); assertEquals(0, get); assertEquals(3, i1.get()); @@ -146,7 +146,7 @@ class AtomicPositiveIntegerTest { @Test - void testAddAndGet() throws Exception { + void testAddAndGet() { int get = i1.addAndGet(3); assertEquals(3, get); assertEquals(3, i1.get()); @@ -187,7 +187,7 @@ class AtomicPositiveIntegerTest { } @Test - void testValues() throws Exception { + void testValues() { Integer i = i1.get(); assertThat(i1.byteValue(), equalTo(i.byteValue())); assertThat(i1.shortValue(), equalTo(i.shortValue())); @@ -203,4 +203,4 @@ class AtomicPositiveIntegerTest { assertEquals(new AtomicPositiveInteger(), new AtomicPositiveInteger()); assertEquals(new AtomicPositiveInteger(1), new AtomicPositiveInteger(1)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ClassUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ClassUtilsTest.java index 6fa46643cc..2df753bcb4 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ClassUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ClassUtilsTest.java @@ -48,12 +48,12 @@ class ClassUtilsTest { } @Test - void testGetCallerClassLoader() throws Exception { + void testGetCallerClassLoader() { assertThat(ClassUtils.getCallerClassLoader(ClassUtilsTest.class), sameInstance(ClassUtilsTest.class.getClassLoader())); } @Test - void testGetClassLoader1() throws Exception { + void testGetClassLoader1() { ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { assertThat(ClassUtils.getClassLoader(ClassUtilsTest.class), sameInstance(oldClassLoader)); @@ -65,7 +65,7 @@ class ClassUtilsTest { } @Test - void testGetClassLoader2() throws Exception { + void testGetClassLoader2() { assertThat(ClassUtils.getClassLoader(), sameInstance(ClassUtils.class.getClassLoader())); } @@ -89,7 +89,7 @@ class ClassUtilsTest { } @Test - void testResolvePrimitiveClassName() throws Exception { + void testResolvePrimitiveClassName() { assertThat(ClassUtils.resolvePrimitiveClassName("boolean") == boolean.class, is(true)); assertThat(ClassUtils.resolvePrimitiveClassName("byte") == byte.class, is(true)); assertThat(ClassUtils.resolvePrimitiveClassName("char") == char.class, is(true)); @@ -109,13 +109,13 @@ class ClassUtilsTest { } @Test - void testToShortString() throws Exception { + void testToShortString() { assertThat(ClassUtils.toShortString(null), equalTo("null")); assertThat(ClassUtils.toShortString(new ClassUtilsTest()), startsWith("ClassUtilsTest@")); } @Test - void testConvertPrimitive() throws Exception { + void testConvertPrimitive() { assertThat(ClassUtils.convertPrimitive(char.class, ""), equalTo(null)); assertThat(ClassUtils.convertPrimitive(char.class, null), equalTo(null)); @@ -151,4 +151,4 @@ class ClassUtilsTest { assertThat(ClassUtils.convertPrimitive(double.class, "10.1"), equalTo(Double.valueOf(10.1))); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java index 3516e75178..8df47daf4a 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java @@ -50,7 +50,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class CollectionUtilsTest { @Test - void testSort() throws Exception { + void testSort() { List list = new ArrayList(); list.add(100); list.add(10); @@ -65,14 +65,14 @@ class CollectionUtilsTest { } @Test - void testSortNull() throws Exception { + void testSortNull() { assertNull(CollectionUtils.sort(null)); assertTrue(CollectionUtils.sort(new ArrayList()).isEmpty()); } @Test - void testSortSimpleName() throws Exception { + void testSortSimpleName() { List list = new ArrayList(); list.add("aaa.z"); list.add("b"); @@ -87,7 +87,7 @@ class CollectionUtilsTest { } @Test - void testSortSimpleNameNull() throws Exception { + void testSortSimpleNameNull() { assertNull(CollectionUtils.sortSimpleName(null)); assertTrue(CollectionUtils.sortSimpleName(new ArrayList()).isEmpty()); @@ -110,7 +110,7 @@ class CollectionUtilsTest { } @Test - void testSplitAll() throws Exception { + void testSplitAll() { assertNull(CollectionUtils.splitAll(null, null)); assertNull(CollectionUtils.splitAll(null, "-")); @@ -132,7 +132,7 @@ class CollectionUtilsTest { } @Test - void testJoinAll() throws Exception { + void testJoinAll() { assertNull(CollectionUtils.joinAll(null, null)); assertNull(CollectionUtils.joinAll(null, "-")); @@ -159,7 +159,7 @@ class CollectionUtilsTest { } @Test - void testJoinList() throws Exception { + void testJoinList() { List list = emptyList(); assertEquals("", CollectionUtils.join(list, "/")); @@ -171,7 +171,7 @@ class CollectionUtilsTest { } @Test - void testMapEquals() throws Exception { + void testMapEquals() { assertTrue(CollectionUtils.mapEquals(null, null)); assertFalse(CollectionUtils.mapEquals(null, new HashMap())); assertFalse(CollectionUtils.mapEquals(new HashMap(), null)); @@ -181,17 +181,17 @@ class CollectionUtilsTest { } @Test - void testStringMap1() throws Exception { + void testStringMap1() { assertThat(toStringMap("key", "value"), equalTo(Collections.singletonMap("key", "value"))); } @Test - void testStringMap2() throws Exception { + void testStringMap2() { Assertions.assertThrows(IllegalArgumentException.class, () -> toStringMap("key", "value", "odd")); } @Test - void testToMap1() throws Exception { + void testToMap1() { assertTrue(CollectionUtils.toMap().isEmpty()); Map expected = new HashMap(); @@ -211,19 +211,19 @@ class CollectionUtilsTest { } @Test - void testToMap2() throws Exception { + void testToMap2() { Assertions.assertThrows(IllegalArgumentException.class, () -> toMap("a", "b", "c")); } @Test - void testIsEmpty() throws Exception { + void testIsEmpty() { assertThat(isEmpty(null), is(true)); assertThat(isEmpty(new HashSet()), is(true)); assertThat(isEmpty(emptyList()), is(true)); } @Test - void testIsNotEmpty() throws Exception { + void testIsNotEmpty() { assertThat(isNotEmpty(singleton("a")), is(true)); } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LFUCacheTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LFUCacheTest.java index abee14aecb..9dbf00c6d8 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LFUCacheTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LFUCacheTest.java @@ -27,7 +27,7 @@ import static org.hamcrest.Matchers.equalTo; class LFUCacheTest { @Test - void testCacheEviction() throws Exception { + void testCacheEviction() { LFUCache cache = new LFUCache<>(8, 0.8f); cache.put("one", 1); cache.put("two", 2); @@ -48,7 +48,7 @@ class LFUCacheTest { } @Test - void testCacheRemove() throws Exception { + void testCacheRemove() { LFUCache cache = new LFUCache<>(8, 0.8f); cache.put("one", 1); cache.put("two", 2); @@ -68,16 +68,16 @@ class LFUCacheTest { } @Test - void testDefaultCapacity() throws Exception { + void testDefaultCapacity() { LFUCache cache = new LFUCache<>(); assertThat(cache.getCapacity(), equalTo(1000)); } @Test - void testErrorConstructArguments() throws IOException { + void testErrorConstructArguments() { Assertions.assertThrows(IllegalArgumentException.class, () -> new LFUCache<>(0, 0.8f)); Assertions.assertThrows(IllegalArgumentException.class, () -> new LFUCache<>(-1, 0.8f)); Assertions.assertThrows(IllegalArgumentException.class, () -> new LFUCache<>(100, 0.0f)); Assertions.assertThrows(IllegalArgumentException.class, () -> new LFUCache<>(100, -0.1f)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LRU2CacheTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LRU2CacheTest.java index 8dab9afeac..8d03fe30a6 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LRU2CacheTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LRU2CacheTest.java @@ -26,7 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class LRU2CacheTest { @Test - void testCache() throws Exception { + void testCache() { LRU2Cache cache = new LRU2Cache(3); cache.put("one", 1); cache.put("two", 2); @@ -62,10 +62,10 @@ class LRU2CacheTest { } @Test - void testCapacity() throws Exception { + void testCapacity() { LRU2Cache cache = new LRU2Cache(); assertThat(cache.getMaxCapacity(), equalTo(1000)); cache.setMaxCapacity(10); assertThat(cache.getMaxCapacity(), equalTo(10)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogHelperTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogHelperTest.java index fd8a041b8f..a5fef528e9 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogHelperTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogHelperTest.java @@ -28,7 +28,7 @@ import static org.mockito.Mockito.when; class LogHelperTest { @Test - void testTrace() throws Exception { + void testTrace() { Logger logger = Mockito.mock(Logger.class); when(logger.isTraceEnabled()).thenReturn(true); LogHelper.trace(logger, "trace"); @@ -41,7 +41,7 @@ class LogHelperTest { } @Test - void testDebug() throws Exception { + void testDebug() { Logger logger = Mockito.mock(Logger.class); when(logger.isDebugEnabled()).thenReturn(true); LogHelper.debug(logger, "debug"); @@ -54,7 +54,7 @@ class LogHelperTest { } @Test - void testInfo() throws Exception { + void testInfo() { Logger logger = Mockito.mock(Logger.class); when(logger.isInfoEnabled()).thenReturn(true); LogHelper.info(logger, "info"); @@ -67,7 +67,7 @@ class LogHelperTest { } @Test - void testWarn() throws Exception { + void testWarn() { Logger logger = Mockito.mock(Logger.class); when(logger.isWarnEnabled()).thenReturn(true); LogHelper.warn(logger, "warn"); @@ -80,7 +80,7 @@ class LogHelperTest { } @Test - void testError() throws Exception { + void testError() { Logger logger = Mockito.mock(Logger.class); when(logger.isErrorEnabled()).thenReturn(true); LogHelper.error(logger, "error"); @@ -91,4 +91,4 @@ class LogHelperTest { LogHelper.error(logger, "error", t); verify(logger).error("error", t); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogTest.java index a357ae6fa8..0dfede0887 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogTest.java @@ -27,7 +27,7 @@ import static org.hamcrest.Matchers.is; class LogTest { @Test - void testLogName() throws Exception { + void testLogName() { Log log1 = new Log(); Log log2 = new Log(); Log log3 = new Log(); @@ -41,7 +41,7 @@ class LogTest { } @Test - void testLogLevel() throws Exception { + void testLogLevel() { Log log1 = new Log(); Log log2 = new Log(); Log log3 = new Log(); @@ -55,7 +55,7 @@ class LogTest { } @Test - void testLogMessage() throws Exception { + void testLogMessage() { Log log1 = new Log(); Log log2 = new Log(); Log log3 = new Log(); @@ -69,7 +69,7 @@ class LogTest { } @Test - void testLogThread() throws Exception { + void testLogThread() { Log log1 = new Log(); Log log2 = new Log(); Log log3 = new Log(); @@ -82,4 +82,4 @@ class LogTest { Assertions.assertNotEquals(log1, log3); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogUtilTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogUtilTest.java index 9af6e22fff..7183ffd998 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogUtilTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LogUtilTest.java @@ -34,7 +34,7 @@ class LogUtilTest { } @Test - void testStartStop() throws Exception { + void testStartStop() { LogUtil.start(); assertThat(DubboAppender.available, is(true)); LogUtil.stop(); @@ -42,7 +42,7 @@ class LogUtilTest { } @Test - void testCheckNoError() throws Exception { + void testCheckNoError() { Log log = mock(Log.class); DubboAppender.logList.add(log); when(log.getLogLevel()).thenReturn(Level.ERROR); @@ -52,7 +52,7 @@ class LogUtilTest { } @Test - void testFindName() throws Exception { + void testFindName() { Log log = mock(Log.class); DubboAppender.logList.add(log); when(log.getLogName()).thenReturn("a"); @@ -60,7 +60,7 @@ class LogUtilTest { } @Test - void testFindLevel() throws Exception { + void testFindLevel() { Log log = mock(Log.class); DubboAppender.logList.add(log); when(log.getLogLevel()).thenReturn(Level.ERROR); @@ -69,7 +69,7 @@ class LogUtilTest { } @Test - void testFindLevelWithThreadName() throws Exception { + void testFindLevelWithThreadName() { Log log = mock(Log.class); DubboAppender.logList.add(log); when(log.getLogLevel()).thenReturn(Level.ERROR); @@ -82,7 +82,7 @@ class LogUtilTest { } @Test - void testFindThread() throws Exception { + void testFindThread() { Log log = mock(Log.class); DubboAppender.logList.add(log); when(log.getLogThread()).thenReturn("thread-1"); @@ -90,7 +90,7 @@ class LogUtilTest { } @Test - void testFindMessage1() throws Exception { + void testFindMessage1() { Log log = mock(Log.class); DubboAppender.logList.add(log); when(log.getLogMessage()).thenReturn("message"); @@ -98,7 +98,7 @@ class LogUtilTest { } @Test - void testFindMessage2() throws Exception { + void testFindMessage2() { Log log = mock(Log.class); DubboAppender.logList.add(log); when(log.getLogMessage()).thenReturn("message"); @@ -110,4 +110,4 @@ class LogUtilTest { assertThat(LogUtil.findMessage(Level.ERROR, "message"), equalTo(1)); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/MemberUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/MemberUtilsTest.java index c1f322fc80..6b6b45109a 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/MemberUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/MemberUtilsTest.java @@ -40,7 +40,7 @@ class MemberUtilsTest { assertTrue(isPublic(getClass().getMethod("publicMethod"))); } - public void noStatic() throws NoSuchMethodException { + public void noStatic() { } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java index accdb9afc8..f3856f0957 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java @@ -45,48 +45,48 @@ import static org.mockito.Mockito.when; class NetUtilsTest { @Test - void testGetRandomPort() throws Exception { + void testGetRandomPort() { assertThat(NetUtils.getRandomPort(), greaterThanOrEqualTo(30000)); assertThat(NetUtils.getRandomPort(), greaterThanOrEqualTo(30000)); assertThat(NetUtils.getRandomPort(), greaterThanOrEqualTo(30000)); } @Test - void testGetAvailablePort() throws Exception { + void testGetAvailablePort() { assertThat(NetUtils.getAvailablePort(), greaterThan(0)); assertThat(NetUtils.getAvailablePort(12345), greaterThanOrEqualTo(12345)); assertThat(NetUtils.getAvailablePort(-1), greaterThanOrEqualTo(0)); } @Test - void testValidAddress() throws Exception { + void testValidAddress() { assertTrue(NetUtils.isValidAddress("10.20.130.230:20880")); assertFalse(NetUtils.isValidAddress("10.20.130.230")); assertFalse(NetUtils.isValidAddress("10.20.130.230:666666")); } @Test - void testIsInvalidPort() throws Exception { + void testIsInvalidPort() { assertTrue(NetUtils.isInvalidPort(0)); assertTrue(NetUtils.isInvalidPort(65536)); assertFalse(NetUtils.isInvalidPort(1024)); } @Test - void testIsLocalHost() throws Exception { + void testIsLocalHost() { assertTrue(NetUtils.isLocalHost("localhost")); assertTrue(NetUtils.isLocalHost("127.1.2.3")); assertFalse(NetUtils.isLocalHost("128.1.2.3")); } @Test - void testIsAnyHost() throws Exception { + void testIsAnyHost() { assertTrue(NetUtils.isAnyHost("0.0.0.0")); assertFalse(NetUtils.isAnyHost("1.1.1.1")); } @Test - void testIsInvalidLocalHost() throws Exception { + void testIsInvalidLocalHost() { assertTrue(NetUtils.isInvalidLocalHost(null)); assertTrue(NetUtils.isInvalidLocalHost("")); assertTrue(NetUtils.isInvalidLocalHost("localhost")); @@ -97,13 +97,13 @@ class NetUtilsTest { } @Test - void testIsValidLocalHost() throws Exception { + void testIsValidLocalHost() { assertTrue(NetUtils.isValidLocalHost("1.2.3.4")); assertTrue(NetUtils.isValidLocalHost("128.0.0.1")); } @Test - void testGetLocalSocketAddress() throws Exception { + void testGetLocalSocketAddress() { InetSocketAddress address = NetUtils.getLocalSocketAddress("localhost", 12345); assertTrue(address.getAddress().isAnyLocalAddress()); assertEquals(address.getPort(), 12345); @@ -113,7 +113,7 @@ class NetUtilsTest { } @Test - void testIsValidAddress() throws Exception { + void testIsValidAddress() { assertFalse(NetUtils.isValidV4Address((InetAddress) null)); InetAddress address = mock(InetAddress.class); when(address.isLoopbackAddress()).thenReturn(true); @@ -133,19 +133,19 @@ class NetUtilsTest { } @Test - void testGetLocalHost() throws Exception { + void testGetLocalHost() { assertNotNull(NetUtils.getLocalHost()); } @Test - void testGetLocalAddress() throws Exception { + void testGetLocalAddress() { InetAddress address = NetUtils.getLocalAddress(); assertNotNull(address); assertTrue(NetUtils.isValidLocalHost(address.getHostAddress())); } @Test - void testFilterLocalHost() throws Exception { + void testFilterLocalHost() { assertNull(NetUtils.filterLocalHost(null)); assertEquals(NetUtils.filterLocalHost(""), ""); String host = NetUtils.filterLocalHost("dubbo://127.0.0.1:8080/foo"); @@ -159,18 +159,18 @@ class NetUtilsTest { } @Test - void testGetHostName() throws Exception { + void testGetHostName() { assertNotNull(NetUtils.getHostName("127.0.0.1")); } @Test - void testGetIpByHost() throws Exception { + void testGetIpByHost() { assertThat(NetUtils.getIpByHost("localhost"), equalTo("127.0.0.1")); assertThat(NetUtils.getIpByHost("dubbo.local"), equalTo("dubbo.local")); } @Test - void testToAddressString() throws Exception { + void testToAddressString() { InetAddress address = mock(InetAddress.class); when(address.getHostAddress()).thenReturn("dubbo"); InetSocketAddress socketAddress = new InetSocketAddress(address, 1234); @@ -178,7 +178,7 @@ class NetUtilsTest { } @Test - void testToAddress() throws Exception { + void testToAddress() { InetSocketAddress address = NetUtils.toAddress("localhost:1234"); assertThat(address.getHostName(), equalTo("localhost")); assertThat(address.getPort(), equalTo(1234)); @@ -188,7 +188,7 @@ class NetUtilsTest { } @Test - void testToURL() throws Exception { + void testToURL() { String url = NetUtils.toURL("dubbo", "host", 1234, "foo"); assertThat(url, equalTo("dubbo://host:1234/foo")); } @@ -248,7 +248,7 @@ class NetUtilsTest { } @Test - void testMatchIpRangeMatchWhenIpv6Exception() throws UnknownHostException { + void testMatchIpRangeMatchWhenIpv6Exception() { IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> NetUtils.matchIpRange("234e:0:4567::3d:*", "234e:0:4567::3d:ff", 90)); @@ -265,7 +265,7 @@ class NetUtilsTest { } @Test - void testMatchIpRangeMatchWhenIpWrongException() throws UnknownHostException { + void testMatchIpRangeMatchWhenIpWrongException() { UnknownHostException thrown = assertThrows(UnknownHostException.class, () -> NetUtils.matchIpRange("192.168.1.63", "192.168.1.ff", 90)); @@ -398,4 +398,4 @@ class NetUtilsTest { System.setProperty(DUBBO_NETWORK_IGNORED_INTERFACE, ""); } } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ParametersTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ParametersTest.java index 21cc63950b..e53a4c7b28 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ParametersTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ParametersTest.java @@ -26,7 +26,7 @@ class ParametersTest { final String ServiceVersion = "1.0.15"; final String LoadBalance = "lcr"; - public void testMap2Parameters() throws Exception { + public void testMap2Parameters() { Map map = new HashMap(); map.put("name", "org.apache.dubbo.rpc.service.GenericService"); map.put("version", "1.0.15"); @@ -44,4 +44,4 @@ class ParametersTest { assertEquals(map.get("version"), ServiceVersion); assertEquals(map.get("lb"), LoadBalance); } -} \ No newline at end of file +} diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java index bfa8cfd72b..3d35af9984 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java @@ -41,7 +41,7 @@ import static org.hamcrest.collection.IsCollectionWithSize.hasSize; class ApplicationConfigTest { @Test - void testName() throws Exception { + void testName() { ApplicationConfig application = new ApplicationConfig(); application.setName("app"); assertThat(application.getName(), equalTo("app")); @@ -53,7 +53,7 @@ class ApplicationConfigTest { } @Test - void testVersion() throws Exception { + void testVersion() { ApplicationConfig application = new ApplicationConfig("app"); application.setVersion("1.0.0"); assertThat(application.getVersion(), equalTo("1.0.0")); @@ -63,28 +63,28 @@ class ApplicationConfigTest { } @Test - void testOwner() throws Exception { + void testOwner() { ApplicationConfig application = new ApplicationConfig("app"); application.setOwner("owner"); assertThat(application.getOwner(), equalTo("owner")); } @Test - void testOrganization() throws Exception { + void testOrganization() { ApplicationConfig application = new ApplicationConfig("app"); application.setOrganization("org"); assertThat(application.getOrganization(), equalTo("org")); } @Test - void testArchitecture() throws Exception { + void testArchitecture() { ApplicationConfig application = new ApplicationConfig("app"); application.setArchitecture("arch"); assertThat(application.getArchitecture(), equalTo("arch")); } @Test - void testEnvironment1() throws Exception { + void testEnvironment1() { ApplicationConfig application = new ApplicationConfig("app"); application.setEnvironment("develop"); assertThat(application.getEnvironment(), equalTo("develop")); @@ -95,7 +95,7 @@ class ApplicationConfigTest { } @Test - void testEnvironment2() throws Exception { + void testEnvironment2() { Assertions.assertThrows(IllegalStateException.class, () -> { ApplicationConfig application = new ApplicationConfig("app"); application.setEnvironment("illegal-env"); @@ -103,7 +103,7 @@ class ApplicationConfigTest { } @Test - void testRegistry() throws Exception { + void testRegistry() { ApplicationConfig application = new ApplicationConfig("app"); RegistryConfig registry = new RegistryConfig(); application.setRegistry(registry); @@ -114,7 +114,7 @@ class ApplicationConfigTest { } @Test - void testMonitor() throws Exception { + void testMonitor() { ApplicationConfig application = new ApplicationConfig("app"); application.setMonitor(new MonitorConfig("monitor-addr")); assertThat(application.getMonitor().getAddress(), equalTo("monitor-addr")); @@ -123,21 +123,21 @@ class ApplicationConfigTest { } @Test - void testLogger() throws Exception { + void testLogger() { ApplicationConfig application = new ApplicationConfig("app"); application.setLogger("log4j"); assertThat(application.getLogger(), equalTo("log4j")); } @Test - void testDefault() throws Exception { + void testDefault() { ApplicationConfig application = new ApplicationConfig("app"); application.setDefault(true); assertThat(application.isDefault(), is(true)); } @Test - void testDumpDirectory() throws Exception { + void testDumpDirectory() { ApplicationConfig application = new ApplicationConfig("app"); application.setDumpDirectory("/dump"); assertThat(application.getDumpDirectory(), equalTo("/dump")); @@ -147,7 +147,7 @@ class ApplicationConfigTest { } @Test - void testQosEnable() throws Exception { + void testQosEnable() { ApplicationConfig application = new ApplicationConfig("app"); application.setQosEnable(true); assertThat(application.getQosEnable(), is(true)); @@ -157,14 +157,14 @@ class ApplicationConfigTest { } @Test - void testQosPort() throws Exception { + void testQosPort() { ApplicationConfig application = new ApplicationConfig("app"); application.setQosPort(8080); assertThat(application.getQosPort(), equalTo(8080)); } @Test - void testQosAcceptForeignIp() throws Exception { + void testQosAcceptForeignIp() { ApplicationConfig application = new ApplicationConfig("app"); application.setQosAcceptForeignIp(true); assertThat(application.getQosAcceptForeignIp(), is(true)); @@ -174,7 +174,7 @@ class ApplicationConfigTest { } @Test - void testParameters() throws Exception { + void testParameters() { ApplicationConfig application = new ApplicationConfig("app"); application.setQosAcceptForeignIp(true); Map parameters = new HashMap(); diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java index 4631770320..ba1ba93a63 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java @@ -30,28 +30,28 @@ import static org.hamcrest.Matchers.is; class ArgumentConfigTest { @Test - void testIndex() throws Exception { + void testIndex() { ArgumentConfig argument = new ArgumentConfig(); argument.setIndex(1); assertThat(argument.getIndex(), is(1)); } @Test - void testType() throws Exception { + void testType() { ArgumentConfig argument = new ArgumentConfig(); argument.setType("int"); assertThat(argument.getType(), equalTo("int")); } @Test - void testCallback() throws Exception { + void testCallback() { ArgumentConfig argument = new ArgumentConfig(); argument.setCallback(true); assertThat(argument.isCallback(), is(true)); } @Test - void testArguments() throws Exception { + void testArguments() { ArgumentConfig argument = new ArgumentConfig(); argument.setIndex(1); argument.setType("int"); diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/config/MethodConfigTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/config/MethodConfigTest.java index 22e04b3a81..d2d15cb1cc 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/config/MethodConfigTest.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/config/MethodConfigTest.java @@ -46,7 +46,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class MethodConfigTest { @Test - void testName() throws Exception { + void testName() { MethodConfig method = new MethodConfig(); method.setName("hello"); assertThat(method.getName(), equalTo("hello")); @@ -56,42 +56,42 @@ class MethodConfigTest { } @Test - void testStat() throws Exception { + void testStat() { MethodConfig method = new MethodConfig(); method.setStat(10); assertThat(method.getStat(), equalTo(10)); } @Test - void testRetry() throws Exception { + void testRetry() { MethodConfig method = new MethodConfig(); method.setRetry(true); assertThat(method.isRetry(), is(true)); } @Test - void testReliable() throws Exception { + void testReliable() { MethodConfig method = new MethodConfig(); method.setReliable(true); assertThat(method.isReliable(), is(true)); } @Test - void testExecutes() throws Exception { + void testExecutes() { MethodConfig method = new MethodConfig(); method.setExecutes(10); assertThat(method.getExecutes(), equalTo(10)); } @Test - void testDeprecated() throws Exception { + void testDeprecated() { MethodConfig method = new MethodConfig(); method.setDeprecated(true); assertThat(method.getDeprecated(), is(true)); } @Test - void testArguments() throws Exception { + void testArguments() { MethodConfig method = new MethodConfig(); ArgumentConfig argument = new ArgumentConfig(); method.setArguments(Collections.singletonList(argument)); @@ -100,7 +100,7 @@ class MethodConfigTest { } @Test - void testSticky() throws Exception { + void testSticky() { MethodConfig method = new MethodConfig(); method.setSticky(true); assertThat(method.getSticky(), is(true)); @@ -118,7 +118,7 @@ class MethodConfigTest { } //@Test - public void testOnreturn() throws Exception { + public void testOnreturn() { MethodConfig method = new MethodConfig(); method.setOnreturn("on-return-object"); assertThat(method.getOnreturn(), equalTo((Object) "on-return-object")); @@ -131,7 +131,7 @@ class MethodConfigTest { } @Test - void testOnreturnMethod() throws Exception { + void testOnreturnMethod() { MethodConfig method = new MethodConfig(); method.setOnreturnMethod("on-return-method"); assertThat(method.getOnreturnMethod(), equalTo("on-return-method")); @@ -144,7 +144,7 @@ class MethodConfigTest { } //@Test - public void testOnthrow() throws Exception { + public void testOnthrow() { MethodConfig method = new MethodConfig(); method.setOnthrow("on-throw-object"); assertThat(method.getOnthrow(), equalTo((Object) "on-throw-object")); @@ -157,7 +157,7 @@ class MethodConfigTest { } @Test - void testOnthrowMethod() throws Exception { + void testOnthrowMethod() { MethodConfig method = new MethodConfig(); method.setOnthrowMethod("on-throw-method"); assertThat(method.getOnthrowMethod(), equalTo("on-throw-method")); @@ -170,7 +170,7 @@ class MethodConfigTest { } //@Test - public void testOninvoke() throws Exception { + public void testOninvoke() { MethodConfig method = new MethodConfig(); method.setOninvoke("on-invoke-object"); assertThat(method.getOninvoke(), equalTo((Object) "on-invoke-object")); @@ -183,7 +183,7 @@ class MethodConfigTest { } @Test - void testOninvokeMethod() throws Exception { + void testOninvokeMethod() { MethodConfig method = new MethodConfig(); method.setOninvokeMethod("on-invoke-method"); assertThat(method.getOninvokeMethod(), equalTo("on-invoke-method")); @@ -196,7 +196,7 @@ class MethodConfigTest { } @Test - void testReturn() throws Exception { + void testReturn() { MethodConfig method = new MethodConfig(); method.setReturn(true); assertThat(method.isReturn(), is(true)); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java index 434c0689fc..88b19cf1c4 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java @@ -135,7 +135,7 @@ class AbstractConfigTest { } @Test - void testAppendParameters1() throws Exception { + void testAppendParameters1() { Map parameters = new HashMap(); parameters.put("num", "ONE"); AbstractConfig.appendParameters(parameters, new ParameterConfig(1, "hello/world", 30, "password"), "prefix"); @@ -148,7 +148,7 @@ class AbstractConfigTest { } @Test - void testAppendParameters2() throws Exception { + void testAppendParameters2() { Assertions.assertThrows(IllegalStateException.class, () -> { Map parameters = new HashMap(); AbstractConfig.appendParameters(parameters, new ParameterConfig()); @@ -156,14 +156,14 @@ class AbstractConfigTest { } @Test - void testAppendParameters3() throws Exception { + void testAppendParameters3() { Map parameters = new HashMap(); AbstractConfig.appendParameters(parameters, null); assertTrue(parameters.isEmpty()); } @Test - void testAppendParameters4() throws Exception { + void testAppendParameters4() { Map parameters = new HashMap(); AbstractConfig.appendParameters(parameters, new ParameterConfig(1, "hello/world", 30, "password")); Assertions.assertEquals("one", parameters.get("key.1")); @@ -174,7 +174,7 @@ class AbstractConfigTest { } @Test - void testAppendAttributes1() throws Exception { + void testAppendAttributes1() { ParameterConfig config = new ParameterConfig(1, "hello/world", 30, "password","BEIJING"); Map parameters = new HashMap<>(); AbstractConfig.appendParameters(parameters, config); @@ -195,24 +195,24 @@ class AbstractConfigTest { } @Test - void checkExtension() throws Exception { + void checkExtension() { Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "world")); } @Test - void checkMultiExtension1() throws Exception { + void checkMultiExtension1() { Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,world")); } @Test - void checkMultiExtension2() throws Exception { + void checkMultiExtension2() { Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world")); } @Test - void checkLength() throws Exception { + void checkLength() { Assertions.assertDoesNotThrow(() -> { StringBuilder builder = new StringBuilder(); for (int i = 0; i <= 200; i++) { @@ -223,7 +223,7 @@ class AbstractConfigTest { } @Test - void checkPathLength() throws Exception { + void checkPathLength() { Assertions.assertDoesNotThrow(() -> { StringBuilder builder = new StringBuilder(); for (int i = 0; i <= 200; i++) { @@ -234,12 +234,12 @@ class AbstractConfigTest { } @Test - void checkName() throws Exception { + void checkName() { Assertions.assertDoesNotThrow(() -> ConfigValidationUtils.checkName("hello", "world%")); } @Test - void checkNameHasSymbol() throws Exception { + void checkNameHasSymbol() { try { ConfigValidationUtils.checkNameHasSymbol("hello", ":*,/ -0123\tabcdABCD"); ConfigValidationUtils.checkNameHasSymbol("mock", "force:return world"); @@ -249,7 +249,7 @@ class AbstractConfigTest { } @Test - void checkKey() throws Exception { + void checkKey() { try { ConfigValidationUtils.checkKey("hello", "*,-0123abcdABCD"); } catch (Exception e) { @@ -258,7 +258,7 @@ class AbstractConfigTest { } @Test - void checkMultiName() throws Exception { + void checkMultiName() { try { ConfigValidationUtils.checkMultiName("hello", ",-._0123abcdABCD"); } catch (Exception e) { @@ -267,7 +267,7 @@ class AbstractConfigTest { } @Test - void checkPathName() throws Exception { + void checkPathName() { try { ConfigValidationUtils.checkPathName("hello", "/-$._0123abcdABCD"); } catch (Exception e) { @@ -276,7 +276,7 @@ class AbstractConfigTest { } @Test - void checkMethodName() throws Exception { + void checkMethodName() { try { ConfigValidationUtils.checkMethodName("hello", "abcdABCD0123abcd"); } catch (Exception e) { @@ -292,7 +292,7 @@ class AbstractConfigTest { } @Test - void checkParameterName() throws Exception { + void checkParameterName() { Map parameters = Collections.singletonMap("hello", ":*,/-._0123abcdABCD"); try { ConfigValidationUtils.checkParameterName(parameters); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java index c13197da14..4973e1d3d9 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java @@ -38,56 +38,56 @@ class AbstractMethodConfigTest { } @Test - void testTimeout() throws Exception { + void testTimeout() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setTimeout(10); assertThat(methodConfig.getTimeout(), equalTo(10)); } @Test - void testForks() throws Exception { + void testForks() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setForks(10); assertThat(methodConfig.getForks(), equalTo(10)); } @Test - void testRetries() throws Exception { + void testRetries() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setRetries(3); assertThat(methodConfig.getRetries(), equalTo(3)); } @Test - void testLoadbalance() throws Exception { + void testLoadbalance() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setLoadbalance("mockloadbalance"); assertThat(methodConfig.getLoadbalance(), equalTo("mockloadbalance")); } @Test - void testAsync() throws Exception { + void testAsync() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setAsync(true); assertThat(methodConfig.isAsync(), is(true)); } @Test - void testActives() throws Exception { + void testActives() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setActives(10); assertThat(methodConfig.getActives(), equalTo(10)); } @Test - void testSent() throws Exception { + void testSent() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setSent(true); assertThat(methodConfig.getSent(), is(true)); } @Test - void testMock() throws Exception { + void testMock() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setMock((Boolean) null); assertThat(methodConfig.getMock(), isEmptyOrNullString()); @@ -100,21 +100,21 @@ class AbstractMethodConfigTest { } @Test - void testMerger() throws Exception { + void testMerger() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setMerger("merger"); assertThat(methodConfig.getMerger(), equalTo("merger")); } @Test - void testCache() throws Exception { + void testCache() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setCache("cache"); assertThat(methodConfig.getCache(), equalTo("cache")); } @Test - void testValidation() throws Exception { + void testValidation() { MethodConfig methodConfig = new MethodConfig(); methodConfig.setValidation("validation"); assertThat(methodConfig.getValidation(), equalTo("validation")); @@ -132,4 +132,4 @@ class AbstractMethodConfigTest { private static class MethodConfig extends AbstractMethodConfig { } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java index a00960c715..bc3ffe739a 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java @@ -56,21 +56,21 @@ class AbstractReferenceConfigTest { } @Test - void testCheck() throws Exception { + void testCheck() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setCheck(true); assertThat(referenceConfig.isCheck(), is(true)); } @Test - void testInit() throws Exception { + void testInit() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setInit(true); assertThat(referenceConfig.isInit(), is(true)); } @Test - void testGeneric() throws Exception { + void testGeneric() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setGeneric(true); assertThat(referenceConfig.isGeneric(), is(true)); @@ -81,14 +81,14 @@ class AbstractReferenceConfigTest { } @Test - void testInjvm() throws Exception { + void testInjvm() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setInjvm(true); assertThat(referenceConfig.isInjvm(), is(true)); } @Test - void testFilter() throws Exception { + void testFilter() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setFilter("mockfilter"); assertThat(referenceConfig.getFilter(), equalTo("mockfilter")); @@ -99,7 +99,7 @@ class AbstractReferenceConfigTest { } @Test - void testRouter() throws Exception { + void testRouter() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setRouter("condition"); assertThat(referenceConfig.getRouter(), equalTo("condition")); @@ -119,7 +119,7 @@ class AbstractReferenceConfigTest { } @Test - void testListener() throws Exception { + void testListener() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setListener("mockinvokerlistener"); assertThat(referenceConfig.getListener(), equalTo("mockinvokerlistener")); @@ -130,14 +130,14 @@ class AbstractReferenceConfigTest { } @Test - void testLazy() throws Exception { + void testLazy() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setLazy(true); assertThat(referenceConfig.getLazy(), is(true)); } @Test - void testOnconnect() throws Exception { + void testOnconnect() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setOnconnect("onConnect"); assertThat(referenceConfig.getOnconnect(), equalTo("onConnect")); @@ -145,7 +145,7 @@ class AbstractReferenceConfigTest { } @Test - void testOndisconnect() throws Exception { + void testOndisconnect() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setOndisconnect("onDisconnect"); assertThat(referenceConfig.getOndisconnect(), equalTo("onDisconnect")); @@ -153,7 +153,7 @@ class AbstractReferenceConfigTest { } @Test - void testStubevent() throws Exception { + void testStubevent() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setOnconnect("onConnect"); Map parameters = new HashMap(); @@ -162,7 +162,7 @@ class AbstractReferenceConfigTest { } @Test - void testReconnect() throws Exception { + void testReconnect() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setReconnect("reconnect"); Map parameters = new HashMap(); @@ -172,7 +172,7 @@ class AbstractReferenceConfigTest { } @Test - void testSticky() throws Exception { + void testSticky() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setSticky(true); Map parameters = new HashMap(); @@ -182,14 +182,14 @@ class AbstractReferenceConfigTest { } @Test - void testVersion() throws Exception { + void testVersion() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setVersion("version"); assertThat(referenceConfig.getVersion(), equalTo("version")); } @Test - void testGroup() throws Exception { + void testGroup() { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setGroup("group"); assertThat(referenceConfig.getGroup(), equalTo("group")); @@ -217,4 +217,4 @@ class AbstractReferenceConfigTest { private static class ReferenceConfig extends AbstractReferenceConfig { } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java index 15039303ce..f25a5ed327 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java @@ -38,42 +38,42 @@ import static org.junit.jupiter.api.Assertions.assertNull; class AbstractServiceConfigTest { @Test - void testVersion() throws Exception { + void testVersion() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setVersion("version"); assertThat(serviceConfig.getVersion(), equalTo("version")); } @Test - void testGroup() throws Exception { + void testGroup() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setGroup("group"); assertThat(serviceConfig.getGroup(), equalTo("group")); } @Test - void testDelay() throws Exception { + void testDelay() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setDelay(1000); assertThat(serviceConfig.getDelay(), equalTo(1000)); } @Test - void testExport() throws Exception { + void testExport() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setExport(true); assertThat(serviceConfig.getExport(), is(true)); } @Test - void testWeight() throws Exception { + void testWeight() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setWeight(500); assertThat(serviceConfig.getWeight(), equalTo(500)); } @Test - void testDocument() throws Exception { + void testDocument() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setDocument("http://dubbo.apache.org"); assertThat(serviceConfig.getDocument(), equalTo("http://dubbo.apache.org")); @@ -83,7 +83,7 @@ class AbstractServiceConfigTest { } @Test - void testToken() throws Exception { + void testToken() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setToken("token"); assertThat(serviceConfig.getToken(), equalTo("token")); @@ -94,21 +94,21 @@ class AbstractServiceConfigTest { } @Test - void testDeprecated() throws Exception { + void testDeprecated() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setDeprecated(true); assertThat(serviceConfig.isDeprecated(), is(true)); } @Test - void testDynamic() throws Exception { + void testDynamic() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setDynamic(true); assertThat(serviceConfig.isDynamic(), is(true)); } @Test - void testProtocol() throws Exception { + void testProtocol() { ServiceConfig serviceConfig = new ServiceConfig(); assertThat(serviceConfig.getProtocol(), nullValue()); serviceConfig.setProtocol(new ProtocolConfig()); @@ -118,7 +118,7 @@ class AbstractServiceConfigTest { } @Test - void testAccesslog() throws Exception { + void testAccesslog() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setAccesslog("access.log"); assertThat(serviceConfig.getAccesslog(), equalTo("access.log")); @@ -129,14 +129,14 @@ class AbstractServiceConfigTest { } @Test - void testExecutes() throws Exception { + void testExecutes() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setExecutes(10); assertThat(serviceConfig.getExecutes(), equalTo(10)); } @Test - void testFilter() throws Exception { + void testFilter() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setFilter("mockfilter"); assertThat(serviceConfig.getFilter(), equalTo("mockfilter")); @@ -147,7 +147,7 @@ class AbstractServiceConfigTest { } @Test - void testListener() throws Exception { + void testListener() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setListener("mockexporterlistener"); assertThat(serviceConfig.getListener(), equalTo("mockexporterlistener")); @@ -158,35 +158,35 @@ class AbstractServiceConfigTest { } @Test - void testRegister() throws Exception { + void testRegister() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setRegister(true); assertThat(serviceConfig.isRegister(), is(true)); } @Test - void testWarmup() throws Exception { + void testWarmup() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setWarmup(100); assertThat(serviceConfig.getWarmup(), equalTo(100)); } @Test - void testSerialization() throws Exception { + void testSerialization() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setSerialization("serialization"); assertThat(serviceConfig.getSerialization(), equalTo("serialization")); } @Test - void testPreferSerialization() throws Exception { + void testPreferSerialization() { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setPreferSerialization("preferSerialization"); assertThat(serviceConfig.getPreferSerialization(), equalTo("preferSerialization")); } @Test - void testPreferSerializationDefault1() throws Exception { + void testPreferSerializationDefault1() { ServiceConfig serviceConfig = new ServiceConfig(); assertNull(serviceConfig.getPreferSerialization()); @@ -202,7 +202,7 @@ class AbstractServiceConfigTest { } @Test - void testPreferSerializationDefault2() throws Exception { + void testPreferSerializationDefault2() { ServiceConfig serviceConfig = new ServiceConfig(); assertNull(serviceConfig.getPreferSerialization()); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java index e582d62624..ee7be3f03c 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ApplicationConfigTest.java @@ -55,7 +55,7 @@ class ApplicationConfigTest { } @Test - void testName() throws Exception { + void testName() { ApplicationConfig application = new ApplicationConfig(); application.setName("app"); assertThat(application.getName(), equalTo("app")); @@ -71,7 +71,7 @@ class ApplicationConfigTest { } @Test - void testVersion() throws Exception { + void testVersion() { ApplicationConfig application = new ApplicationConfig("app"); application.setVersion("1.0.0"); assertThat(application.getVersion(), equalTo("1.0.0")); @@ -81,28 +81,28 @@ class ApplicationConfigTest { } @Test - void testOwner() throws Exception { + void testOwner() { ApplicationConfig application = new ApplicationConfig("app"); application.setOwner("owner"); assertThat(application.getOwner(), equalTo("owner")); } @Test - void testOrganization() throws Exception { + void testOrganization() { ApplicationConfig application = new ApplicationConfig("app"); application.setOrganization("org"); assertThat(application.getOrganization(), equalTo("org")); } @Test - void testArchitecture() throws Exception { + void testArchitecture() { ApplicationConfig application = new ApplicationConfig("app"); application.setArchitecture("arch"); assertThat(application.getArchitecture(), equalTo("arch")); } @Test - void testEnvironment1() throws Exception { + void testEnvironment1() { ApplicationConfig application = new ApplicationConfig("app"); application.setEnvironment("develop"); assertThat(application.getEnvironment(), equalTo("develop")); @@ -113,7 +113,7 @@ class ApplicationConfigTest { } @Test - void testEnvironment2() throws Exception { + void testEnvironment2() { Assertions.assertThrows(IllegalStateException.class, () -> { ApplicationConfig application = new ApplicationConfig("app"); application.setEnvironment("illegal-env"); @@ -121,7 +121,7 @@ class ApplicationConfigTest { } @Test - void testRegistry() throws Exception { + void testRegistry() { ApplicationConfig application = new ApplicationConfig("app"); RegistryConfig registry = new RegistryConfig(); application.setRegistry(registry); @@ -132,7 +132,7 @@ class ApplicationConfigTest { } @Test - void testMonitor() throws Exception { + void testMonitor() { ApplicationConfig application = new ApplicationConfig("app"); application.setMonitor(new MonitorConfig("monitor-addr")); assertThat(application.getMonitor().getAddress(), equalTo("monitor-addr")); @@ -141,21 +141,21 @@ class ApplicationConfigTest { } @Test - void testLogger() throws Exception { + void testLogger() { ApplicationConfig application = new ApplicationConfig("app"); application.setLogger("log4j"); assertThat(application.getLogger(), equalTo("log4j")); } @Test - void testDefault() throws Exception { + void testDefault() { ApplicationConfig application = new ApplicationConfig("app"); application.setDefault(true); assertThat(application.isDefault(), is(true)); } @Test - void testDumpDirectory() throws Exception { + void testDumpDirectory() { ApplicationConfig application = new ApplicationConfig("app"); application.setDumpDirectory("/dump"); assertThat(application.getDumpDirectory(), equalTo("/dump")); @@ -165,7 +165,7 @@ class ApplicationConfigTest { } @Test - void testQosEnable() throws Exception { + void testQosEnable() { ApplicationConfig application = new ApplicationConfig("app"); application.setQosEnable(true); assertThat(application.getQosEnable(), is(true)); @@ -175,14 +175,14 @@ class ApplicationConfigTest { } @Test - void testQosPort() throws Exception { + void testQosPort() { ApplicationConfig application = new ApplicationConfig("app"); application.setQosPort(8080); assertThat(application.getQosPort(), equalTo(8080)); } @Test - void testQosAcceptForeignIp() throws Exception { + void testQosAcceptForeignIp() { ApplicationConfig application = new ApplicationConfig("app"); application.setQosAcceptForeignIp(true); assertThat(application.getQosAcceptForeignIp(), is(true)); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java index a966a3d794..a3007f4503 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ArgumentConfigTest.java @@ -29,28 +29,28 @@ import static org.hamcrest.Matchers.is; class ArgumentConfigTest { @Test - void testIndex() throws Exception { + void testIndex() { ArgumentConfig argument = new ArgumentConfig(); argument.setIndex(1); assertThat(argument.getIndex(), is(1)); } @Test - void testType() throws Exception { + void testType() { ArgumentConfig argument = new ArgumentConfig(); argument.setType("int"); assertThat(argument.getType(), equalTo("int")); } @Test - void testCallback() throws Exception { + void testCallback() { ArgumentConfig argument = new ArgumentConfig(); argument.setCallback(true); assertThat(argument.isCallback(), is(true)); } @Test - void testArguments() throws Exception { + void testArguments() { ArgumentConfig argument = new ArgumentConfig(); argument.setIndex(1); argument.setType("int"); @@ -60,4 +60,4 @@ class ArgumentConfigTest { assertThat(parameters, hasEntry("callback", "true")); assertThat(parameters.size(), is(1)); } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/cache/CacheTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/cache/CacheTest.java index 688192b06b..839b8d3c15 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/cache/CacheTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/cache/CacheTest.java @@ -128,7 +128,7 @@ class CacheTest { } @Test - void testCacheProvider() throws Exception { + void testCacheProvider() { CacheFactory cacheFactory = ExtensionLoader.getExtensionLoader(CacheFactory.class).getAdaptiveExtension(); Map parameters = new HashMap(); @@ -141,4 +141,4 @@ class CacheTest { assertTrue(cache instanceof ThreadLocalCache); } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java index 70d3df05bd..de42881568 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java @@ -40,7 +40,7 @@ class DelegateProviderMetaDataInvokerTest { } @Test - void testDelegate() throws Exception { + void testDelegate() { DelegateProviderMetaDataInvoker delegate = new DelegateProviderMetaDataInvoker(invoker, service); delegate.getInterface(); @@ -57,4 +57,4 @@ class DelegateProviderMetaDataInvokerTest { assertThat(delegate.getMetadata(), sameInstance(service)); } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java index 4031af29aa..b71662cd3b 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6000/Issue6000Test.java @@ -50,7 +50,7 @@ class Issue6000Test { } @Test - void test() throws Exception { + void test() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Issue6000Test.class); try { @@ -67,4 +67,4 @@ class Issue6000Test { } } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java index 8b1c332c67..b3c996b36a 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue6252/Issue6252Test.java @@ -52,7 +52,7 @@ class Issue6252Test { private DemoService demoService; @Test - void test() throws Exception { + void test() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Issue6252Test.class); try { DemoService demoService = context.getBean(DemoService.class); @@ -61,4 +61,4 @@ class Issue6252Test { } } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java index c1e0ede149..84f7cb494c 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/issue7003/Issue7003Test.java @@ -59,7 +59,7 @@ class Issue7003Test { } @Test - void test() throws Exception { + void test() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Issue7003Test.class); try { @@ -90,4 +90,4 @@ class Issue7003Test { private HelloService helloService; } -} \ No newline at end of file +} diff --git a/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java b/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java index c4412ae9cd..a14877b123 100644 --- a/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java +++ b/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/support/jcache/JCacheFactoryTest.java @@ -32,7 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; class JCacheFactoryTest extends AbstractCacheFactoryTest { @Test - void testJCacheFactory() throws Exception { + void testJCacheFactory() { Cache cache = super.constructCache(); assertThat(cache instanceof JCache, is(true)); } @@ -52,4 +52,4 @@ class JCacheFactoryTest extends AbstractCacheFactoryTest { protected AbstractCacheFactory getCacheFactory() { return new JCacheFactory(); } -} \ No newline at end of file +} diff --git a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java b/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java index d3a52c71e8..4f8371966a 100644 --- a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java +++ b/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java @@ -121,7 +121,7 @@ class KubernetesServiceDiscoveryTest { } @Test - void testEndpointsUpdate() throws Exception { + void testEndpointsUpdate() { serviceDiscovery.setCurrentHostname(POD_NAME); serviceDiscovery.setKubernetesClient(mockClient); @@ -191,7 +191,7 @@ class KubernetesServiceDiscoveryTest { } @Test - void testServiceUpdate() throws Exception { + void testServiceUpdate() { serviceDiscovery.setCurrentHostname(POD_NAME); serviceDiscovery.setKubernetesClient(mockClient); diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java index 0f77c49848..14432ee0a1 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java @@ -47,7 +47,7 @@ class AbstractServiceNameMappingTest { } @AfterEach - public void clearup() throws Exception { + public void clearup() { mapping.removeCachedMapping(ServiceNameMapping.buildMappingKey(url)); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java index f8df70bc35..fc091b01d9 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java @@ -82,7 +82,7 @@ class AbstractMetadataReportTest { } @Test - void testStoreProviderUsual() throws ClassNotFoundException, InterruptedException { + void testStoreProviderUsual() throws ClassNotFoundException { String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService"; String version = "1.0.0"; String group = null; @@ -96,7 +96,7 @@ class AbstractMetadataReportTest { } @Test - void testStoreProviderSync() throws ClassNotFoundException, InterruptedException { + void testStoreProviderSync() throws ClassNotFoundException { String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService"; String version = "1.0.0"; String group = null; @@ -107,7 +107,7 @@ class AbstractMetadataReportTest { } @Test - void testFileExistAfterPut() throws InterruptedException, ClassNotFoundException { + void testFileExistAfterPut() throws ClassNotFoundException { //just for one method URL singleUrl = URL.valueOf("redis://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.metadata.store.InterfaceNameTestService?version=1.0.0&application=singleTest"); NewMetadataReport singleMetadataReport = new NewMetadataReport(singleUrl); @@ -129,7 +129,7 @@ class AbstractMetadataReportTest { } @Test - void testRetry() throws InterruptedException, ClassNotFoundException { + void testRetry() throws ClassNotFoundException { String interfaceName = "org.apache.dubbo.metadata.store.RetryTestService"; String version = "1.0.0.retry"; String group = null; @@ -164,7 +164,7 @@ class AbstractMetadataReportTest { } @Test - void testRetryCancel() throws InterruptedException, ClassNotFoundException { + void testRetryCancel() throws ClassNotFoundException { String interfaceName = "org.apache.dubbo.metadata.store.RetryTestService"; String version = "1.0.0.retrycancel"; String group = null; @@ -201,7 +201,7 @@ class AbstractMetadataReportTest { return providerMetadataIdentifier; } - private MetadataIdentifier storeConsumer(AbstractMetadataReport abstractMetadataReport, String interfaceName, String version, String group, String application, Map tmp) throws ClassNotFoundException { + private MetadataIdentifier storeConsumer(AbstractMetadataReport abstractMetadataReport, String interfaceName, String version, String group, String application, Map tmp) { URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?version=" + version + "&application=" + application + (group == null ? "" : "&group=" + group) + "&testPKey=9090"); @@ -214,7 +214,7 @@ class AbstractMetadataReportTest { } @Test - void testPublishAll() throws ClassNotFoundException, InterruptedException { + void testPublishAll() throws ClassNotFoundException { ThreadPoolExecutor reportCacheExecutor = (ThreadPoolExecutor) abstractMetadataReport.getReportCacheExecutor(); assertTrue(abstractMetadataReport.store.isEmpty()); diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/AbstractAnnotationProcessingTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/AbstractAnnotationProcessingTest.java index d224f077be..fb0421eb91 100644 --- a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/AbstractAnnotationProcessingTest.java +++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/AbstractAnnotationProcessingTest.java @@ -47,7 +47,7 @@ public abstract class AbstractAnnotationProcessingTest { protected Types types; @BeforeEach - public final void init() throws IOException { + public final void init() { testInstanceHolder.set(this); } diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/MockConfigService.java b/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/MockConfigService.java index 86b5b879f7..a2970e282e 100644 --- a/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/MockConfigService.java +++ b/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/MockConfigService.java @@ -27,37 +27,37 @@ public class MockConfigService implements ConfigService { } @Override - public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException { + public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) { return null; } @Override - public void addListener(String dataId, String group, Listener listener) throws NacosException { + public void addListener(String dataId, String group, Listener listener) { } @Override - public boolean publishConfig(String dataId, String group, String content) throws NacosException { + public boolean publishConfig(String dataId, String group, String content) { return false; } @Override - public boolean publishConfig(String dataId, String group, String content, String type) throws NacosException { + public boolean publishConfig(String dataId, String group, String content, String type) { return false; } @Override - public boolean publishConfigCas(String dataId, String group, String content, String casMd5) throws NacosException { + public boolean publishConfigCas(String dataId, String group, String content, String casMd5) { return false; } @Override - public boolean publishConfigCas(String dataId, String group, String content, String casMd5, String type) throws NacosException { + public boolean publishConfigCas(String dataId, String group, String content, String casMd5, String type) { return false; } @Override - public boolean removeConfig(String dataId, String group) throws NacosException { + public boolean removeConfig(String dataId, String group) { return false; } @@ -72,7 +72,7 @@ public class MockConfigService implements ConfigService { } @Override - public void shutDown() throws NacosException { + public void shutDown() { } } diff --git a/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java index c9b4e125de..2b7dc9413e 100644 --- a/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java +++ b/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java @@ -59,7 +59,7 @@ class RedisMetadataReportTest { URL registryUrl; @BeforeEach - public void constructor(final TestInfo testInfo) throws IOException { + public void constructor(final TestInfo testInfo) { final boolean usesAuthentication = usesAuthentication(testInfo); int redisPort = 0; IOException exception = null; diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilterTest.java index 057279fe66..1fe702e193 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilterTest.java @@ -36,7 +36,7 @@ import org.assertj.core.api.BDDAssertions; class ObservationReceiverFilterTest extends AbstractObservationFilterTest { @Override - public SampleTestRunnerConsumer yourCode() throws Exception { + public SampleTestRunnerConsumer yourCode() { return (buildingBlocks, meterRegistry) -> { setupConfig(); setupAttachments(buildingBlocks.getTracer()); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationSenderFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationSenderFilterTest.java index b68edf0223..e25c2412b6 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationSenderFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationSenderFilterTest.java @@ -29,7 +29,7 @@ import org.assertj.core.api.BDDAssertions; class ObservationSenderFilterTest extends AbstractObservationFilterTest { @Override - public SampleTestRunnerConsumer yourCode() throws Exception { + public SampleTestRunnerConsumer yourCode() { return (buildingBlocks, meterRegistry) -> { setupConfig(); setupAttachments(); diff --git a/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/DubboMonitorTest.java b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/DubboMonitorTest.java index ed67f844b1..df40e97627 100644 --- a/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/DubboMonitorTest.java +++ b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/DubboMonitorTest.java @@ -107,7 +107,7 @@ class DubboMonitorTest { }; @Test - void testCount() throws Exception { + void testCount() { DubboMonitor monitor = new DubboMonitor(monitorInvoker, monitorService); URL statistics = new URLBuilder(DUBBO_PROTOCOL, "10.20.153.10", 0) .addParameter(APPLICATION_KEY, "morgan") @@ -141,7 +141,7 @@ class DubboMonitorTest { } @Test - void testMonitorFactory() throws Exception { + void testMonitorFactory() { MockMonitorService monitorService = new MockMonitorService(); URL statistics = new URLBuilder(DUBBO_PROTOCOL, "10.20.153.10", 0) .addParameter(APPLICATION_KEY, "morgan") diff --git a/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java index d1ec4113f7..508f3d3b10 100644 --- a/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java +++ b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java @@ -136,7 +136,7 @@ class MetricsFilterTest { } } - private void testConsumerSuccess() throws Exception { + private void testConsumerSuccess() { IMetricManager metricManager = MetricManager.getIMetricManager(); metricManager.clear(); MetricsFilter metricsFilter = new MetricsFilter(); @@ -197,7 +197,7 @@ class MetricsFilterTest { } - private void testProviderSuccess() throws Exception { + private void testProviderSuccess() { IMetricManager metricManager = MetricManager.getIMetricManager(); metricManager.clear(); MetricsFilter metricsFilter = new MetricsFilter(); @@ -354,4 +354,4 @@ class MetricsFilterTest { Assertions.assertEquals(50.0 / 100.0, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_rate")); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java index ffe32eefe9..fd0957f1e1 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java @@ -26,7 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class CommandContextFactoryTest { @Test - void testNewInstance() throws Exception { + void testNewInstance() { CommandContext context = CommandContextFactory.newInstance("test"); assertThat(context.getCommandName(), equalTo("test")); context = CommandContextFactory.newInstance("command", new String[]{"hello"}, true); @@ -34,4 +34,4 @@ class CommandContextFactoryTest { assertThat(context.getArgs(), Matchers.arrayContaining("hello")); assertTrue(context.isHttp()); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java index 7fd82f63ca..c2da2c4b6f 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java @@ -29,7 +29,7 @@ import static org.hamcrest.Matchers.equalTo; class DefaultCommandExecutorTest { @Test - void testExecute1() throws Exception { + void testExecute1() { Assertions.assertThrows(NoSuchCommandException.class, () -> { DefaultCommandExecutor executor = new DefaultCommandExecutor(FrameworkModel.defaultModel()); executor.execute(CommandContextFactory.newInstance("not-exit")); @@ -48,7 +48,7 @@ class DefaultCommandExecutorTest { } @Test - void shouldNotThrowPermissionDenyException_GivenPermissionConfigAndMatchDefaultPUBLICCmdPermissionLevel() throws Exception { + void shouldNotThrowPermissionDenyException_GivenPermissionConfigAndMatchDefaultPUBLICCmdPermissionLevel() { DefaultCommandExecutor executor = new DefaultCommandExecutor(FrameworkModel.defaultModel()); final CommandContext commandContext = CommandContextFactory.newInstance("live", new String[]{"dubbo"}, false); commandContext.setQosConfiguration(QosConfiguration.builder().build()); @@ -56,7 +56,7 @@ class DefaultCommandExecutorTest { } @Test - void shouldNotThrowPermissionDenyException_GivenPermissionConfigAndNotMatchCmdPermissionLevel() throws Exception { + void shouldNotThrowPermissionDenyException_GivenPermissionConfigAndNotMatchCmdPermissionLevel() { DefaultCommandExecutor executor = new DefaultCommandExecutor(FrameworkModel.defaultModel()); final CommandContext commandContext = CommandContextFactory.newInstance("live", new String[]{"dubbo"}, false); // 1 PROTECTED diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java index 728766fd3c..d068a51094 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java @@ -37,7 +37,7 @@ import static org.mockito.Mockito.when; class HttpCommandDecoderTest { @Test - void decodeGet() throws Exception { + void decodeGet() { HttpRequest request = mock(HttpRequest.class); when(request.uri()).thenReturn("localhost:80/test"); when(request.method()).thenReturn(HttpMethod.GET); @@ -50,7 +50,7 @@ class HttpCommandDecoderTest { } @Test - void decodePost() throws Exception { + void decodePost() { FullHttpRequest request = mock(FullHttpRequest.class); when(request.uri()).thenReturn("localhost:80/test"); when(request.method()).thenReturn(HttpMethod.POST); @@ -62,4 +62,4 @@ class HttpCommandDecoderTest { assertThat(context.isHttp(), is(true)); assertThat(context.getArgs(), arrayContaining("b", "d")); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java index d0c8f78af9..9728fda5a9 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java @@ -27,7 +27,7 @@ import static org.hamcrest.Matchers.containsString; class HelpTest { @Test - void testMainHelp() throws Exception { + void testMainHelp() { Help help = new Help(FrameworkModel.defaultModel()); String output = help.execute(Mockito.mock(CommandContext.class), null); assertThat(output, containsString("greeting")); @@ -39,7 +39,7 @@ class HelpTest { } @Test - void testGreeting() throws Exception { + void testGreeting() { Help help = new Help(FrameworkModel.defaultModel()); String output = help.execute(Mockito.mock(CommandContext.class), new String[]{"greeting"}); assertThat(output, containsString("COMMAND NAME")); @@ -47,4 +47,4 @@ class HelpTest { assertThat(output, containsString("EXAMPLE")); assertThat(output, containsString("greeting dubbo")); } -} \ No newline at end of file +} diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java index 03adb56fbc..0f9a347f48 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMappingTest.java @@ -103,7 +103,7 @@ class MetadataServiceNameMappingTest { private int counter = 0; @Override - public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable { + public Boolean answer(InvocationOnMock invocationOnMock) { if (++counter == 10) { return true; } diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java index 537486cce5..79c74a70dc 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/MigrationRuleListenerTest.java @@ -86,7 +86,7 @@ class MigrationRuleListenerTest { * Check local rule take effect */ @Test - void test() throws InterruptedException { + void test() { DynamicConfiguration dynamicConfiguration = Mockito.mock(DynamicConfiguration.class); ApplicationModel.reset(); @@ -166,7 +166,7 @@ class MigrationRuleListenerTest { * 2. remote rule change and all invokers gets notified */ @Test - void testWithConfigurationListenerAndLocalRule() throws InterruptedException { + void testWithConfigurationListenerAndLocalRule() { DynamicConfiguration dynamicConfiguration = Mockito.mock(DynamicConfiguration.class); Mockito.doReturn(remoteRule).when(dynamicConfiguration).getConfig(Mockito.anyString(), Mockito.anyString()); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryFactoryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryFactoryTest.java index ae66edc2cf..436924531e 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryFactoryTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryFactoryTest.java @@ -91,7 +91,7 @@ class AbstractRegistryFactoryTest { } @Test - void testRegistryFactoryCache() throws Exception { + void testRegistryFactoryCache() { URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostAddress() + ":2233"); Registry registry1 = registryFactory.getRegistry(url); Registry registry2 = registryFactory.getRegistry(url); @@ -102,14 +102,14 @@ class AbstractRegistryFactoryTest { * Registration center address `dubbo` does not resolve */ // @Test - public void testRegistryFactoryIpCache() throws Exception { + public void testRegistryFactoryIpCache() { Registry registry1 = registryFactory.getRegistry(URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":2233")); Registry registry2 = registryFactory.getRegistry(URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostAddress() + ":2233")); Assertions.assertEquals(registry1, registry2); } @Test - void testRegistryFactoryGroupCache() throws Exception { + void testRegistryFactoryGroupCache() { Registry registry1 = registryFactory.getRegistry(URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":2233?group=aaa")); Registry registry2 = registryFactory.getRegistry(URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":2233?group=bbb")); Assertions.assertNotSame(registry1, registry2); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryTest.java index ce7ddd2690..637df6ba5b 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/AbstractRegistryTest.java @@ -90,10 +90,9 @@ class AbstractRegistryTest { * Test method for * {@link org.apache.dubbo.registry.support.AbstractRegistry#register(URL)}. * - * @throws Exception */ @Test - void testRegister() throws Exception { + void testRegister() { //test one url abstractRegistry.register(mockUrl); assert abstractRegistry.getRegistered().contains(mockUrl); diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java index 47a350ba12..987ec388f2 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java @@ -159,7 +159,7 @@ class DefaultFutureTest { } @Test - void testClose() throws Exception { + void testClose() { Channel channel = new MockedChannel(); Request request = new Request(123); ExecutorService executor = ExtensionLoader.getExtensionLoader(ExecutorRepository.class) diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java index 59236928a3..7dd38a60d2 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java @@ -85,12 +85,12 @@ class AbstractCodecTest { private AbstractCodec getAbstractCodec() { AbstractCodec codec = new AbstractCodec() { @Override - public void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException { + public void encode(Channel channel, ChannelBuffer buffer, Object message) { } @Override - public Object decode(Channel channel, ChannelBuffer buffer) throws IOException { + public Object decode(Channel channel, ChannelBuffer buffer) { return null; } }; diff --git a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java index 243935500d..a21ed9e114 100644 --- a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java +++ b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java @@ -53,7 +53,7 @@ public abstract class ClientToServerTest { } @BeforeEach - protected void tearDown() throws Exception { + protected void tearDown() { try { if (server != null) server.close(); diff --git a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyStringTest.java b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyStringTest.java index 271e791173..d1221f8ec0 100644 --- a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyStringTest.java +++ b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/NettyStringTest.java @@ -45,7 +45,7 @@ class NettyStringTest { } @AfterAll - public static void tearDown() throws Exception { + public static void tearDown() { try { if (server != null) server.close(); @@ -56,7 +56,7 @@ class NettyStringTest { } @Test - void testHandler() throws Exception { + void testHandler() { //Thread.sleep(20000); /*client.request("world\r\n"); Future future = client.request("world", 10000); diff --git a/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/support/AbstractZookeeperTransporterTest.java b/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/support/AbstractZookeeperTransporterTest.java index 043ba1c33d..a90d735e4e 100644 --- a/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/support/AbstractZookeeperTransporterTest.java +++ b/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/support/AbstractZookeeperTransporterTest.java @@ -80,7 +80,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testFetchAndUpdateZookeeperClientCache() throws Exception { + void testFetchAndUpdateZookeeperClientCache() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zookeeperServerPort1 + ",127.0.0.1:" + zookeeperServerPort2 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url); //just for connected @@ -120,7 +120,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testNotRepeatConnect() throws Exception { + void testNotRepeatConnect() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); URL url2 = URL.valueOf(zookeeperConnectionAddress2 + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true"); ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url); @@ -139,7 +139,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testRepeatConnectForBackUpAdd() throws Exception { + void testRepeatConnectForBackUpAdd() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zookeeperServerPort1 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); URL url2 = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.metadata.store.MetadataReport?backup=127.0.0.1:" + zookeeperServerPort2 + "&address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true"); @@ -159,7 +159,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testRepeatConnectForNoMatchBackUpAdd() throws Exception { + void testRepeatConnectForNoMatchBackUpAdd() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zookeeperServerPort1 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); URL url2 = URL.valueOf(zookeeperConnectionAddress2 + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true"); @@ -179,7 +179,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testSameHostWithDifferentUser() throws Exception { + void testSameHostWithDifferentUser() { URL url1 = URL.valueOf("zookeeper://us1:pw1@127.0.0.1:" + zookeeperServerPort1 + "/path1"); URL url2 = URL.valueOf("zookeeper://us2:pw2@127.0.0.1:" + zookeeperServerPort1 + "/path2"); ZookeeperClient client1 = abstractZookeeperTransporter.connect(url1); diff --git a/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClientTest.java b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClientTest.java index 61aa0361ea..7ece96bc82 100644 --- a/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClientTest.java +++ b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClientTest.java @@ -97,7 +97,7 @@ class CuratorZookeeperClientTest { curatorClient.addTargetChildListener(path, new CuratorZookeeperClient.CuratorWatcherImpl() { @Override - public void process(WatchedEvent watchedEvent) throws Exception { + public void process(WatchedEvent watchedEvent) { countDownLatch.countDown(); } }); @@ -116,7 +116,7 @@ class CuratorZookeeperClientTest { @Test @Disabled("Global registry center cannot stop") - public void testWithStoppedServer() throws IOException { + public void testWithStoppedServer() { Assertions.assertThrows(IllegalStateException.class, () -> { curatorClient.create("/testPath", true, true); curatorClient.delete("/testPath"); @@ -225,7 +225,7 @@ class CuratorZookeeperClientTest { curatorClient.addTargetDataListener(path + "/d.json", new CuratorZookeeperClient.NodeCacheListenerImpl() { @Override - public void nodeChanged() throws Exception { + public void nodeChanged() { atomicInteger.incrementAndGet(); } }); @@ -305,7 +305,7 @@ class CuratorZookeeperClientTest { } @Test - void testPersistentCas2() throws Exception { + void testPersistentCas2() { // test update failed when others create success String path = "/dubbo/mapping/org.apache.dubbo.demo.DemoService"; CuratorZookeeperClient curatorClient = new CuratorZookeeperClient(URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService")); @@ -430,7 +430,7 @@ class CuratorZookeeperClientTest { } @Test - void testEphemeralCas2() throws Exception { + void testEphemeralCas2() { // test update failed when others create success String path = "/dubbo/mapping/org.apache.dubbo.demo.DemoService"; CuratorZookeeperClient curatorClient = new CuratorZookeeperClient(URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService")); diff --git a/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/support/AbstractZookeeperTransporterTest.java b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/support/AbstractZookeeperTransporterTest.java index bab6987656..506a4f41af 100644 --- a/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/support/AbstractZookeeperTransporterTest.java +++ b/dubbo-remoting/dubbo-remoting-zookeeper/src/test/java/org/apache/dubbo/remoting/zookeeper/curator/support/AbstractZookeeperTransporterTest.java @@ -84,7 +84,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testFetchAndUpdateZookeeperClientCache() throws Exception { + void testFetchAndUpdateZookeeperClientCache() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zookeeperServerPort1 + ",127.0.0.1:" + zookeeperServerPort2 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url); //just for connected @@ -124,7 +124,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testNotRepeatConnect() throws Exception { + void testNotRepeatConnect() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); URL url2 = URL.valueOf(zookeeperConnectionAddress2 + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true"); ZookeeperClient newZookeeperClient = abstractZookeeperTransporter.connect(url); @@ -143,7 +143,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testRepeatConnectForBackUpAdd() throws Exception { + void testRepeatConnectForBackUpAdd() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zookeeperServerPort1 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); URL url2 = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.metadata.store.MetadataReport?backup=127.0.0.1:" + zookeeperServerPort2 + "&address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true"); @@ -163,7 +163,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testRepeatConnectForNoMatchBackUpAdd() throws Exception { + void testRepeatConnectForNoMatchBackUpAdd() { URL url = URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService?backup=127.0.0.1:" + zookeeperServerPort1 + "&application=metadatareport-local-xml-provider2&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=47418&specVersion=2.7.0-SNAPSHOT×tamp=1547102428828"); URL url2 = URL.valueOf(zookeeperConnectionAddress2 + "/org.apache.dubbo.metadata.store.MetadataReport?address=zookeeper://127.0.0.1:2181&application=metadatareport-local-xml-provider2&cycle-report=false&interface=org.apache.dubbo.metadata.store.MetadataReport&retry-period=4590&retry-times=23&sync-report=true"); @@ -183,7 +183,7 @@ class AbstractZookeeperTransporterTest { } @Test - void testSameHostWithDifferentUser() throws Exception { + void testSameHostWithDifferentUser() { URL url1 = URL.valueOf("zookeeper://us1:pw1@127.0.0.1:" + zookeeperServerPort1 + "/path1"); URL url2 = URL.valueOf("zookeeper://us2:pw2@127.0.0.1:" + zookeeperServerPort1 + "/path2"); ZookeeperClient client1 = abstractZookeeperTransporter.connect(url1); diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java index c445b8e8ed..24ee75905a 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java @@ -98,7 +98,7 @@ class ActiveLimitFilterTest { } @Test - void testInvokeTimeOut() throws Exception { + void testInvokeTimeOut() { int totalThread = 100; int maxActives = 10; long timeout = 1; @@ -147,7 +147,7 @@ class ActiveLimitFilterTest { } @Test - void testInvokeNotTimeOut() throws Exception { + void testInvokeNotTimeOut() { int totalThread = 100; int maxActives = 10; long timeout = 1000; diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java index 823eec9903..bcfdf265de 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java @@ -37,7 +37,7 @@ class DefaultTPSLimiterTest { private final DefaultTPSLimiter defaultTPSLimiter = new DefaultTPSLimiter(); @Test - void testIsAllowable() throws Exception { + void testIsAllowable() { Invocation invocation = new MockInvocation(); URL url = URL.valueOf("test://test"); url = url.addParameter(INTERFACE_KEY, "org.apache.dubbo.rpc.file.TpsService"); @@ -49,7 +49,7 @@ class DefaultTPSLimiterTest { } @Test - void testIsNotAllowable() throws Exception { + void testIsNotAllowable() { Invocation invocation = new MockInvocation(); URL url = URL.valueOf("test://test"); url = url.addParameter(INTERFACE_KEY, "org.apache.dubbo.rpc.file.TpsService"); @@ -65,7 +65,7 @@ class DefaultTPSLimiterTest { } @Test - void testTPSLimiterForMethodLevelConfig() throws Exception { + void testTPSLimiterForMethodLevelConfig() { Invocation invocation = new MockInvocation(); URL url = URL.valueOf("test://test"); url = url.addParameter(INTERFACE_KEY, "org.apache.dubbo.rpc.file.TpsService"); @@ -83,7 +83,7 @@ class DefaultTPSLimiterTest { } @Test - void testConfigChange() throws Exception { + void testConfigChange() { Invocation invocation = new MockInvocation(); URL url = URL.valueOf("test://test"); url = url.addParameter(INTERFACE_KEY, "org.apache.dubbo.rpc.file.TpsService"); diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/proxy/AbstractProxyTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/proxy/AbstractProxyTest.java index 5b4de528f7..52091590a4 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/proxy/AbstractProxyTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/proxy/AbstractProxyTest.java @@ -38,7 +38,7 @@ public abstract class AbstractProxyTest { public static ProxyFactory factory; @Test - void testGetProxy() throws Exception { + void testGetProxy() { URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1"); MyInvoker invoker = new MyInvoker<>(url); @@ -61,7 +61,7 @@ public abstract class AbstractProxyTest { } @Test - void testGetInvoker() throws Exception { + void testGetInvoker() { URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1"); DemoService origin = new DemoServiceImpl(); diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java index 4442d7cf11..e245754694 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java @@ -78,7 +78,7 @@ class ArgumentCallbackTest { public void setUp() { } - public void initOrResetUrl(int callbacks, int timeout) throws Exception { + public void initOrResetUrl(int callbacks, int timeout) { int port = NetUtils.getAvailablePort(); consumerUrl = serviceURL = URL.valueOf("dubbo://127.0.0.1:" + port + "/" + IDemoService.class.getName() + "?group=test" + "&xxx.0.callback=true" @@ -206,7 +206,7 @@ class ArgumentCallbackTest { } @Test - void TestCallbackConsumerLimit() throws Exception { + void TestCallbackConsumerLimit() { Assertions.assertThrows(RpcException.class, () -> { initOrResetUrl(1, 1000); // URL cannot be transferred automatically from the server side to the client side by using API, instead, @@ -233,7 +233,7 @@ class ArgumentCallbackTest { } @Test - void TestCallbackProviderLimit() throws Exception { + void TestCallbackProviderLimit() { Assertions.assertThrows(RpcException.class, () -> { initOrResetUrl(1, 1000); // URL cannot be transferred automatically from the server side to the client side by using API, instead, diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvailableTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvailableTest.java index 96ca315069..590bc0ad53 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvailableTest.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvailableTest.java @@ -47,7 +47,7 @@ class DubboInvokerAvailableTest { private static ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); @BeforeAll - public static void setUpBeforeClass() throws Exception { + public static void setUpBeforeClass() { } @BeforeEach @@ -91,7 +91,7 @@ class DubboInvokerAvailableTest { @Disabled @Test - void test_normal_channel_close_wait_gracefully() throws Exception { + void test_normal_channel_close_wait_gracefully() { int testPort = NetUtils.getAvailablePort(); URL url = URL.valueOf("dubbo://127.0.0.1:" + testPort + "/org.apache.dubbo.rpc.protocol.dubbo.IDemoService?scope=true&lazy=false"); Exporter exporter = ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url); diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java index 33c59fb502..0da2ea933e 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java @@ -74,7 +74,7 @@ class DubboProtocolTest { } @Test - void testDemoProtocol() throws Exception { + void testDemoProtocol() { DemoService service = new DemoServiceImpl(); int port = NetUtils.getAvailablePort(); protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("dubbo://127.0.0.1:" + port + "/" + DemoService.class.getName() + "?codec=exchange"))); @@ -187,7 +187,7 @@ class DubboProtocolTest { } @Test - void testPerm() throws Exception { + void testPerm() { DemoService service = new DemoServiceImpl(); int port = NetUtils.getAvailablePort(); protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("dubbo://127.0.0.1:" + port + "/" + DemoService.class.getName() + "?codec=exchange"))); @@ -201,7 +201,7 @@ class DubboProtocolTest { @Test @Disabled - public void testNonSerializedParameter() throws Exception { + public void testNonSerializedParameter() { DemoService service = new DemoServiceImpl(); int port = NetUtils.getAvailablePort(); protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("dubbo://127.0.0.1:" + port + "/" + DemoService.class.getName() + "?codec=exchange"))); @@ -217,7 +217,7 @@ class DubboProtocolTest { @Test @Disabled - public void testReturnNonSerialized() throws Exception { + public void testReturnNonSerialized() { DemoService service = new DemoServiceImpl(); int port = NetUtils.getAvailablePort(); protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("dubbo://127.0.0.1:" + port + "/" + DemoService.class.getName() + "?codec=exchange"))); @@ -256,7 +256,7 @@ class DubboProtocolTest { } @Test - void testPayloadOverException() throws Exception { + void testPayloadOverException() { DemoService service = new DemoServiceImpl(); int port = NetUtils.getAvailablePort(); protocol.export(proxy.getInvoker(service, DemoService.class, diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java index 8ad582a0ce..ee949d13ce 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java @@ -82,7 +82,7 @@ class InjvmProtocolTest { } @Test - void testLocalProtocolWithToken() throws Exception { + void testLocalProtocolWithToken() { DemoService service = new DemoServiceImpl(); Invoker invoker = proxy.getInvoker(service, DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService?token=abc").addParameter(INTERFACE_KEY, DemoService.class.getName())); assertTrue(invoker.isAvailable()); @@ -93,7 +93,7 @@ class InjvmProtocolTest { } @Test - void testIsInjvmRefer() throws Exception { + void testIsInjvmRefer() { DemoService service = new DemoServiceImpl(); URL url = URL.valueOf("injvm://127.0.0.1/TestService") .addParameter(INTERFACE_KEY, DemoService.class.getName()); @@ -124,7 +124,7 @@ class InjvmProtocolTest { } @Test - void testLocalProtocolAsync() throws Exception { + void testLocalProtocolAsync() { DemoService service = new DemoServiceImpl(); URL url = URL.valueOf("injvm://127.0.0.1/TestService") .addParameter(ASYNC_KEY, true) diff --git a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java b/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java index cae21deb37..71875022a6 100644 --- a/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java +++ b/dubbo-xds/src/test/java/org/apache/dubbo/registry/xds/util/bootstrap/BootstrapperTest.java @@ -142,7 +142,7 @@ class BootstrapperTest { private static BootstrapperImpl.FileReader createFileReader(final String rawData) { return new BootstrapperImpl.FileReader() { @Override - public String readFile(String path) throws IOException { + public String readFile(String path) { return rawData; } }; From 53eeae310f1cea20c15139d2e9a579da5f96cb42 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Mon, 27 Feb 2023 20:29:04 +0800 Subject: [PATCH 044/144] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b23fea32b..473717f0c4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Apache Dubbo Project -[![Build Status](https://github.com/apache/dubbo/workflows/Build%20and%20Test%20For%20Dubbo%203/badge.svg?branch=3.0)](https://github.com/apache/dubbo/actions/workflows/build-and-test-3.yml?query=branch%3A3.0) -[![Codecov](https://codecov.io/gh/apache/dubbo/branch/3.0/graph/badge.svg)](https://codecov.io/gh/apache/dubbo) +[![Build and Test For PR](https://github.com/apache/dubbo/actions/workflows/build-and-test-pr.yml/badge.svg)](https://github.com/apache/dubbo/actions/workflows/build-and-test-pr.yml) +[![Codecov](https://codecov.io/gh/apache/dubbo/branch/3.2/graph/badge.svg)](https://codecov.io/gh/apache/dubbo) ![Maven](https://img.shields.io/maven-central/v/org.apache.dubbo/dubbo.svg) ![License](https://img.shields.io/github/license/alibaba/dubbo.svg) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/apache/dubbo.svg)](http://isitmaintained.com/project/apache/dubbo "Average time to resolve an issue") From 32ada2487d570e675a1811e7a4bd9332373bfe6e Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Mon, 27 Feb 2023 20:31:00 +0800 Subject: [PATCH 045/144] Fix heartbeat failed if serialization changed (#11512) fixes #11268 --- .../remoting/exchange/HeartBeatRequest.java | 33 +++++++++++++++++++ .../remoting/exchange/HeartBeatResponse.java | 33 +++++++++++++++++++ .../exchange/codec/ExchangeCodec.java | 18 ++++++---- .../support/header/HeartbeatHandler.java | 10 ++++-- .../dubbo/rpc/protocol/dubbo/DubboCodec.java | 22 +++++++++---- 5 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatRequest.java create mode 100644 dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatResponse.java diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatRequest.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatRequest.java new file mode 100644 index 0000000000..3cacbb9577 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatRequest.java @@ -0,0 +1,33 @@ +/* + * 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.remoting.exchange; + +public class HeartBeatRequest extends Request { + private byte proto; + + public HeartBeatRequest(long id) { + super(id); + } + + public byte getProto() { + return proto; + } + + public void setProto(byte proto) { + this.proto = proto; + } +} diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatResponse.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatResponse.java new file mode 100644 index 0000000000..35d4477c49 --- /dev/null +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/HeartBeatResponse.java @@ -0,0 +1,33 @@ +/* + * 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.remoting.exchange; + +public class HeartBeatResponse extends Response{ + private byte proto; + + public HeartBeatResponse(long id, String version) { + super(id, version); + } + + public byte getProto() { + return proto; + } + + public void setProto(byte proto) { + this.proto = proto; + } +} diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java index d631030637..9937c573fb 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java @@ -32,6 +32,7 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.buffer.ChannelBuffer; import org.apache.dubbo.remoting.buffer.ChannelBufferInputStream; import org.apache.dubbo.remoting.buffer.ChannelBufferOutputStream; +import org.apache.dubbo.remoting.exchange.HeartBeatRequest; import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Response; import org.apache.dubbo.remoting.exchange.support.DefaultFuture; @@ -184,31 +185,34 @@ public class ExchangeCodec extends TelnetCodec { return res; } else { // decode request. - Request req = new Request(id); - req.setVersion(Version.getProtocolVersion()); - req.setTwoWay((flag & FLAG_TWOWAY) != 0); - if ((flag & FLAG_EVENT) != 0) { - req.setEvent(true); - } + Request req; try { Object data; - if (req.isEvent()) { + if ((flag & FLAG_EVENT) != 0) { byte[] eventPayload = CodecSupport.getPayload(is); if (CodecSupport.isHeartBeat(eventPayload, proto)) { // heart beat response data is always null; + req = new HeartBeatRequest(id); + ((HeartBeatRequest) req).setProto(proto); data = null; } else { + req = new Request(id); data = decodeEventData(channel, CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto), eventPayload); } + req.setEvent(true); } else { + req = new Request(id); data = decodeRequestData(channel, CodecSupport.deserialize(channel.getUrl(), is, proto)); } req.setData(data); } catch (Throwable t) { // bad request + req = new Request(id); req.setBroken(true); req.setData(t); } + req.setVersion(Version.getProtocolVersion()); + req.setTwoWay((flag & FLAG_TWOWAY) != 0); return req; } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandler.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandler.java index 38a10e34cf..f1bb03cbef 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandler.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandler.java @@ -23,6 +23,8 @@ import org.apache.dubbo.remoting.Channel; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.remoting.RemotingException; +import org.apache.dubbo.remoting.exchange.HeartBeatRequest; +import org.apache.dubbo.remoting.exchange.HeartBeatResponse; import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Response; import org.apache.dubbo.remoting.transport.AbstractChannelHandlerDelegate; @@ -65,10 +67,12 @@ public class HeartbeatHandler extends AbstractChannelHandlerDelegate { public void received(Channel channel, Object message) throws RemotingException { setReadTimestamp(channel); if (isHeartbeatRequest(message)) { - Request req = (Request) message; + HeartBeatRequest req = (HeartBeatRequest) message; if (req.isTwoWay()) { - Response res = new Response(req.getId(), req.getVersion()); + HeartBeatResponse res; + res = new HeartBeatResponse(req.getId(), req.getVersion()); res.setEvent(HEARTBEAT_EVENT); + res.setProto(req.getProto()); channel.send(res); if (logger.isDebugEnabled()) { int heartbeat = channel.getUrl().getParameter(Constants.HEARTBEAT_KEY, 0); @@ -105,7 +109,7 @@ public class HeartbeatHandler extends AbstractChannelHandlerDelegate { } private boolean isHeartbeatRequest(Object message) { - return message instanceof Request && ((Request) message).isHeartbeat(); + return message instanceof HeartBeatRequest && ((Request) message).isHeartbeat(); } private boolean isHeartbeatResponse(Object message) { diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java index 28b1453588..88a0f5622d 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java @@ -27,6 +27,8 @@ import org.apache.dubbo.common.serialize.Serialization; import org.apache.dubbo.common.threadpool.manager.ExecutorRepository; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.remoting.Channel; +import org.apache.dubbo.remoting.exchange.HeartBeatRequest; +import org.apache.dubbo.remoting.exchange.HeartBeatResponse; import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Response; import org.apache.dubbo.remoting.exchange.codec.ExchangeCodec; @@ -131,24 +133,24 @@ public class DubboCodec extends ExchangeCodec { return res; } else { // decode request. - Request req = new Request(id); - req.setVersion(Version.getProtocolVersion()); - req.setTwoWay((flag & FLAG_TWOWAY) != 0); - if ((flag & FLAG_EVENT) != 0) { - req.setEvent(true); - } + Request req; try { Object data; - if (req.isEvent()) { + if ((flag & FLAG_EVENT) != 0) { byte[] eventPayload = CodecSupport.getPayload(is); if (CodecSupport.isHeartBeat(eventPayload, proto)) { // heart beat response data is always null; + req = new HeartBeatRequest(id); + ((HeartBeatRequest) req).setProto(proto); data = null; } else { + req = new Request(id); ObjectInput in = CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto); data = decodeEventData(channel, in, eventPayload); } + req.setEvent(true); } else { + req = new HeartBeatRequest(id); DecodeableRpcInvocation inv; if (isDecodeDataInIoThread(channel)) { inv = new DecodeableRpcInvocation(frameworkModel, channel, req, is, proto); @@ -165,9 +167,12 @@ public class DubboCodec extends ExchangeCodec { log.warn(PROTOCOL_FAILED_DECODE, "", "", "Decode request failed: " + t.getMessage(), t); } // bad request + req = new HeartBeatRequest(id); req.setBroken(true); req.setData(t); } + req.setVersion(Version.getProtocolVersion()); + req.setTwoWay((flag & FLAG_TWOWAY) != 0); return req; } @@ -267,6 +272,9 @@ public class DubboCodec extends ExchangeCodec { @Override protected Serialization getSerialization(Channel channel, Response res) { + if (res instanceof HeartBeatResponse) { + return CodecSupport.getSerializationById(((HeartBeatResponse) res).getProto()); + } if (!(res.getResult() instanceof AppResponse)) { return super.getSerialization(channel, res); } From 12c8ea19cc834f2ecb0ac7020b217f89e0bfa272 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Tue, 28 Feb 2023 12:38:53 +0800 Subject: [PATCH 046/144] Bump grpc-java from 1.41.0 to 1.53.0 (#11681) --- dubbo-dependencies-bom/pom.xml | 2 +- dubbo-xds/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index d470ea02e3..7208334a6e 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -148,7 +148,7 @@ 8.5.85 0.7.5 2.1.2 - 1.41.0 + 1.53.0 0.8.1 1.2.1 diff --git a/dubbo-xds/pom.xml b/dubbo-xds/pom.xml index e96257feff..679e555b87 100644 --- a/dubbo-xds/pom.xml +++ b/dubbo-xds/pom.xml @@ -32,7 +32,7 @@ false 3.22.0 - 1.41.0 + 1.53.0 From 548369311919dd83e87c792808b34ab0ecded5c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=B8=E7=8F=82=E6=B4=81?= <76939156+lan-dian@users.noreply.github.com> Date: Tue, 28 Feb 2023 13:32:31 +0800 Subject: [PATCH 047/144] fix: remove redundancy exceptions (#11676) --- .../dubbo/rpc/cluster/ConfiguratorTest.java | 2 +- .../filter/DefaultFilterChainBuilderTest.java | 2 +- .../support/AbstractClusterInvokerTest.java | 3 +- .../dubbo/config/ConsumerConfigTest.java | 21 +++-- .../filter/ValidationFilterTest.java | 12 +-- .../support/jvalidation/JValidatorTest.java | 4 +- .../dubbo/qos/command/CommandContextTest.java | 2 +- .../qos/command/util/CommandHelperTest.java | 6 +- .../service/generic/GenericServiceTest.java | 4 +- .../org/apache/dubbo/registry/ZKTools.java | 2 +- .../registry/nacos/MockNamingService.java | 92 +++++++++---------- .../nacos/NacosConnectionsManagerTest.java | 26 +++--- .../nacos/NacosNamingServiceWrapperTest.java | 24 ++--- .../curator5/Curator5ZookeeperClientTest.java | 8 +- .../Curator5ZookeeperTransporterTest.java | 2 +- .../dubbo/rpc/filter/TimeoutFilterTest.java | 4 +- 16 files changed, 108 insertions(+), 106 deletions(-) diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/ConfiguratorTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/ConfiguratorTest.java index 84e8468b21..bdf95198df 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/ConfiguratorTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/ConfiguratorTest.java @@ -34,7 +34,7 @@ import java.util.Optional; class ConfiguratorTest { @Test - void test() throws Exception { + void test() { Optional> emptyOptional = Configurator.toConfigurators(Collections.emptyList()); Assertions.assertEquals(Optional.empty(), emptyOptional); diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java index afe93b7a2a..7f0bb6ff07 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java @@ -78,7 +78,7 @@ class DefaultFilterChainBuilderTest { urlWithoutFilter = urlWithoutFilter.setScopeModel(ApplicationModel.defaultModel()); AbstractInvoker invokerWithoutFilter = new AbstractInvoker(DemoService.class, urlWithoutFilter) { @Override - protected Result doInvoke(Invocation invocation) throws Throwable { + protected Result doInvoke(Invocation invocation) { return null; } }; diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java index acf4804583..40bef70dfb 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java @@ -35,6 +35,7 @@ import org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance; import org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance; import org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance; import org.apache.dubbo.rpc.model.ApplicationModel; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -259,7 +260,7 @@ class AbstractClusterInvokerTest { } @Test - void testSelect_multiInvokers() throws Exception { + void testSelect_multiInvokers() { testSelect_multiInvokers(RoundRobinLoadBalance.NAME); testSelect_multiInvokers(LeastActiveLoadBalance.NAME); testSelect_multiInvokers(RandomLoadBalance.NAME); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java index 84d6c926ae..336f344165 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConsumerConfigTest.java @@ -17,19 +17,20 @@ package org.apache.dubbo.config; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; - import org.apache.dubbo.common.utils.JsonUtils; import org.apache.dubbo.config.api.DemoService; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.rpc.model.ApplicationModel; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -47,7 +48,7 @@ class ConsumerConfigTest { } @Test - void testTimeout() throws Exception { + void testTimeout() { System.clearProperty("sun.rmi.transport.tcp.responseTimeout"); ConsumerConfig consumer = new ConsumerConfig(); consumer.setTimeout(10); @@ -63,35 +64,35 @@ class ConsumerConfigTest { } @Test - void testClient() throws Exception { + void testClient() { ConsumerConfig consumer = new ConsumerConfig(); consumer.setClient("client"); assertThat(consumer.getClient(), equalTo("client")); } @Test - void testThreadpool() throws Exception { + void testThreadpool() { ConsumerConfig consumer = new ConsumerConfig(); consumer.setThreadpool("fixed"); assertThat(consumer.getThreadpool(), equalTo("fixed")); } @Test - void testCorethreads() throws Exception { + void testCorethreads() { ConsumerConfig consumer = new ConsumerConfig(); consumer.setCorethreads(10); assertThat(consumer.getCorethreads(), equalTo(10)); } @Test - void testThreads() throws Exception { + void testThreads() { ConsumerConfig consumer = new ConsumerConfig(); consumer.setThreads(20); assertThat(consumer.getThreads(), equalTo(20)); } @Test - void testQueues() throws Exception { + void testQueues() { ConsumerConfig consumer = new ConsumerConfig(); consumer.setQueues(5); assertThat(consumer.getQueues(), equalTo(5)); diff --git a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java index dde1cf38c1..4260d76e50 100644 --- a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java +++ b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java @@ -43,12 +43,12 @@ class ValidationFilterTest { private ValidationFilter validationFilter; @BeforeEach - public void setUp() throws Exception { + public void setUp() { this.validationFilter = new ValidationFilter(); } @Test - void testItWithNotExistClass() throws Exception { + void testItWithNotExistClass() { URL url = URL.valueOf("test://test:11/test?validation=true"); given(validation.getValidator(url)).willThrow(new IllegalStateException("Not found class test, cause: test")); @@ -66,7 +66,7 @@ class ValidationFilterTest { } @Test - void testItWithExistClass() throws Exception { + void testItWithExistClass() { URL url = URL.valueOf("test://test:11/test?validation=true"); given(validation.getValidator(url)).willReturn(validator); @@ -83,7 +83,7 @@ class ValidationFilterTest { } @Test - void testItWithoutUrlParameters() throws Exception { + void testItWithoutUrlParameters() { URL url = URL.valueOf("test://test:11/test"); given(validation.getValidator(url)).willReturn(validator); @@ -100,7 +100,7 @@ class ValidationFilterTest { } @Test - void testItWhileMethodNameStartWithDollar() throws Exception { + void testItWhileMethodNameStartWithDollar() { URL url = URL.valueOf("test://test:11/test"); given(validation.getValidator(url)).willReturn(validator); @@ -119,7 +119,7 @@ class ValidationFilterTest { @Test - void testItWhileThrowoutRpcException() throws Exception { + void testItWhileThrowoutRpcException() { Assertions.assertThrows(RpcException.class, () -> { URL url = URL.valueOf("test://test:11/test?validation=true"); diff --git a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java index 38298eeb6d..0f04dafd6e 100644 --- a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java +++ b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java @@ -30,7 +30,7 @@ import java.util.Map; class JValidatorTest { @Test - void testItWithNonExistMethod() throws Exception { + void testItWithNonExistMethod() { Assertions.assertThrows(NoSuchMethodException.class, () -> { URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget"); JValidator jValidator = new JValidator(url); @@ -46,7 +46,7 @@ class JValidatorTest { } @Test - void testItWhenItViolatedConstraint() throws Exception { + void testItWhenItViolatedConstraint() { Assertions.assertThrows(ValidationException.class, () -> { URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget"); JValidator jValidator = new JValidator(url); diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java index 098ba908fa..cb4bc16e71 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java @@ -30,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class CommandContextTest { @Test - void test() throws Exception { + void test() { CommandContext context = new CommandContext("test", new String[]{"hello"}, true); Object request = new Object(); context.setOriginRequest(request); diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java index a98333af29..b7f519ee42 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java @@ -72,13 +72,13 @@ class CommandHelperTest { private CommandHelper commandHelper = new CommandHelper(FrameworkModel.defaultModel()); @Test - void testHasCommand() throws Exception { + void testHasCommand() { assertTrue(commandHelper.hasCommand("greeting")); assertFalse(commandHelper.hasCommand("not-exiting")); } @Test - void testGetAllCommandClass() throws Exception { + void testGetAllCommandClass() { List> classes = commandHelper.getAllCommandClass(); // update this list when introduce a new command @@ -125,7 +125,7 @@ class CommandHelperTest { } @Test - void testGetCommandClass() throws Exception { + void testGetCommandClass() { assertThat(commandHelper.getCommandClass("greeting"), equalTo(GreetingCommand.class)); assertNull(commandHelper.getCommandClass("not-exiting")); } diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/legacy/service/generic/GenericServiceTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/legacy/service/generic/GenericServiceTest.java index ba19263480..5de484b373 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/legacy/service/generic/GenericServiceTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/legacy/service/generic/GenericServiceTest.java @@ -216,7 +216,7 @@ class GenericServiceTest { } @Test - void testGenericInvokeWithBeanSerialization() throws Exception { + void testGenericInvokeWithBeanSerialization() { ServiceConfig service = new ServiceConfig(); service.setInterface(DemoService.class); DemoServiceImpl impl = new DemoServiceImpl(); @@ -256,7 +256,7 @@ class GenericServiceTest { } @Test - void testGenericImplementationWithBeanSerialization() throws Exception { + void testGenericImplementationWithBeanSerialization() { final AtomicReference reference = new AtomicReference(); ServiceConfig service = new ServiceConfig(); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/ZKTools.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/ZKTools.java index d1484c62fb..fcd3dcd76c 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/ZKTools.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/ZKTools.java @@ -260,7 +260,7 @@ public class ZKTools { treeCache.start(); treeCache.getListenable().addListener(new TreeCacheListener() { @Override - public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception { + public void childEvent(CuratorFramework client, TreeCacheEvent event) { TreeCacheEvent.Type type = event.getType(); ChildData data = event.getData(); diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/MockNamingService.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/MockNamingService.java index e6e7896908..b7c62f9c11 100644 --- a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/MockNamingService.java +++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/MockNamingService.java @@ -16,8 +16,6 @@ */ package org.apache.dubbo.registry.nacos; -import java.util.List; - import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.listener.EventListener; @@ -26,29 +24,31 @@ import com.alibaba.nacos.api.naming.pojo.ListView; import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import com.alibaba.nacos.api.selector.AbstractSelector; +import java.util.List; + public class MockNamingService implements NamingService { @Override - public void registerInstance(String serviceName, String ip, int port) throws NacosException { + public void registerInstance(String serviceName, String ip, int port) { } @Override - public void registerInstance(String serviceName, String groupName, String ip, int port) throws NacosException { + public void registerInstance(String serviceName, String groupName, String ip, int port) { } @Override - public void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException { + public void registerInstance(String serviceName, String ip, int port, String clusterName) { } @Override - public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException { + public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) { } @Override - public void registerInstance(String serviceName, Instance instance) throws NacosException { + public void registerInstance(String serviceName, Instance instance) { } @@ -58,42 +58,42 @@ public class MockNamingService implements NamingService { } @Override - public void batchRegisterInstance(String serviceName, String groupName, List instances) throws NacosException { + public void batchRegisterInstance(String serviceName, String groupName, List instances) { } @Override - public void deregisterInstance(String serviceName, String ip, int port) throws NacosException { + public void deregisterInstance(String serviceName, String ip, int port) { } @Override - public void deregisterInstance(String serviceName, String groupName, String ip, int port) throws NacosException { + public void deregisterInstance(String serviceName, String groupName, String ip, int port) { } @Override - public void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException { + public void deregisterInstance(String serviceName, String ip, int port, String clusterName) { } @Override - public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException { + public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) { } @Override - public void deregisterInstance(String serviceName, Instance instance) throws NacosException { + public void deregisterInstance(String serviceName, Instance instance) { } @Override - public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException { + public void deregisterInstance(String serviceName, String groupName, Instance instance) { } @Override - public List getAllInstances(String serviceName) throws NacosException { + public List getAllInstances(String serviceName) { return null; } @@ -108,107 +108,107 @@ public class MockNamingService implements NamingService { } @Override - public List getAllInstances(String serviceName, String groupName, boolean subscribe) throws NacosException { + public List getAllInstances(String serviceName, String groupName, boolean subscribe) { return null; } @Override - public List getAllInstances(String serviceName, List clusters) throws NacosException { + public List getAllInstances(String serviceName, List clusters) { return null; } @Override - public List getAllInstances(String serviceName, String groupName, List clusters) throws NacosException { + public List getAllInstances(String serviceName, String groupName, List clusters) { return null; } @Override - public List getAllInstances(String serviceName, List clusters, boolean subscribe) throws NacosException { + public List getAllInstances(String serviceName, List clusters, boolean subscribe) { return null; } @Override - public List getAllInstances(String serviceName, String groupName, List clusters, boolean subscribe) throws NacosException { + public List getAllInstances(String serviceName, String groupName, List clusters, boolean subscribe) { return null; } @Override - public List selectInstances(String serviceName, boolean healthy) throws NacosException { + public List selectInstances(String serviceName, boolean healthy) { return null; } @Override - public List selectInstances(String serviceName, String groupName, boolean healthy) throws NacosException { + public List selectInstances(String serviceName, String groupName, boolean healthy) { return null; } @Override - public List selectInstances(String serviceName, boolean healthy, boolean subscribe) throws NacosException { + public List selectInstances(String serviceName, boolean healthy, boolean subscribe) { return null; } @Override - public List selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe) throws NacosException { + public List selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe) { return null; } @Override - public List selectInstances(String serviceName, List clusters, boolean healthy) throws NacosException { + public List selectInstances(String serviceName, List clusters, boolean healthy) { return null; } @Override - public List selectInstances(String serviceName, String groupName, List clusters, boolean healthy) throws NacosException { + public List selectInstances(String serviceName, String groupName, List clusters, boolean healthy) { return null; } @Override - public List selectInstances(String serviceName, List clusters, boolean healthy, boolean subscribe) throws NacosException { + public List selectInstances(String serviceName, List clusters, boolean healthy, boolean subscribe) { return null; } @Override - public List selectInstances(String serviceName, String groupName, List clusters, boolean healthy, boolean subscribe) throws NacosException { + public List selectInstances(String serviceName, String groupName, List clusters, boolean healthy, boolean subscribe) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName, String groupName) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName, List clusters) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName, List clusters) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName, String groupName, List clusters) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName, String groupName, List clusters) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName, List clusters, boolean subscribe) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName, List clusters, boolean subscribe) { return null; } @Override - public Instance selectOneHealthyInstance(String serviceName, String groupName, List clusters, boolean subscribe) throws NacosException { + public Instance selectOneHealthyInstance(String serviceName, String groupName, List clusters, boolean subscribe) { return null; } @@ -233,47 +233,47 @@ public class MockNamingService implements NamingService { } @Override - public void unsubscribe(String serviceName, EventListener listener) throws NacosException { + public void unsubscribe(String serviceName, EventListener listener) { } @Override - public void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException { + public void unsubscribe(String serviceName, String groupName, EventListener listener) { } @Override - public void unsubscribe(String serviceName, List clusters, EventListener listener) throws NacosException { + public void unsubscribe(String serviceName, List clusters, EventListener listener) { } @Override - public void unsubscribe(String serviceName, String groupName, List clusters, EventListener listener) throws NacosException { + public void unsubscribe(String serviceName, String groupName, List clusters, EventListener listener) { } @Override - public ListView getServicesOfServer(int pageNo, int pageSize) throws NacosException { + public ListView getServicesOfServer(int pageNo, int pageSize) { return null; } @Override - public ListView getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException { + public ListView getServicesOfServer(int pageNo, int pageSize, String groupName) { return null; } @Override - public ListView getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException { + public ListView getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) { return null; } @Override - public ListView getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException { + public ListView getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) { return null; } @Override - public List getSubscribeServices() throws NacosException { + public List getSubscribeServices() { return null; } @@ -283,7 +283,7 @@ public class MockNamingService implements NamingService { } @Override - public void shutDown() throws NacosException { + public void shutDown() { } } diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosConnectionsManagerTest.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosConnectionsManagerTest.java index 5396bd10e2..bc2dea58d0 100644 --- a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosConnectionsManagerTest.java +++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosConnectionsManagerTest.java @@ -16,6 +16,17 @@ */ package org.apache.dubbo.registry.nacos; +import org.apache.dubbo.common.URL; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; @@ -23,17 +34,6 @@ import java.util.List; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.dubbo.common.URL; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; -import org.mockito.Mockito; - -import com.alibaba.nacos.api.NacosFactory; -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.api.naming.NamingService; -import com.alibaba.nacos.api.naming.pojo.Instance; - import static com.alibaba.nacos.client.constant.Constants.HealthCheck.DOWN; import static com.alibaba.nacos.client.constant.Constants.HealthCheck.UP; import static org.mockito.ArgumentMatchers.any; @@ -93,7 +93,7 @@ public class NacosConnectionsManagerTest { } @Test - void testRetryCreate() throws NacosException { + void testRetryCreate() { try (MockedStatic nacosFactoryMockedStatic = Mockito.mockStatic(NacosFactory.class)) { AtomicInteger atomicInteger = new AtomicInteger(0); NamingService mock = new MockNamingService() { @@ -115,7 +115,7 @@ public class NacosConnectionsManagerTest { } } @Test - void testNoCheck() throws NacosException { + void testNoCheck() { try (MockedStatic nacosFactoryMockedStatic = Mockito.mockStatic(NacosFactory.class)) { NamingService mock = new MockNamingService() { @Override diff --git a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java index 7fcf7f47f1..6e3c730d83 100644 --- a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java +++ b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java @@ -16,6 +16,16 @@ */ package org.apache.dubbo.registry.nacos; +import org.apache.dubbo.common.URL; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.listener.EventListener; +import com.alibaba.nacos.api.naming.pojo.Instance; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -24,16 +34,6 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.dubbo.common.URL; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.api.naming.NamingService; -import com.alibaba.nacos.api.naming.listener.EventListener; -import com.alibaba.nacos.api.naming.pojo.Instance; - class NacosNamingServiceWrapperTest { @Test void testSubscribe() throws NacosException { @@ -501,12 +501,12 @@ class NacosNamingServiceWrapperTest { void testSuccess() { NamingService namingService = new MockNamingService() { @Override - public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException { + public void registerInstance(String serviceName, String groupName, Instance instance) { } @Override - public List getAllInstances(String serviceName, String groupName) throws NacosException { + public List getAllInstances(String serviceName, String groupName) { return null; } }; diff --git a/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperClientTest.java b/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperClientTest.java index be71b74f52..dc1de17c45 100644 --- a/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperClientTest.java +++ b/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperClientTest.java @@ -88,7 +88,7 @@ class Curator5ZookeeperClientTest { curatorClient.addTargetChildListener(path, new Curator5ZookeeperClient.CuratorWatcherImpl() { @Override - public void process(WatchedEvent watchedEvent) throws Exception { + public void process(WatchedEvent watchedEvent) { countDownLatch.countDown(); } }); @@ -201,7 +201,7 @@ class Curator5ZookeeperClientTest { final AtomicInteger atomicInteger = new AtomicInteger(0); curatorClient.addTargetDataListener(path + "/d.json", new Curator5ZookeeperClient.NodeCacheListenerImpl() { @Override - public void nodeChanged() throws Exception { + public void nodeChanged() { atomicInteger.incrementAndGet(); } }); @@ -280,7 +280,7 @@ class Curator5ZookeeperClientTest { } @Test - void testPersistentCas2() throws Exception { + void testPersistentCas2() { // test update failed when others create success String path = "/dubbo/mapping/org.apache.dubbo.demo.DemoService"; Curator5ZookeeperClient curatorClient = new Curator5ZookeeperClient(URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService")); @@ -405,7 +405,7 @@ class Curator5ZookeeperClientTest { } @Test - void testEphemeralCas2() throws Exception { + void testEphemeralCas2() { // test update failed when others create success String path = "/dubbo/mapping/org.apache.dubbo.demo.DemoService"; Curator5ZookeeperClient curatorClient = new Curator5ZookeeperClient(URL.valueOf(zookeeperConnectionAddress1 + "/org.apache.dubbo.registry.RegistryService")); diff --git a/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperTransporterTest.java b/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperTransporterTest.java index a6b3f062df..1418d2fc3d 100644 --- a/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperTransporterTest.java +++ b/dubbo-remoting/dubbo-remoting-zookeeper-curator5/src/test/java/org/apache/dubbo/remoting/zookeeper/curator5/Curator5ZookeeperTransporterTest.java @@ -38,7 +38,7 @@ class Curator5ZookeeperTransporterTest { } @BeforeEach - public void setUp() throws Exception { + public void setUp() { zookeeperClient = new Curator5ZookeeperTransporter().connect(URL.valueOf(zookeeperConnectionAddress1 + "/service")); curatorZookeeperTransporter = new Curator5ZookeeperTransporter(); } diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java index dbf0206db9..3613f54007 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java @@ -36,7 +36,7 @@ class TimeoutFilterTest { private TimeoutFilter timeoutFilter = new TimeoutFilter(); @Test - void testInvokeWithoutTimeout() throws Exception { + void testInvokeWithoutTimeout() { int timeout = 3000; Invoker invoker = Mockito.mock(Invoker.class); @@ -51,7 +51,7 @@ class TimeoutFilterTest { } @Test - void testInvokeWithTimeout() throws Exception { + void testInvokeWithTimeout() { int timeout = 100; URL url = URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&timeout=" + timeout); From 15f5b0e950402de9e459290e1c91ad2b1b6f9ec4 Mon Sep 17 00:00:00 2001 From: jojocodeX <571943037@qq.com> Date: Tue, 28 Feb 2023 15:42:20 +0800 Subject: [PATCH 048/144] add error type metrics (#11596) --- .../KubernetesServiceDiscoveryTest.java | 25 ++- .../dubbo/metrics/event/MetricsEvent.java | 5 +- .../dubbo/metrics/model/MethodMetric.java | 15 +- .../dubbo/metrics/model/MetricsKey.java | 23 +- .../collector/AggregateMetricsCollector.java | 131 +++++------- .../collector/DefaultMetricsCollector.java | 6 +- .../sample/MethodMetricsSampler.java | 9 +- .../sample/MetricsCountSampleConfigurer.java | 1 - .../collector/sample/MetricsCountSampler.java | 4 + .../collector/sample/MetricsSampler.java | 1 - .../sample/SimpleMetricsCountSampler.java | 96 +++++++-- .../sample/ThreadPoolMetricsSampler.java | 76 ++++--- .../filter/MethodMetricsInterceptor.java | 77 ++++--- .../metrics/filter/MetricsClusterFilter.java | 68 ++++++ .../dubbo/metrics/filter/MetricsFilter.java | 10 +- ...che.dubbo.rpc.cluster.filter.ClusterFilter | 1 + .../AggregateMetricsCollectorTest.java | 16 +- .../metrics/filter/MetricsFilterTest.java | 81 ++++++- .../metrics/sampler/CountSamplerTest.java | 197 ++++++++++++++++++ 19 files changed, 627 insertions(+), 215 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java create mode 100644 dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java diff --git a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java b/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java index 4f8371966a..b786953245 100644 --- a/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java +++ b/dubbo-kubernetes/src/test/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscoveryTest.java @@ -16,10 +16,15 @@ */ package org.apache.dubbo.registry.kubernetes; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - +import io.fabric8.kubernetes.api.model.Endpoints; +import io.fabric8.kubernetes.api.model.EndpointsBuilder; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.PodBuilder; +import io.fabric8.kubernetes.api.model.Service; +import io.fabric8.kubernetes.api.model.ServiceBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.NamespacedKubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; import org.apache.dubbo.common.URL; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.registry.client.DefaultServiceInstance; @@ -38,15 +43,9 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import io.fabric8.kubernetes.api.model.Endpoints; -import io.fabric8.kubernetes.api.model.EndpointsBuilder; -import io.fabric8.kubernetes.api.model.Pod; -import io.fabric8.kubernetes.api.model.PodBuilder; -import io.fabric8.kubernetes.api.model.Service; -import io.fabric8.kubernetes.api.model.ServiceBuilder; -import io.fabric8.kubernetes.client.Config; -import io.fabric8.kubernetes.client.NamespacedKubernetesClient; -import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import static org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst.NAMESPACE; import static org.awaitility.Awaitility.await; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java index 3b21f6cc7f..5c49988f2e 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java @@ -54,7 +54,10 @@ public abstract class MetricsEvent { PROCESSING, UNKNOWN_FAILED, TOTAL_FAILED, - APPLICATION_INFO + APPLICATION_INFO, + NETWORK_EXCEPTION, + SERVICE_UNAVAILABLE, + CODEC_EXCEPTION; } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java index cbccdcf188..35b7a6bf71 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MethodMetric.java @@ -26,15 +26,15 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR; import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_VERSION_KEY; import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; @@ -51,9 +51,7 @@ public class MethodMetric implements Metric { private String group; private String version; - public MethodMetric() { - - } + public MethodMetric() {} public MethodMetric(String applicationName, Invocation invocation) { this.applicationName = applicationName; @@ -97,7 +95,6 @@ public class MethodMetric implements Metric { tags.put(TAG_IP, getLocalHost()); tags.put(TAG_HOSTNAME, getLocalHostName()); tags.put(TAG_APPLICATION_NAME, applicationName); - tags.put(TAG_INTERFACE_KEY, interfaceName); tags.put(TAG_METHOD_KEY, methodName); tags.put(TAG_GROUP_KEY, group); diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java index 0e3e160a1b..8d55c707b1 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java @@ -22,13 +22,17 @@ public enum MetricsKey { // provider metrics key METRIC_REQUESTS("dubbo.%s.requests.total", "Total Requests"), - METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Succeed Requests"), - METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total", "Failed Business Requests"), + METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Total Succeed Requests"), + METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total","Total Failed Business Requests"), + METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing", "Processing Requests"), METRIC_REQUESTS_TIMEOUT("dubbo.%s.requests.timeout.total", "Total Timeout Failed Requests"), METRIC_REQUESTS_LIMIT("dubbo.%s.requests.limit.total", "Total Limit Failed Requests"), - METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Unknown Failed Requests"), + METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Total Unknown Failed Requests"), METRIC_REQUESTS_TOTAL_FAILED("dubbo.%s.requests.failed.total", "Total Failed Requests"), + METRIC_REQUESTS_NETWORK_FAILED("dubbo.%s.requests.failed.network.total", "Total network Failed Requests"), + METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED("dubbo.%s.requests.failed.service.unavailable.total", "Total Service Unavailable Failed Requests"), + METRIC_REQUESTS_CODEC_FAILED("dubbo.%s.requests.failed.codec.total", "Total Codec Failed Requests"), METRIC_REQUESTS_TOTAL_AGG("dubbo.%s.requests.total.aggregate", "Aggregated Total Requests"), METRIC_REQUESTS_SUCCEED_AGG("dubbo.%s.requests.succeed.aggregate", "Aggregated Succeed Requests"), @@ -37,6 +41,9 @@ public enum MetricsKey { METRIC_REQUESTS_TIMEOUT_AGG("dubbo.%s.requests.timeout.failed.aggregate", "Aggregated timeout Failed Requests"), METRIC_REQUESTS_LIMIT_AGG("dubbo.%s.requests.limit.aggregate", "Aggregated limit Requests"), METRIC_REQUESTS_TOTAL_FAILED_AGG("dubbo.%s.requests.failed.total.aggregate", "Aggregated failed total Requests"), + METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG("dubbo.%s.requests.failed.network.total.aggregate", "Aggregated failed network total Requests"), + METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG("dubbo.%s.requests.failed.codec.total.aggregate", "Aggregated failed codec total Requests"), + METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG("dubbo.%s.requests.failed.service.unavailable.total.aggregate", "Aggregated failed codec total Requests"), METRIC_QPS("dubbo.%s.qps.total", "Query Per Seconds"), METRIC_RT_LAST("dubbo.%s.rt.milliseconds.last", "Last Response Time"), @@ -88,8 +95,8 @@ public enum MetricsKey { // consumer metrics key ; - private final String name; - private final String description; + private String name; + private String description; public final String getName() { return this.name; @@ -99,6 +106,12 @@ public enum MetricsKey { return String.format(name, type); } + + public final MetricsKey formatName(String type) { + this.name = String.format(name, type); + return this; + } + public final String getDescription() { return this.description; } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java index a929194922..1651c87dc3 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java @@ -17,11 +17,6 @@ package org.apache.dubbo.metrics.collector; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.config.MetricsConfig; import org.apache.dubbo.config.context.ConfigManager; @@ -37,7 +32,11 @@ import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.model.ApplicationModel; - +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import static org.apache.dubbo.metrics.model.MetricsCategory.QPS; import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; @@ -49,24 +48,17 @@ import static org.apache.dubbo.metrics.model.MetricsCategory.RT; public class AggregateMetricsCollector implements MetricsCollector, MetricsListener { private int bucketNum; private int timeWindowSeconds; - - private final ConcurrentMap totalRequests = new ConcurrentHashMap<>(); - private final ConcurrentMap succeedRequests = new ConcurrentHashMap<>(); - private final ConcurrentMap unknownFailedRequests = new ConcurrentHashMap<>(); - private final ConcurrentMap businessFailedRequests = new ConcurrentHashMap<>(); - private final ConcurrentMap timeoutRequests = new ConcurrentHashMap<>(); - private final ConcurrentMap limitRequests = new ConcurrentHashMap<>(); - private final ConcurrentMap totalFailedRequests = new ConcurrentHashMap<>(); - private final ConcurrentMap qps = new ConcurrentHashMap<>(); + private final Map> methodTypeCounter = new ConcurrentHashMap<>(); private final ConcurrentMap rt = new ConcurrentHashMap<>(); - + private final ConcurrentHashMap qps = new ConcurrentHashMap<>(); private final ApplicationModel applicationModel; - private static final Integer DEFAULT_COMPRESSION = 100; private static final Integer DEFAULT_BUCKET_NUM = 10; private static final Integer DEFAULT_TIME_WINDOW_SECONDS = 120; public AggregateMetricsCollector(ApplicationModel applicationModel) { + this.registryerEventTypeHandler(); + this.applicationModel = applicationModel; ConfigManager configManager = applicationModel.getApplicationConfigManager(); MetricsConfig config = configManager.getMetrics().orElse(null); @@ -80,10 +72,6 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe } } - private void registerListener() { - applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class).addListener(this); - } - @Override public void onEvent(MetricsEvent event) { if (event instanceof RTEvent) { @@ -100,45 +88,24 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe quantile.add(responseTime); } + private void onRequestEvent(RequestEvent event) { MethodMetric metric = (MethodMetric) event.getSource(); - RequestEvent.Type type = event.getType(); - TimeWindowCounter counter = null; - switch (type) { - case TOTAL: - counter = ConcurrentHashMapUtils.computeIfAbsent(totalRequests, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - TimeWindowCounter qpsCounter = ConcurrentHashMapUtils.computeIfAbsent(qps, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - qpsCounter.increment(); - break; - case SUCCEED: - counter = ConcurrentHashMapUtils.computeIfAbsent(succeedRequests, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - break; - case UNKNOWN_FAILED: - counter = ConcurrentHashMapUtils.computeIfAbsent(unknownFailedRequests, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - break; - case BUSINESS_FAILED: - counter = ConcurrentHashMapUtils.computeIfAbsent(businessFailedRequests, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - break; - case REQUEST_TIMEOUT: - counter = ConcurrentHashMapUtils.computeIfAbsent(timeoutRequests, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - break; + MetricsEvent.Type type = event.getType(); - case REQUEST_LIMIT: - counter = ConcurrentHashMapUtils.computeIfAbsent(limitRequests, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - break; + ConcurrentMap counter = methodTypeCounter.get(type); - case TOTAL_FAILED: - counter = ConcurrentHashMapUtils.computeIfAbsent(totalFailedRequests, metric, k -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - break; - - default: - break; + if (counter == null) { + return; } + TimeWindowCounter windowCounter = ConcurrentHashMapUtils.computeIfAbsent(counter, metric, methodMetric -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - if (counter != null) { - counter.increment(); + if (type == MetricsEvent.Type.TOTAL) { + TimeWindowCounter qpsCounter = ConcurrentHashMapUtils.computeIfAbsent(qps, metric, methodMetric -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); + qpsCounter.increment(); } + windowCounter.increment(); } @Override @@ -152,39 +119,51 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe } private void collectRequests(List list) { - totalRequests.forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_TOTAL_AGG, k, v))); - succeedRequests.forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_SUCCEED_AGG, k, v))); - unknownFailedRequests.forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_FAILED_AGG, k, v))); - businessFailedRequests.forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG, k, v))); - timeoutRequests.forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_TIMEOUT_AGG, k, v))); - limitRequests.forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_LIMIT_AGG, k, v))); - totalFailedRequests.forEach((k, v) -> - list.add(getGaugeMetricSample(MetricsKey.METRIC_REQUESTS_TOTAL_FAILED_AGG, k, v))); - + collectMethod(list, MetricsEvent.Type.TOTAL, MetricsKey.METRIC_REQUESTS_TOTAL_AGG); + collectMethod(list, MetricsEvent.Type.SUCCEED, MetricsKey.METRIC_REQUESTS_SUCCEED_AGG); + collectMethod(list, MetricsEvent.Type.UNKNOWN_FAILED, MetricsKey.METRIC_REQUESTS_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.BUSINESS_FAILED, MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.REQUEST_TIMEOUT, MetricsKey.METRIC_REQUESTS_TIMEOUT_AGG); + collectMethod(list, MetricsEvent.Type.REQUEST_LIMIT, MetricsKey.METRIC_REQUESTS_LIMIT_AGG); + collectMethod(list, MetricsEvent.Type.TOTAL_FAILED, MetricsKey.METRIC_REQUESTS_TOTAL_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.NETWORK_EXCEPTION, MetricsKey.METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.CODEC_EXCEPTION, MetricsKey.METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.SERVICE_UNAVAILABLE, MetricsKey.METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG); } - private GaugeMetricSample getGaugeMetricSample(MetricsKey metricRequestsTotalAgg, MethodMetric k, TimeWindowCounter v) { - return new GaugeMetricSample(metricRequestsTotalAgg.getNameByType(k.getSide()), - metricRequestsTotalAgg.getDescription(), k.getTags(), REQUESTS, v::get); + private void collectMethod(List list, MetricsEvent.Type eventType, MetricsKey metricsKey) { + ConcurrentHashMap windowCounter = methodTypeCounter.get(eventType); + if (windowCounter != null) { + windowCounter.forEach((k, v) -> list.add(new GaugeMetricSample(metricsKey.formatName(k.getSide()), k.getTags(), REQUESTS, v::get))); + } } private void collectQPS(List list) { - qps.forEach((k, v) -> list.add(new GaugeMetricSample(MetricsKey.METRIC_QPS.getNameByType(k.getSide()), - MetricsKey.METRIC_QPS.getDescription(), k.getTags(), QPS, () -> v.get() / v.bucketLivedSeconds()))); + qps.forEach((k, v) -> list.add(new GaugeMetricSample(MetricsKey.METRIC_QPS.formatName(k.getSide()), k.getTags(), QPS, () -> v.get() / v.bucketLivedSeconds()))); } private void collectRT(List list) { rt.forEach((k, v) -> { - list.add(new GaugeMetricSample(MetricsKey.METRIC_RT_P99.getNameByType(k.getSide()), - MetricsKey.METRIC_RT_P99.getDescription(), k.getTags(), RT, () -> v.quantile(0.99))); - list.add(new GaugeMetricSample(MetricsKey.METRIC_RT_P95.getNameByType(k.getSide()), - MetricsKey.METRIC_RT_P95.getDescription(), k.getTags(), RT, () -> v.quantile(0.95))); + list.add(new GaugeMetricSample(MetricsKey.METRIC_RT_P99.formatName(k.getSide()), k.getTags(), RT, () -> v.quantile(0.99))); + list.add(new GaugeMetricSample(MetricsKey.METRIC_RT_P95.formatName(k.getSide()), k.getTags(), RT, () -> v.quantile(0.95))); }); } + + private void registryerEventTypeHandler() { + methodTypeCounter.put(MetricsEvent.Type.TOTAL, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.SUCCEED, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.UNKNOWN_FAILED, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.BUSINESS_FAILED, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.REQUEST_TIMEOUT, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.REQUEST_LIMIT, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.TOTAL_FAILED, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.SERVICE_UNAVAILABLE, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.NETWORK_EXCEPTION, new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.CODEC_EXCEPTION, new ConcurrentHashMap<>()); + } + + private void registerListener() { + applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class).addListener(this); + } + } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java index b91ae3a1de..87bd5ea53e 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java @@ -29,10 +29,8 @@ import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.model.ApplicationModel; - import java.util.ArrayList; import java.util.List; - import static org.apache.dubbo.metrics.model.MetricsCategory.APPLICATION; import static org.apache.dubbo.metrics.model.MetricsKey.APPLICATION_METRIC_INFO; @@ -84,6 +82,10 @@ public class DefaultMetricsCollector implements MetricsCollector { return this.methodSampler; } + public ThreadPoolMetricsSampler getThreadPoolSampler() { + return this.threadPoolSampler; + } + public void collectApplication(ApplicationModel applicationModel) { this.setApplicationName(applicationModel.getApplicationName()); this.applicationModel = applicationModel; diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java index 75bc637ab0..3144a3c241 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java @@ -28,11 +28,9 @@ import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.Invocation; - import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; - import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; @@ -63,7 +61,8 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler metricSamples = new ArrayList<>(); collect(metricSamples); - metricSamples.addAll(collectRT((key, metric, count) -> getGaugeMetricSample(key, metric, RT, () -> count))); + metricSamples.addAll( + this.collectRT((key, metric, count) -> getGaugeMetricSample(key, metric, RT, () -> count))); return metricSamples; } @@ -77,8 +76,12 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler get) { return new GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()), metricsKey.getDescription(), diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java index 15da69cd56..439b04eabf 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampleConfigurer.java @@ -18,7 +18,6 @@ package org.apache.dubbo.metrics.collector.sample; import org.apache.dubbo.metrics.model.Metric; - import java.util.function.Consumer; import java.util.function.Function; diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java index 06512199aa..3fbd3da676 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java @@ -38,10 +38,14 @@ public interface MetricsCountSampler extends MetricsSamp void addRT(S source, Long rt); + void addRT(S source, K metricName, Long rt); + Optional> getCount(K metricName); List collectRT(MetricSampleFactory factory); + List collectRT(MetricSampleFactory factory,K metricName); + interface MetricSampleFactory { R newInstance(MetricsKey key, M metric, Long count); } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java index 9d59726288..55111af991 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsSampler.java @@ -18,7 +18,6 @@ package org.apache.dubbo.metrics.collector.sample; import org.apache.dubbo.metrics.model.sample.MetricSample; - import java.util.List; public interface MetricsSampler { diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java index 898e0d9dd8..5e1ddded2a 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java @@ -44,14 +44,15 @@ public abstract class SimpleMetricsCountSampler implements MetricsCountSampler { private final ConcurrentMap EMPTY_COUNT = new ConcurrentHashMap<>(); - + private Map> metricCounter = new ConcurrentHashMap<>(); + // lastRT, totalRT, rtCount, avgRT share a container, can utilize the system cache line + private final ConcurrentMap rtSample = new ConcurrentHashMap<>(); private final ConcurrentMap minRT = new ConcurrentHashMap<>(); private final ConcurrentMap maxRT = new ConcurrentHashMap<>(); - // lastRT, totalRT, rtCount, avgRT share a container, can utilize the system cache line - private final ConcurrentMap rtArray = new ConcurrentHashMap<>(); - - private final Map> metricCounter = new ConcurrentHashMap<>(); + private final ConcurrentMap> rtGroupSample = new ConcurrentHashMap<>(); + private final ConcurrentMap> groupMinRT = new ConcurrentHashMap<>(); + private final ConcurrentMap> groupMaxRT = new ConcurrentHashMap<>(); @Override public void inc(S source, K metricName) { @@ -84,7 +85,6 @@ public abstract class SimpleMetricsCountSampler return true; }); } - @Override public void addRT(S source, Long rt) { MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); @@ -94,16 +94,16 @@ public abstract class SimpleMetricsCountSampler M metric = sampleConfigure.getMetric(); - AtomicLongArray rtArray = ConcurrentHashMapUtils.computeIfAbsent(this.rtArray, metric, k -> new AtomicLongArray(4)); + AtomicLongArray rtCalculator = ConcurrentHashMapUtils.computeIfAbsent(this.rtSample, metric, k -> new AtomicLongArray(4)); // set lastRT - rtArray.set(0, rt); + rtCalculator.set(0, rt); // add to totalRT - rtArray.addAndGet(1, rt); + rtCalculator.addAndGet(1, rt); // add to rtCount - rtArray.incrementAndGet(2); + rtCalculator.incrementAndGet(2); // calc avgRT. In order to reduce the amount of calculation, calculated when collect //rtArray.set(3, Math.floorDiv(rtArray.get(1), rtArray.get(2))); @@ -119,6 +119,49 @@ public abstract class SimpleMetricsCountSampler sampleConfigure.getFireEventHandler().accept(sampleConfigure); } + @Override + public void addRT(S source, K metricName, Long rt) { + MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); + sampleConfigure.setSource(source); + sampleConfigure.setMetricsName(metricName); + + this.rtConfigure(sampleConfigure); + + M metric = sampleConfigure.getMetric(); + + ConcurrentMap nameToCalculator = rtGroupSample.get(metricName); + + if (nameToCalculator == null) { + ConcurrentHashMap calculator = new ConcurrentHashMap<>(); + calculator.put(metric, new AtomicLongArray(4)); + + rtGroupSample.put(metricName,calculator); + + nameToCalculator = rtGroupSample.get(metricName); + } + AtomicLongArray calculator = nameToCalculator.get(metric); + + // set lastRT + calculator.set(0, rt); + + // add to totalRT + calculator.addAndGet(1, rt); + + // add to rtCount + calculator.incrementAndGet(2); + + ConcurrentMap minRT = ConcurrentHashMapUtils.computeIfAbsent(groupMinRT, metricName, k -> new ConcurrentHashMap<>()); + LongAccumulator min = ConcurrentHashMapUtils.computeIfAbsent(minRT, metric, k -> new LongAccumulator(Long::min, Long.MAX_VALUE)); + min.accumulate(rt); + + ConcurrentMap maxRT = ConcurrentHashMapUtils.computeIfAbsent(groupMaxRT, metricName, k -> new ConcurrentHashMap<>()); + LongAccumulator max = ConcurrentHashMapUtils.computeIfAbsent(maxRT, metric, k -> new LongAccumulator(Long::max, Long.MIN_VALUE)); + max.accumulate(rt); + sampleConfigure.setRt(rt); + + sampleConfigure.getFireEventHandler().accept(sampleConfigure); + } + @Override public Optional> getCount(K metricName) { return Optional.ofNullable(metricCounter.get(metricName) == null ? @@ -128,29 +171,40 @@ public abstract class SimpleMetricsCountSampler @Override public List collectRT(MetricSampleFactory factory) { - final List rtMetricSamples = new ArrayList<>(); - rtArray.forEach((k, v) -> { + return collect(factory, rtSample, this.minRT, this.maxRT); + } + + public List collectRT(MetricSampleFactory factory,K metricName){ + return collect(factory, rtGroupSample.get(metricName), groupMinRT.get(metricName), + groupMaxRT.get(metricName)); + } + + private List collect(MetricSampleFactory factory, + ConcurrentMap rtSample, + ConcurrentMap min, + ConcurrentMap max){ + final List result = new ArrayList<>(); + rtSample.forEach((k, v) -> { // lastRT - rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_LAST, k, v.get(0))); + result.add(factory.newInstance(MetricsKey.METRIC_RT_LAST, k, v.get(0))); // totalRT long totalRT = v.get(1); long rtCount = v.get(2); - rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_SUM, k, totalRT)); + result.add(factory.newInstance(MetricsKey.METRIC_RT_SUM, k, totalRT)); // avgRT - rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_AVG, k, Math.floorDiv(totalRT, rtCount))); + result.add(factory.newInstance(MetricsKey.METRIC_RT_AVG, k, Math.floorDiv(totalRT, rtCount))); }); - this.minRT.forEach((k, v) -> - rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MIN, k, v.get()))); + min.forEach((k, v) -> + result.add(factory.newInstance(MetricsKey.METRIC_RT_MIN, k, v.get()))); - this.maxRT.forEach((k, v) -> - rtMetricSamples.add(factory.newInstance(MetricsKey.METRIC_RT_MAX, k, v.get()))); + max.forEach((k, v) -> + result.add(factory.newInstance(MetricsKey.METRIC_RT_MAX, k, v.get()))); - return rtMetricSamples; + return result; } protected void rtConfigure(MetricsCountSampleConfigurer configure) { - } protected abstract void countConfigure(MetricsCountSampleConfigurer sampleConfigure); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java index 17ad4bb5e3..6198f76261 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java @@ -15,70 +15,84 @@ * limitations under the License. */ package org.apache.dubbo.metrics.collector.sample; - +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.ThreadPoolMetric; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; - import java.util.ArrayList; -import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Optional; -import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; - +import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION; import static org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL; public class ThreadPoolMetricsSampler implements MetricsSampler { - private final DefaultMetricsCollector collector; + private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ThreadPoolMetricsSampler.class); + + private DefaultMetricsCollector collector; private FrameworkExecutorRepository frameworkExecutorRepository; - private final Set threadPoolMetricSet = new HashSet<>(); + private Map sampleThreadPoolExecutor = new ConcurrentHashMap<>(); public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) { this.collector = collector; + this.registryDefaultSampleThreadPoolExecutor(); + } + + public void addExecutors(String name, ExecutorService executorService) { + Optional.ofNullable(executorService).filter(Objects::nonNull).filter(e -> e instanceof ThreadPoolExecutor) + .map(e -> (ThreadPoolExecutor) e) + .ifPresent(threadPoolExecutor -> sampleThreadPoolExecutor.put(name, threadPoolExecutor)); } @Override public List sample() { - collect(); List metricSamples = new ArrayList<>(); - threadPoolMetricSet.forEach(e -> metricSamples.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_CORE_SIZE, e.getTags(), THREAD_POOL, e::getCorePoolSize))); - threadPoolMetricSet.forEach(e -> metricSamples.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_LARGEST_SIZE, e.getTags(), THREAD_POOL, e::getLargestPoolSize))); - threadPoolMetricSet.forEach(e -> metricSamples.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_MAX_SIZE, e.getTags(), THREAD_POOL, e::getMaximumPoolSize))); - threadPoolMetricSet.forEach(e -> metricSamples.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_ACTIVE_SIZE, e.getTags(), THREAD_POOL, e::getActiveCount))); - threadPoolMetricSet.forEach(e -> metricSamples.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_THREAD_COUNT, e.getTags(), THREAD_POOL, e::getPoolSize))); - threadPoolMetricSet.forEach(e -> metricSamples.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_QUEUE_SIZE, e.getTags(), THREAD_POOL, e::getQueueSize))); + + sampleThreadPoolExecutor.forEach((name, executor)->{ + metricSamples.addAll(createMetricsSample(name,executor)); + }); return metricSamples; } - private void collect() { + private List createMetricsSample(String name,ThreadPoolExecutor executor) { + List list = new ArrayList<>(); + ThreadPoolMetric poolMetrics = new ThreadPoolMetric(collector.getApplicationName(), name, executor); + + list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_CORE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getCorePoolSize)); + list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_LARGEST_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getLargestPoolSize)); + list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_MAX_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getMaximumPoolSize)); + list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_ACTIVE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getActiveCount)); + list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_THREAD_COUNT, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getPoolSize)); + list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_QUEUE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getQueueSize)); + + return list; + } + + private void registryDefaultSampleThreadPoolExecutor() { try { if (this.frameworkExecutorRepository == null) { - this.frameworkExecutorRepository = collector.getApplicationModel().getFrameworkModel().getBeanFactory().getBean(FrameworkExecutorRepository.class); + this.frameworkExecutorRepository = collector.getApplicationModel() + .getFrameworkModel().getBeanFactory() + .getBean(FrameworkExecutorRepository.class); } - } catch (Exception ignored) { + } catch (Exception ex) { + logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", "ThreadPoolMetricsSampler! frameworkExecutorRepository non-init"); } - - if (frameworkExecutorRepository != null) { - addThread("SharedExecutor", frameworkExecutorRepository.getSharedExecutor()); - addThread("MappingRefreshingExecutor", frameworkExecutorRepository.getMappingRefreshingExecutor()); - addThread("PoolRouterExecutor", frameworkExecutorRepository.getPoolRouterExecutor()); + if (this.frameworkExecutorRepository != null) { + this.addExecutors("sharedExecutor", frameworkExecutorRepository.getSharedExecutor()); + this.addExecutors("mappingRefreshingExecutor", frameworkExecutorRepository.getMappingRefreshingExecutor()); + this.addExecutors("poolRouterExecutor", frameworkExecutorRepository.getPoolRouterExecutor()); } } - private void addThread(String threadPoolName, ExecutorService executorService) { - Optional executorOptional = Optional.ofNullable(executorService); - if (executorOptional.isPresent() && executorOptional.get() instanceof ThreadPoolExecutor) { - threadPoolMetricSet.add( - new ThreadPoolMetric(collector.getApplicationName(), threadPoolName, - (ThreadPoolExecutor) executorOptional.get())); - } - - } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java index 9dd6113909..a66c42139d 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java @@ -16,15 +16,11 @@ */ package org.apache.dubbo.metrics.filter; - import org.apache.dubbo.metrics.collector.sample.MethodMetricsSampler; import org.apache.dubbo.metrics.event.MetricsEvent; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; - -import java.util.function.Supplier; - import static org.apache.dubbo.common.constants.MetricsConstants.METRIC_FILTER_START_TIME; public class MethodMetricsInterceptor { @@ -35,60 +31,61 @@ public class MethodMetricsInterceptor { this.sampler = sampler; } - public void beforeExecute(Invocation invocation) { + public void beforeMethod(Invocation invocation) { sampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); sampler.incOnEvent(invocation,MetricsEvent.Type.PROCESSING); invocation.put(METRIC_FILTER_START_TIME, System.currentTimeMillis()); } - public void postExecute(Invocation invocation, Result result) { + public void afterMethod(Invocation invocation, Result result) { if (result.hasException()) { - throwExecute(invocation, result.getException()); - return; + handleMethodException(invocation, result.getException()); + }else{ + sampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED); + onCompleted(invocation); } - sampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED); - endExecute(invocation); } - public void throwExecute(Invocation invocation, Throwable throwable) { + public void handleMethodException(Invocation invocation, Throwable throwable) { + if (throwable == null) { + return; + } + if (throwable instanceof RpcException) { - RpcException rpcException = (RpcException) throwable; - switch (rpcException.getCode()) { + RpcException e = (RpcException) throwable; - case RpcException.TIMEOUT_EXCEPTION: - sampler.incOnEvent(invocation,MetricsEvent.Type.REQUEST_TIMEOUT); - break; + MetricsEvent.Type eventType = MetricsEvent.Type.UNKNOWN_FAILED; - case RpcException.LIMIT_EXCEEDED_EXCEPTION: - sampler.incOnEvent(invocation,MetricsEvent.Type.REQUEST_LIMIT); - break; - - case RpcException.BIZ_EXCEPTION: - sampler.incOnEvent(invocation,MetricsEvent.Type.BUSINESS_FAILED); - break; - - default: - sampler.incOnEvent(invocation,MetricsEvent.Type.UNKNOWN_FAILED); + if (e.isTimeout()) { + eventType = MetricsEvent.Type.REQUEST_TIMEOUT; } + if (e.isLimitExceed()) { + eventType = MetricsEvent.Type.REQUEST_LIMIT; + } + if (e.isBiz()) { + eventType = MetricsEvent.Type.BUSINESS_FAILED; + } + if (e.isSerialization()) { + eventType = MetricsEvent.Type.CODEC_EXCEPTION; + } + if (e.isNetwork()) { + eventType = MetricsEvent.Type.NETWORK_EXCEPTION; + } + sampler.incOnEvent(invocation,eventType); + } + + if (throwable instanceof RpcException && ((RpcException) throwable).isBiz()) { + onCompleted(invocation); } sampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL_FAILED); - - endExecute(invocation, () -> throwable instanceof RpcException && ((RpcException) throwable).isBiz()); } - private void endExecute(Invocation invocation) { - endExecute(invocation, () -> true); - } - - private void endExecute(Invocation invocation, Supplier rtStat) { - if (rtStat.get()) { - Long endTime = System.currentTimeMillis(); - Long beginTime = (Long) invocation.get(METRIC_FILTER_START_TIME); - Long rt = endTime - beginTime; - sampler.addRT(invocation, rt); - } + private void onCompleted(Invocation invocation) { + Long endTime = System.currentTimeMillis(); + Long beginTime = (Long) invocation.get(METRIC_FILTER_START_TIME); + Long rt = endTime - beginTime; + sampler.addRT(invocation, rt); sampler.dec(invocation,MetricsEvent.Type.PROCESSING); } - } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java new file mode 100644 index 0000000000..114b191fa0 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java @@ -0,0 +1,68 @@ +/* + * 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.metrics.filter; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.rpc.BaseFilter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.cluster.filter.ClusterFilter; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.ScopeModelAware; +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; + +@Activate(group = CONSUMER) +public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware { + + private DefaultMetricsCollector collector; + + @Override + public void setApplicationModel(ApplicationModel applicationModel) { + this.collector = applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class); + } + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + return invoker.invoke(invocation); + } + + @Override + public void onResponse(Result result, Invoker invoker, Invocation invocation) { + handleMethodException(result.getException(), invocation); + } + + @Override + public void onError(Throwable t, Invoker invoker, Invocation invocation) { + handleMethodException(t, invocation); + } + + private void handleMethodException(Throwable t, Invocation invocation) { + if (collector == null || !collector.isCollectEnabled()) { + return; + } + if (t != null && t instanceof RpcException) { + RpcException e = (RpcException) t; + if (e.isForbidden()) { + collector.getMethodSampler().incOnEvent(invocation, MetricsEvent.Type.SERVICE_UNAVAILABLE); + } + } + } +} diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java index 51c89a40ae..c981f62831 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java @@ -34,10 +34,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAware { private DefaultMetricsCollector collector = null; - private MethodMetricsInterceptor metricsInterceptor; - @Override public void setApplicationModel(ApplicationModel applicationModel) { collector = applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class); @@ -45,7 +43,6 @@ public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAwa if (collector != null) { metricsInterceptor = new MethodMetricsInterceptor(collector.getMethodSampler()); } - } @Override @@ -54,10 +51,9 @@ public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAwa return invoker.invoke(invocation); } - metricsInterceptor.beforeExecute(invocation); + metricsInterceptor.beforeMethod(invocation); return invoker.invoke(invocation); - } @Override @@ -65,7 +61,7 @@ public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAwa if (collector == null || !collector.isCollectEnabled()) { return; } - metricsInterceptor.postExecute(invocation, result); + metricsInterceptor.afterMethod(invocation, result); } @Override @@ -73,7 +69,7 @@ public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAwa if (collector == null || !collector.isCollectEnabled()) { return; } - metricsInterceptor.throwExecute(invocation, t); + metricsInterceptor.handleMethodException(invocation, t); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter index 8407d6c769..5714fefb30 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter +++ b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter @@ -1 +1,2 @@ observationsender=org.apache.dubbo.metrics.observation.ObservationSenderFilter +metricsClusterFilter=org.apache.dubbo.metrics.filter.MetricsClusterFilter diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java index c12e3ef335..bba5f0a1ee 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java @@ -105,10 +105,14 @@ class AggregateMetricsCollectorTest { defaultCollector.setApplicationName(applicationName); MethodMetricsSampler methodMetricsCountSampler = defaultCollector.getMethodSampler(); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.UNKNOWN_FAILED); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.BUSINESS_FAILED); + methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL); + methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED); + methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.UNKNOWN_FAILED); + methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.BUSINESS_FAILED); + methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.NETWORK_EXCEPTION); + methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.SERVICE_UNAVAILABLE); + methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.CODEC_EXCEPTION); + List samples = collector.collect(); for (MetricSample sample : samples) { @@ -131,6 +135,10 @@ class AggregateMetricsCollectorTest { Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_FAILED_AGG.getNameByType(side)), 1L); Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG.getNameByType(side)), 1L); + Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG.getNameByType(side)), 1L); + Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG.getNameByType(side)), 1L); + Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG.getNameByType(side)), 1L); + Assertions.assertTrue(sampleMap.containsKey(MetricsKey.METRIC_QPS.getNameByType(side))); } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java index f18115607f..11029fef55 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java @@ -44,6 +44,11 @@ import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE; import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_PARAMETER_DESC; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; @@ -57,6 +62,7 @@ class MetricsFilterTest { private ApplicationModel applicationModel; private MetricsFilter filter; + private MetricsClusterFilter metricsClusterFilter; private DefaultMetricsCollector collector; private RpcInvocation invocation; private final Invoker invoker = mock(Invoker.class); @@ -86,6 +92,8 @@ class MetricsFilterTest { invocation.setInvoker(new TestMetricsInvoker(side)); RpcContext.getServiceContext().setUrl(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&side=" + side)); + metricsClusterFilter = new MetricsClusterFilter(); + metricsClusterFilter.setApplicationModel(applicationModel); } @AfterEach @@ -128,7 +136,6 @@ class MetricsFilterTest { Assertions.assertEquals(tags.get(TAG_VERSION_KEY), VERSION); } - @Test void testBusinessFailedRequests() { collector.setCollectEnabled(true); @@ -257,6 +264,78 @@ class MetricsFilterTest { Assertions.assertEquals(tags.get(TAG_VERSION_KEY), VERSION); } + @Test + public void testErrors(){ + testFilterError(RpcException.SERIALIZATION_EXCEPTION, MetricsKey.METRIC_REQUESTS_CODEC_FAILED.formatName(side)); + testFilterError(RpcException.NETWORK_EXCEPTION, MetricsKey.METRIC_REQUESTS_NETWORK_FAILED.formatName(side)); + } + + @Test + public void testNoProvider(){ + testClusterFilterError(RpcException.FORBIDDEN_EXCEPTION, + MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED.formatName(CommonConstants.CONSUMER)); + } + + private void testClusterFilterError(int errorCode,MetricsKey metricsKey){ + setup(); + collector.setCollectEnabled(true); + given(invoker.invoke(invocation)).willThrow(new RpcException(errorCode)); + initParam(); + + Long count = 1L; + + for (int i = 0; i < count; i++) { + try { + metricsClusterFilter.invoke(invoker, invocation); + } catch (Exception e) { + Assertions.assertTrue(e instanceof RpcException); + metricsClusterFilter.onError(e, invoker, invocation); + } + } + Map metricsMap = getMetricsMap(); + Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName())); + + MetricSample sample = metricsMap.get(metricsKey.getName()); + + Assertions.assertSame(((GaugeMetricSample) sample).getSupplier().get().longValue(), count); + teardown(); + } + + private void testFilterError(int errorCode,MetricsKey metricsKey){ + setup(); + collector.setCollectEnabled(true); + given(invoker.invoke(invocation)).willThrow(new RpcException(errorCode)); + initParam(); + + Long count = 1L; + + for (int i = 0; i < count; i++) { + try { + filter.invoke(invoker, invocation); + } catch (Exception e) { + Assertions.assertTrue(e instanceof RpcException); + filter.onError(e, invoker, invocation); + } + } + Map metricsMap = getMetricsMap(); + Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName())); + + MetricSample sample = metricsMap.get(metricsKey.getName()); + + Assertions.assertSame(((GaugeMetricSample) sample).getSupplier().get().longValue(), count); + + + Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName())); + Map tags = sample.getTags(); + + Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), INTERFACE_NAME); + Assertions.assertEquals(tags.get(TAG_METHOD_KEY), METHOD_NAME); + Assertions.assertEquals(tags.get(TAG_GROUP_KEY), GROUP); + Assertions.assertEquals(tags.get(TAG_VERSION_KEY), VERSION); + + teardown(); + } + @Test void testMissingVersion() { collector.setCollectEnabled(true); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java new file mode 100644 index 0000000000..98cab8f0d6 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java @@ -0,0 +1,197 @@ +/* + * 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.metrics.sampler; + +import org.apache.dubbo.metrics.collector.sample.MetricsCountSampleConfigurer; +import org.apache.dubbo.metrics.collector.sample.SimpleMetricsCountSampler; +import org.apache.dubbo.metrics.model.MethodMetric; +import org.apache.dubbo.metrics.model.Metric; +import org.apache.dubbo.metrics.model.MetricsCategory; +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; +import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.jetbrains.annotations.NotNull; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static org.apache.dubbo.metrics.model.MetricsCategory.RT; + +public class CountSamplerTest { + + public RequestMetricsCountSampler sampler = new RequestMetricsCountSampler(); + + @BeforeEach + public void before() { + sampler = new RequestMetricsCountSampler(); + } + + @Test + public void rtTest() { + String applicationName = "test"; + + sampler.addRT(applicationName, RTType.METHOD_REQUEST, 2L); + Map collect = getCollect(RTType.METHOD_REQUEST); + + Assertions.assertNotNull(collect); + + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( + MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 2); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( + MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 2); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( + MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 2); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( + MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 2); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( + MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 2); + + sampler.addRT(applicationName, RTType.METHOD_REQUEST, 1L); + collect = getCollect(RTType.METHOD_REQUEST); + + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( + MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 1); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( + MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 1); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( + MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 2); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( + MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 1); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( + MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 3); + + sampler.addRT(applicationName, RTType.APPLICATION, 4L); + collect = getCollect(RTType.APPLICATION); + + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( + MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 4); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( + MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 4); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( + MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 4); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( + MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 4); + Assertions.assertTrue( + null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( + MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 4); + } + + @NotNull + private Map getCollect(RTType rtType) { + List metricSamples = sampler.collectRT((key, metric, count) -> new GaugeMetricSample(key.formatName("consumer"), metric.getTags(), RT, () -> count),rtType); + + Map collect = metricSamples.stream() + .collect(Collectors.toMap(MetricSample::getName, v -> v)); + return collect; + } + + private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey, MethodMetric methodMetric, + MetricsCategory metricsCategory, Supplier get) { + return new GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()), metricsKey.getDescription(), + methodMetric.getTags(), metricsCategory, get); + } + + + public class RequestMetricsCountSampler + extends SimpleMetricsCountSampler { + + @Override + public List sample() { + return null; + } + + @Override + protected void countConfigure( + MetricsCountSampleConfigurer sampleConfigure) { + sampleConfigure.configureMetrics( + configure -> new RequestMethodMetrics(configure.getSource())); + sampleConfigure.configureEventHandler(configure -> { + System.out.println("generic event"); + }); + } + + @Override + public void rtConfigure( + MetricsCountSampleConfigurer sampleConfigure) { + sampleConfigure.configureMetrics(configure -> new RequestMethodMetrics(configure.getSource())); + sampleConfigure.configureEventHandler(configure -> { + System.out.println("rt event"); + }); + } + } + + static enum RTType{ + METHOD_REQUEST, + APPLICATION + } + + static class RequestMethodMetrics implements Metric { + + private String applicationName; + + public RequestMethodMetrics(String applicationName) { + this.applicationName=applicationName; + } + @Override + public Map getTags() { + Map tags = new HashMap<>(); + tags.put("serviceName", "test"); + tags.put("version", "1.0.0"); + tags.put("uptime", "20220202"); + return tags; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof RequestMethodMetrics)) + return false; + RequestMethodMetrics that = (RequestMethodMetrics) o; + return Objects.equals(applicationName, that.applicationName); + } + + @Override + public int hashCode() { + return Objects.hash(applicationName); + } + } + +} + From ed9e26f0176610e49bc0c8deba9788b7ae1147b5 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Tue, 28 Feb 2023 16:05:25 +0800 Subject: [PATCH 049/144] Code optimization (#11683) --- .../main/java/org/apache/dubbo/common/URL.java | 2 +- .../org/apache/dubbo/common/URLBuilder.java | 4 ++-- .../common/beans/factory/ScopeBeanFactory.java | 15 ++++++++------- .../common/beanutil/JavaBeanDescriptor.java | 2 +- .../apache/dubbo/common/bytecode/Mixin.java | 2 +- .../dubbo/common/cache/FileCacheStore.java | 8 ++++---- .../dubbo/common/config/Environment.java | 4 ++-- .../dubbo/common/config/ModuleEnvironment.java | 4 ++-- .../config/OrderedPropertiesConfiguration.java | 2 +- .../common/config/PrefixedConfiguration.java | 4 ++-- .../wrapper/CompositeDynamicConfiguration.java | 2 +- .../extension/AdaptiveClassCodeGenerator.java | 2 +- .../common/extension/ExtensionLoader.java | 18 +++++++++--------- .../dubbo/common/function/Predicates.java | 4 ++-- .../apache/dubbo/common/function/Streams.java | 1 + .../common/function/ThrowableConsumer.java | 1 - .../java/org/apache/dubbo/common/io/Bytes.java | 4 ++-- .../common/lang/ShutdownHookCallbacks.java | 8 +++++--- .../common/store/support/SimpleDataStore.java | 8 ++++---- .../common/threadpool/ThreadlessExecutor.java | 2 +- .../dubbo/common/threadpool/manager/Ring.java | 2 +- .../dubbo/common/utils/AnnotationUtils.java | 10 ++++++++++ .../utils/ClassLoaderResourceLoader.java | 4 ++-- .../dubbo/common/utils/CollectionUtils.java | 4 +++- .../dubbo/common/utils/ConcurrentHashSet.java | 4 ++-- .../apache/dubbo/common/utils/ConfigUtils.java | 2 +- .../apache/dubbo/common/utils/LFUCache.java | 6 +++--- .../apache/dubbo/common/utils/LRU2Cache.java | 2 +- .../org/apache/dubbo/common/utils/LogUtil.java | 2 +- .../org/apache/dubbo/common/utils/Stack.java | 2 +- .../rpc/executor/DefaultExecutorSupport.java | 4 ++-- 31 files changed, 77 insertions(+), 62 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java index 164bbb6575..15e2185494 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java @@ -116,7 +116,7 @@ class URL implements Serializable { private static final long serialVersionUID = -1985165475234910535L; - private static Map cachedURLs = new LRUCache<>(); + private static final Map cachedURLs = new LRUCache<>(); private final URLAddress urlAddress; private final URLParam urlParam; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URLBuilder.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URLBuilder.java index 3177ac1ceb..fba84657ab 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/URLBuilder.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URLBuilder.java @@ -43,9 +43,9 @@ public final class URLBuilder extends ServiceConfigURL { private String path; - private Map parameters; + private final Map parameters; - private Map attributes; + private final Map attributes; private Map> methodParameters; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java index ff655443d5..304bfa90d8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java @@ -47,12 +47,12 @@ public class ScopeBeanFactory { protected static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(ScopeBeanFactory.class); private final ScopeBeanFactory parent; - private ExtensionAccessor extensionAccessor; - private List extensionPostProcessors; - private ConcurrentHashMap beanNameIdCounterMap = new ConcurrentHashMap<>(); - private List registeredBeanInfos = new CopyOnWriteArrayList<>(); + private final ExtensionAccessor extensionAccessor; + private final List extensionPostProcessors; + private final ConcurrentHashMap, AtomicInteger> beanNameIdCounterMap = new ConcurrentHashMap<>(); + private final List registeredBeanInfos = new CopyOnWriteArrayList<>(); private InstantiationStrategy instantiationStrategy; - private AtomicBoolean destroyed = new AtomicBoolean(); + private final AtomicBoolean destroyed = new AtomicBoolean(); public ScopeBeanFactory(ScopeBeanFactory parent, ExtensionAccessor extensionAccessor) { this.parent = parent; @@ -207,6 +207,7 @@ public class ScopeBeanFactory { return bean; } + @SuppressWarnings("unchecked") private T getBeanInternal(String name, Class type) { checkDestroyed(); // All classes are derived from java.lang.Object, cannot filter bean by it @@ -272,8 +273,8 @@ public class ScopeBeanFactory { } static class BeanInfo { - private String name; - private Object instance; + private final String name; + private final Object instance; public BeanInfo(String name, Object instance) { this.name = name; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanDescriptor.java b/dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanDescriptor.java index fec86a454a..d572720fc1 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanDescriptor.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanDescriptor.java @@ -57,7 +57,7 @@ public final class JavaBeanDescriptor implements Serializable, Iterable properties = new LinkedHashMap<>(); + private final Map properties = new LinkedHashMap<>(); public JavaBeanDescriptor() {} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Mixin.java b/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Mixin.java index 86b819d0b6..12293d1976 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Mixin.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Mixin.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicLong; */ public abstract class Mixin { private static final String PACKAGE_NAME = Mixin.class.getPackage().getName(); - private static AtomicLong MIXIN_CLASS_COUNTER = new AtomicLong(0); + private static final AtomicLong MIXIN_CLASS_COUNTER = new AtomicLong(0); protected Mixin() { } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/cache/FileCacheStore.java b/dubbo-common/src/main/java/org/apache/dubbo/common/cache/FileCacheStore.java index 0d4eb98da1..231b79a152 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/cache/FileCacheStore.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/cache/FileCacheStore.java @@ -49,10 +49,10 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CACHE public class FileCacheStore { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(FileCacheStore.class); - private String cacheFilePath; - private File cacheFile; - private File lockFile; - private FileLock directoryLock; + private final String cacheFilePath; + private final File cacheFile; + private final File lockFile; + private final FileLock directoryLock; private FileCacheStore(String cacheFilePath, File cacheFile, File lockFile, FileLock directoryLock) { this.cacheFilePath = cacheFilePath; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java index 070a94ce85..e20959e3a1 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java @@ -70,8 +70,8 @@ public class Environment extends LifecycleAdapter implements ApplicationExt { private String localMigrationRule; - private AtomicBoolean initialized = new AtomicBoolean(false); - private ScopeModel scopeModel; + private final AtomicBoolean initialized = new AtomicBoolean(false); + private final ScopeModel scopeModel; public Environment(ScopeModel scopeModel) { this.scopeModel = scopeModel; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java index 9557d41839..673815afb1 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java @@ -39,11 +39,11 @@ public class ModuleEnvironment extends Environment implements ModuleExt { public static final String NAME = "moduleEnvironment"; - private AtomicBoolean initialized = new AtomicBoolean(false); + private final AtomicBoolean initialized = new AtomicBoolean(false); private final ModuleModel moduleModel; - private Environment applicationDelegate; + private final Environment applicationDelegate; private OrderedPropertiesConfiguration orderedPropertiesConfiguration; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java index 191320ed7f..b4440a0764 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java @@ -28,7 +28,7 @@ import java.util.Set; public class OrderedPropertiesConfiguration implements Configuration { private Properties properties; - private ModuleModel moduleModel; + private final ModuleModel moduleModel; public OrderedPropertiesConfiguration(ModuleModel moduleModel) { this.moduleModel = moduleModel; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java index e23e6601ec..d8b45881fa 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java @@ -20,9 +20,9 @@ import org.apache.dubbo.common.utils.StringUtils; public class PrefixedConfiguration implements Configuration { - private String prefix; + private final String prefix; - private Configuration origin; + private final Configuration origin; public PrefixedConfiguration(Configuration origin, String prefix) { this.origin = origin; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java index 2925d7a4bc..b4afd0d46e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java @@ -37,7 +37,7 @@ public class CompositeDynamicConfiguration implements DynamicConfiguration { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(CompositeDynamicConfiguration.class); - private Set configurations = new HashSet<>(); + private final Set configurations = new HashSet<>(); public void addConfiguration(DynamicConfiguration configuration) { if (configuration != null) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java index 514ba91407..1c9517f7ae 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java @@ -74,7 +74,7 @@ public class AdaptiveClassCodeGenerator { private final Class type; - private String defaultExtName; + private final String defaultExtName; public AdaptiveClassCodeGenerator(Class type, String defaultExtName) { this.type = type; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java index 7de6405e3a..5f000daa8a 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java @@ -134,27 +134,27 @@ public class ExtensionLoader { private Set> cachedWrapperClasses; - private Map exceptions = new ConcurrentHashMap<>(); + private final Map exceptions = new ConcurrentHashMap<>(); private static volatile LoadingStrategy[] strategies = loadLoadingStrategies(); - private static Map specialSPILoadingStrategyMap = getSpecialSPILoadingStrategyMap(); + private static final Map specialSPILoadingStrategyMap = getSpecialSPILoadingStrategyMap(); private static SoftReference>> urlListMapCache = new SoftReference<>( new ConcurrentHashMap<>()); - private static List ignoredInjectMethodsDesc = getIgnoredInjectMethodsDesc(); + private static final List ignoredInjectMethodsDesc = getIgnoredInjectMethodsDesc(); /** * Record all unacceptable exceptions when using SPI */ - private Set unacceptableExceptions = new ConcurrentHashSet<>(); - private ExtensionDirector extensionDirector; - private List extensionPostProcessors; + private final Set unacceptableExceptions = new ConcurrentHashSet<>(); + private final ExtensionDirector extensionDirector; + private final List extensionPostProcessors; private InstantiationStrategy instantiationStrategy; - private ActivateComparator activateComparator; - private ScopeModel scopeModel; - private AtomicBoolean destroyed = new AtomicBoolean(); + private final ActivateComparator activateComparator; + private final ScopeModel scopeModel; + private final AtomicBoolean destroyed = new AtomicBoolean(); public static void setLoadingStrategies(LoadingStrategy... strategies) { if (ArrayUtils.isNotEmpty(strategies)) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/function/Predicates.java b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Predicates.java index 445b169647..f78a1ba3b8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/function/Predicates.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Predicates.java @@ -57,7 +57,7 @@ public interface Predicates { * @return non-null */ static Predicate and(Predicate... predicates) { - return of(predicates).reduce((a, b) -> a.and(b)).orElseGet(Predicates::alwaysTrue); + return of(predicates).reduce(Predicate::and).orElseGet(Predicates::alwaysTrue); } /** @@ -68,7 +68,7 @@ public interface Predicates { * @return non-null */ static Predicate or(Predicate... predicates) { - return of(predicates).reduce((a, b) -> a.or(b)).orElse(e -> true); + return of(predicates).reduce(Predicate::or).orElse(e -> true); } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/function/Streams.java b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Streams.java index 65e4fa6fae..0c715a54c5 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/function/Streams.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Streams.java @@ -47,6 +47,7 @@ public interface Streams { return filterStream(values, predicate).collect(LinkedHashSet::new, Set::add, Set::addAll); } + @SuppressWarnings("unchecked") static > S filter(S values, Predicate predicate) { final boolean isSet = Set.class.isAssignableFrom(values.getClass()); return (S) (isSet ? filterSet(values, predicate) : filterList(values, predicate)); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/function/ThrowableConsumer.java b/dubbo-common/src/main/java/org/apache/dubbo/common/function/ThrowableConsumer.java index 8a1cc6d1ca..d922e2baee 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/function/ThrowableConsumer.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/function/ThrowableConsumer.java @@ -58,7 +58,6 @@ public interface ThrowableConsumer { * @param t the function argument * @param consumer {@link ThrowableConsumer} * @param the source type - * @return the result after execution */ static void execute(T t, ThrowableConsumer consumer) { consumer.execute(t); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java b/dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java index b7f4596147..9e3a16a559 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java @@ -41,9 +41,9 @@ public class Bytes { private static final int MASK4 = 0x0f, MASK6 = 0x3f, MASK8 = 0xff; - private static final Map DECODE_TABLE_MAP = new ConcurrentHashMap(); + private static final Map DECODE_TABLE_MAP = new ConcurrentHashMap<>(); - private static ThreadLocal MD = new ThreadLocal(); + private static final ThreadLocal MD = new ThreadLocal<>(); private Bytes() { } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java b/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java index 5f0c7b4089..8392f23bdc 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java @@ -36,7 +36,7 @@ public class ShutdownHookCallbacks implements Disposable { private final List callbacks = new LinkedList<>(); - private ApplicationModel applicationModel; + private final ApplicationModel applicationModel; public ShutdownHookCallbacks(ApplicationModel applicationModel) { this.applicationModel = applicationModel; @@ -45,7 +45,9 @@ public class ShutdownHookCallbacks implements Disposable { public ShutdownHookCallbacks addCallback(ShutdownHookCallback callback) { synchronized (this) { - this.callbacks.add(callback); + if (!callbacks.contains(callback)) { + this.callbacks.add(callback); + } } return this; } @@ -65,7 +67,7 @@ public class ShutdownHookCallbacks implements Disposable { private void loadCallbacks() { ExtensionLoader loader = - applicationModel.getExtensionLoader(ShutdownHookCallback.class); + applicationModel.getExtensionLoader(ShutdownHookCallback.class); loader.getSupportedExtensionInstances().forEach(this::addCallback); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/store/support/SimpleDataStore.java b/dubbo-common/src/main/java/org/apache/dubbo/common/store/support/SimpleDataStore.java index d511ebd513..61c0956b44 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/store/support/SimpleDataStore.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/store/support/SimpleDataStore.java @@ -28,17 +28,17 @@ import java.util.concurrent.ConcurrentMap; public class SimpleDataStore implements DataStore { // > - private ConcurrentMap> data = - new ConcurrentHashMap>(); + private final ConcurrentMap> data = + new ConcurrentHashMap<>(); @Override public Map get(String componentName) { ConcurrentMap value = data.get(componentName); if (value == null) { - return new HashMap(); + return new HashMap<>(); } - return new HashMap(value); + return new HashMap<>(value); } @Override diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/ThreadlessExecutor.java b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/ThreadlessExecutor.java index 0cf664405f..f1479e60ae 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/ThreadlessExecutor.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/ThreadlessExecutor.java @@ -172,7 +172,7 @@ public class ThreadlessExecutor extends AbstractExecutorService { } private static class RunnableWrapper implements Runnable { - private Runnable runnable; + private final Runnable runnable; public RunnableWrapper(Runnable runnable) { this.runnable = runnable; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/Ring.java b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/Ring.java index eb9e50a9ee..c168b45c8e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/Ring.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/Ring.java @@ -25,7 +25,7 @@ public class Ring { AtomicInteger count = new AtomicInteger(); - private List itemList = new CopyOnWriteArrayList(); + private final List itemList = new CopyOnWriteArrayList<>(); public void addItem(T t) { if (t != null) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java index 770694ec9b..447cc22625 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java @@ -61,6 +61,7 @@ public interface AnnotationUtils { * @param the type of annotation * @return If resolved, return the type of annotation, or null */ + @SuppressWarnings("unchecked") static Class resolveAnnotationType(AnnotatedElement annotatedElement, String annotationClassName) { ClassLoader classLoader = annotatedElement.getClass().getClassLoader(); @@ -192,6 +193,7 @@ public interface AnnotationUtils { * @param annotationsToFilter the annotations to filter * @return non-null read-only {@link List} */ + @SuppressWarnings("unchecked") static List getAllDeclaredAnnotations(Class type, Predicate... annotationsToFilter) { if (type == null) { @@ -223,6 +225,7 @@ public interface AnnotationUtils { * @param metaAnnotationsToFilter the meta annotations to filter * @return non-null read-only {@link List} */ + @SuppressWarnings("unchecked") static List getMetaAnnotations(Class annotationType, Predicate... metaAnnotationsToFilter) { return getDeclaredAnnotations(annotationType, @@ -243,6 +246,7 @@ public interface AnnotationUtils { * @param annotationsToFilter the annotations to filter * @return non-null read-only {@link List} */ + @SuppressWarnings("unchecked") static List getAllMetaAnnotations(Class annotationType, Predicate... annotationsToFilter) { @@ -280,6 +284,7 @@ public interface AnnotationUtils { * @param the required type of annotation * @return If found, return first matched-type {@link Annotation annotation}, or null */ + @SuppressWarnings("unchecked") static A findAnnotation(AnnotatedElement annotatedElement, Class annotationType) { return (A) filterFirst(getAllDeclaredAnnotations(annotatedElement), a -> isSameType(a, annotationType)); } @@ -292,6 +297,7 @@ public interface AnnotationUtils { * @param the type of required annotation * @return if found, return all matched results, or get an {@link Collections#emptyList() empty list} */ + @SuppressWarnings("unchecked") static List findMetaAnnotations(Class annotationType, Class metaAnnotationType) { return (List) getAllMetaAnnotations(annotationType, a -> isSameType(a, metaAnnotationType)); @@ -305,6 +311,7 @@ public interface AnnotationUtils { * @param the type of required annotation * @return if found, return all matched results, or get an {@link Collections#emptyList() empty list} */ + @SuppressWarnings("unchecked") static List findMetaAnnotations(AnnotatedElement annotatedElement, Class metaAnnotationType) { List metaAnnotations = new LinkedList<>(); @@ -395,6 +402,7 @@ public interface AnnotationUtils { * @param annotationType the class of annotation * @return If the specified annotation type is present, return true, or false */ + @SuppressWarnings("unchecked") static boolean isAnnotationPresent(Class type, Class annotationType) { return isAnnotationPresent(type, true, annotationType); } @@ -406,6 +414,7 @@ public interface AnnotationUtils { * @param annotationClassName the class name of annotation * @return If any specified annotation types are present, return true */ + @SuppressWarnings("unchecked") static boolean isAnnotationPresent(AnnotatedElement annotatedElement, String annotationClassName) { ClassLoader classLoader = annotatedElement.getClass().getClassLoader(); Class resolvedType = resolveClass(annotationClassName, classLoader); @@ -477,6 +486,7 @@ public interface AnnotationUtils { * @return null if not found * @since 2.7.9 */ + @SuppressWarnings("unchecked") static T getDefaultValue(Class annotationType, String attributeName) { Method method = findMethod(annotationType, attributeName); return (T) (method == null ? null : method.getDefaultValue()); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java index 1d542c5c33..8328cd727c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java @@ -38,12 +38,12 @@ import java.util.concurrent.CountDownLatch; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_IO_EXCEPTION; public class ClassLoaderResourceLoader { - private static ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ClassLoaderResourceLoader.class); + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ClassLoaderResourceLoader.class); private static SoftReference>>> classLoaderResourcesCache = null; static { // register resources destroy listener - GlobalResourcesRepository.registerGlobalDisposable(() -> destroy()); + GlobalResourcesRepository.registerGlobalDisposable(ClassLoaderResourceLoader::destroy); } public static Map> loadResources(String fileName, Collection classLoaders) throws InterruptedException { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java index 4bf027e434..52c6f07188 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -88,11 +89,12 @@ public class CollectionUtils { * @param The value type of specified {@link Map} * @return {@link Map} */ + @SuppressWarnings("unchecked") public static Map flip(Map map) { if (isEmptyMap(map)) { return (Map) map; } - Set set = map.values().stream().collect(Collectors.toSet()); + Set set = new HashSet<>(map.values()); if (set.size() != map.size()) { throw new IllegalArgumentException("The map value must be unique."); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConcurrentHashSet.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConcurrentHashSet.java index 5067a7aead..1e8ea4cb53 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConcurrentHashSet.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConcurrentHashSet.java @@ -32,11 +32,11 @@ public class ConcurrentHashSet extends AbstractSet implements Set, java private final ConcurrentMap map; public ConcurrentHashSet() { - map = new ConcurrentHashMap(); + map = new ConcurrentHashMap<>(); } public ConcurrentHashSet(int initialCapacity) { - map = new ConcurrentHashMap(initialCapacity); + map = new ConcurrentHashMap<>(initialCapacity); } /** diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java index e937098ce1..b45a57a2f7 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java @@ -51,7 +51,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_IO_EX public class ConfigUtils { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ConfigUtils.class); - private static Pattern VARIABLE_PATTERN = Pattern.compile( + private static final Pattern VARIABLE_PATTERN = Pattern.compile( "\\$\\s*\\{?\\s*([\\._0-9a-zA-Z]+)\\s*\\}?"); private static int PID = -1; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LFUCache.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LFUCache.java index 22a15dbdfe..dcc6a945b6 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LFUCache.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LFUCache.java @@ -22,11 +22,11 @@ import java.util.concurrent.locks.ReentrantLock; public class LFUCache { - private Map> map; - private CacheDeque[] freqTable; + private final Map> map; + private final CacheDeque[] freqTable; private final int capacity; - private int evictionCount; + private final int evictionCount; private int curSize = 0; private final ReentrantLock lock = new ReentrantLock(); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRU2Cache.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRU2Cache.java index b64a2d2f5a..0602536402 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRU2Cache.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRU2Cache.java @@ -39,7 +39,7 @@ public class LRU2Cache extends LinkedHashMap { private volatile int maxCapacity; // as history list - private PreCache preCache; + private final PreCache preCache; public LRU2Cache() { this(DEFAULT_MAX_CAPACITY); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LogUtil.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LogUtil.java index 46d535215a..35c609bd11 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LogUtil.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LogUtil.java @@ -26,7 +26,7 @@ import java.util.List; public class LogUtil { - private static Logger Log = LoggerFactory.getLogger(LogUtil.class); + private static final Logger Log = LoggerFactory.getLogger(LogUtil.class); public static void start() { DubboAppender.doStart(); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Stack.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Stack.java index 0d737cd7b1..58241aadba 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Stack.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/Stack.java @@ -27,7 +27,7 @@ import java.util.List; public class Stack { private int mSize = 0; - private List mElements = new ArrayList(); + private final List mElements = new ArrayList(); public Stack() { } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/executor/DefaultExecutorSupport.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/executor/DefaultExecutorSupport.java index 68a670dd88..3cd671d201 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/executor/DefaultExecutorSupport.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/executor/DefaultExecutorSupport.java @@ -22,8 +22,8 @@ import org.apache.dubbo.common.threadpool.manager.ExecutorRepository; import java.util.concurrent.Executor; public class DefaultExecutorSupport implements ExecutorSupport { - private ExecutorRepository executorRepository; - private URL url; + private final ExecutorRepository executorRepository; + private final URL url; public DefaultExecutorSupport(URL url) { this.url = url; From dc74f131a73eb2607d3d473496decac36acadb1a Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Wed, 1 Mar 2023 09:23:39 +0800 Subject: [PATCH 050/144] Refactor GaugeMetricSample (#11692) --- .../model/sample/GaugeMetricSample.java | 40 ++++++++----- .../collector/AggregateMetricsCollector.java | 10 ++-- .../collector/DefaultMetricsCollector.java | 8 ++- .../sample/MethodMetricsSampler.java | 26 ++++++--- .../sample/SimpleMetricsCountSampler.java | 2 +- .../sample/ThreadPoolMetricsSampler.java | 25 ++++---- .../report/AbstractMetricsReporter.java | 32 ++++++----- .../service/DefaultMetricsService.java | 6 +- .../AggregateMetricsCollectorTest.java | 28 +++++---- .../metrics/filter/MetricsFilterTest.java | 10 ++-- .../DefaultMetricsCollectorTest.java | 32 +++++------ .../model/sample/GaugeMetricSampleTest.java | 18 +++--- .../metrics/sampler/CountSamplerTest.java | 57 +++++++++---------- .../collector/stat/MetadataStatComposite.java | 7 ++- .../MetadataMetricsCollectorTest.java | 15 +++-- .../collector/stat/RegistryStatComposite.java | 10 +++- .../RegistryMetricsCollectorTest.java | 7 +-- .../collector/RegistryMetricsSampleTest.java | 6 +- .../model/sample/GaugeMetricSampleTest.java | 16 ++++-- 19 files changed, 195 insertions(+), 160 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/sample/GaugeMetricSample.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/sample/GaugeMetricSample.java index 9277ab1d1e..63d4c5c70d 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/sample/GaugeMetricSample.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/sample/GaugeMetricSample.java @@ -21,35 +21,45 @@ import org.apache.dubbo.metrics.model.MetricsCategory; import org.apache.dubbo.metrics.model.MetricsKey; import java.util.Map; -import java.util.function.Supplier; +import java.util.Objects; +import java.util.function.ToDoubleFunction; /** * GaugeMetricSample. */ -public class GaugeMetricSample extends MetricSample { +public class GaugeMetricSample extends MetricSample { - private Supplier supplier; + private final T value; - public GaugeMetricSample(MetricsKey metricsKey, Map tags, MetricsCategory category, Supplier supplier) { - super(metricsKey.getName(), metricsKey.getDescription(), tags, Type.GAUGE, category); - this.supplier = supplier; + private final ToDoubleFunction apply; + + public GaugeMetricSample(MetricsKey metricsKey, Map tags, MetricsCategory category, T value, ToDoubleFunction apply) { + this(metricsKey.getName(), metricsKey.getDescription(), tags, category, null, value, apply); } - public GaugeMetricSample(String name, String description, Map tags, MetricsCategory category, Supplier supplier) { - super(name, description, tags, Type.GAUGE, category); - this.supplier = supplier; + public GaugeMetricSample(String name, String description, Map tags, MetricsCategory category, T value, ToDoubleFunction apply) { + this(name, description, tags, category, null, value, apply); } - public GaugeMetricSample(String name, String description, Map tags, MetricsCategory category, String baseUnit, Supplier supplier) { + public GaugeMetricSample(String name, String description, Map tags, MetricsCategory category, String baseUnit, T value, ToDoubleFunction apply) { super(name, description, tags, Type.GAUGE, category, baseUnit); - this.supplier = supplier; + this.value = Objects.requireNonNull(value, "The GaugeMetricSample value cannot be null"); + this.apply = Objects.requireNonNull(apply, "The GaugeMetricSample apply cannot be null"); } - public Supplier getSupplier() { - return supplier; + public T getValue() { + return this.value; } - public void setSupplier(Supplier supplier) { - this.supplier = supplier; + public ToDoubleFunction getApply() { + return this.apply; + } + + public long applyAsLong() { + return (long) getApply().applyAsDouble(getValue()); + } + + public double applyAsDouble() { + return getApply().applyAsDouble(getValue()); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java index 1651c87dc3..c5e0191d7b 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java @@ -32,11 +32,13 @@ import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.model.ApplicationModel; + import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; + import static org.apache.dubbo.metrics.model.MetricsCategory.QPS; import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; @@ -134,18 +136,18 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe private void collectMethod(List list, MetricsEvent.Type eventType, MetricsKey metricsKey) { ConcurrentHashMap windowCounter = methodTypeCounter.get(eventType); if (windowCounter != null) { - windowCounter.forEach((k, v) -> list.add(new GaugeMetricSample(metricsKey.formatName(k.getSide()), k.getTags(), REQUESTS, v::get))); + windowCounter.forEach((k, v) -> list.add(new GaugeMetricSample<>(metricsKey.formatName(k.getSide()), k.getTags(), REQUESTS, v, TimeWindowCounter::get))); } } private void collectQPS(List list) { - qps.forEach((k, v) -> list.add(new GaugeMetricSample(MetricsKey.METRIC_QPS.formatName(k.getSide()), k.getTags(), QPS, () -> v.get() / v.bucketLivedSeconds()))); + qps.forEach((k, v) -> list.add(new GaugeMetricSample<>(MetricsKey.METRIC_QPS.formatName(k.getSide()), k.getTags(), QPS, v, value -> value.get() / value.bucketLivedSeconds()))); } private void collectRT(List list) { rt.forEach((k, v) -> { - list.add(new GaugeMetricSample(MetricsKey.METRIC_RT_P99.formatName(k.getSide()), k.getTags(), RT, () -> v.quantile(0.99))); - list.add(new GaugeMetricSample(MetricsKey.METRIC_RT_P95.formatName(k.getSide()), k.getTags(), RT, () -> v.quantile(0.95))); + list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P99.formatName(k.getSide()), k.getTags(), RT, v, value -> value.quantile(0.99))); + list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P95.formatName(k.getSide()), k.getTags(), RT, v, value -> value.quantile(0.95))); }); } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java index 87bd5ea53e..ae3d378c88 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java @@ -29,8 +29,11 @@ import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.model.ApplicationModel; + import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + import static org.apache.dubbo.metrics.model.MetricsCategory.APPLICATION; import static org.apache.dubbo.metrics.model.MetricsKey.APPLICATION_METRIC_INFO; @@ -111,8 +114,9 @@ public class DefaultMetricsCollector implements MetricsCollector { public List sample() { List samples = new ArrayList<>(); this.getCount(MetricsEvent.Type.APPLICATION_INFO).filter(e -> !e.isEmpty()) - .ifPresent(map -> map.forEach((k, v) -> samples.add(new GaugeMetricSample(APPLICATION_METRIC_INFO, k.getTags(), - APPLICATION, v::get)))); + .ifPresent(map -> map.forEach((k, v) -> + samples.add(new GaugeMetricSample<>(APPLICATION_METRIC_INFO, k.getTags(), APPLICATION, v, AtomicLong::get))) + ); return samples; } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java index 3144a3c241..186a691f90 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java @@ -28,9 +28,11 @@ import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.Invocation; + import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; +import java.util.function.ToDoubleFunction; + import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; @@ -62,7 +64,7 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler getGaugeMetricSample(key, metric, RT, () -> count))); + this.collectRT((key, metric, count) -> getGaugeMetricSample(key, metric, RT, count, Number::longValue))); return metricSamples; } @@ -78,19 +80,27 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler get) { - return new GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()), metricsKey.getDescription(), - methodMetric.getTags(), metricsCategory, get); + private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey, + MethodMetric methodMetric, + MetricsCategory metricsCategory, + Number value, + ToDoubleFunction apply) { + return new GaugeMetricSample<>( + metricsKey.getNameByType(methodMetric.getSide()), + metricsKey.getDescription(), + methodMetric.getTags(), + metricsCategory, + value, + apply); } private void count(List list, MetricsEvent.Type eventType, MetricsKey metricsKey) { getCount(eventType).filter(e -> !e.isEmpty()) .ifPresent(map -> map.forEach((k, v) -> - list.add(getGaugeMetricSample(metricsKey, k, REQUESTS, v::get)))); + list.add(getGaugeMetricSample(metricsKey, k, REQUESTS, v, value -> v.get())))); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java index 5e1ddded2a..7580cee6c3 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java @@ -44,7 +44,7 @@ public abstract class SimpleMetricsCountSampler implements MetricsCountSampler { private final ConcurrentMap EMPTY_COUNT = new ConcurrentHashMap<>(); - private Map> metricCounter = new ConcurrentHashMap<>(); + private final Map> metricCounter = new ConcurrentHashMap<>(); // lastRT, totalRT, rtCount, avgRT share a container, can utilize the system cache line private final ConcurrentMap rtSample = new ConcurrentHashMap<>(); private final ConcurrentMap minRT = new ConcurrentHashMap<>(); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java index 6198f76261..7495b5a884 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java @@ -15,6 +15,7 @@ * limitations under the License. */ package org.apache.dubbo.metrics.collector.sample; + import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; @@ -23,6 +24,7 @@ import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.ThreadPoolMetric; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -31,6 +33,7 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; + import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION; import static org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL; @@ -38,9 +41,9 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ThreadPoolMetricsSampler.class); - private DefaultMetricsCollector collector; + private final DefaultMetricsCollector collector; private FrameworkExecutorRepository frameworkExecutorRepository; - private Map sampleThreadPoolExecutor = new ConcurrentHashMap<>(); + private final Map sampleThreadPoolExecutor = new ConcurrentHashMap<>(); public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) { this.collector = collector; @@ -57,23 +60,23 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { public List sample() { List metricSamples = new ArrayList<>(); - sampleThreadPoolExecutor.forEach((name, executor)->{ - metricSamples.addAll(createMetricsSample(name,executor)); + sampleThreadPoolExecutor.forEach((name, executor) -> { + metricSamples.addAll(createMetricsSample(name, executor)); }); return metricSamples; } - private List createMetricsSample(String name,ThreadPoolExecutor executor) { + private List createMetricsSample(String name, ThreadPoolExecutor executor) { List list = new ArrayList<>(); ThreadPoolMetric poolMetrics = new ThreadPoolMetric(collector.getApplicationName(), name, executor); - list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_CORE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getCorePoolSize)); - list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_LARGEST_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getLargestPoolSize)); - list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_MAX_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getMaximumPoolSize)); - list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_ACTIVE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getActiveCount)); - list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_THREAD_COUNT, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getPoolSize)); - list.add(new GaugeMetricSample(MetricsKey.THREAD_POOL_QUEUE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics::getQueueSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_CORE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getCorePoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_LARGEST_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getLargestPoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_MAX_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getMaximumPoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_ACTIVE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getActiveCount)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_THREAD_COUNT, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getPoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_QUEUE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getQueueSize)); return list; } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java index dccc46e2cc..e88bd0cdc4 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java @@ -17,17 +17,6 @@ package org.apache.dubbo.metrics.report; -import io.micrometer.core.instrument.Gauge; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.Tags; -import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; -import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; -import io.micrometer.core.instrument.binder.system.ProcessorMetrics; -import io.micrometer.core.instrument.binder.system.UptimeMetrics; -import io.micrometer.core.instrument.composite.CompositeMeterRegistry; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; import org.apache.dubbo.common.constants.MetricsConstants; @@ -41,6 +30,18 @@ import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.model.ApplicationModel; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import io.micrometer.core.instrument.binder.system.ProcessorMetrics; +import io.micrometer.core.instrument.binder.system.UptimeMetrics; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; + import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -62,6 +63,7 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { private final AtomicBoolean initialized = new AtomicBoolean(false); protected final URL url; + @SuppressWarnings("rawtypes") protected final List collectors = new ArrayList<>(); public static final CompositeMeterRegistry compositeRegistry = new CompositeMeterRegistry(); @@ -120,6 +122,7 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { } } + @SuppressWarnings("rawtypes") private void initCollectors() { ScopeBeanFactory beanFactory = applicationModel.getBeanFactory(); beanFactory.getOrRegisterBean(AggregateMetricsCollector.class); @@ -130,11 +133,10 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { private void scheduleMetricsCollectorSyncJob() { NamedThreadFactory threadFactory = new NamedThreadFactory("metrics-collector-sync-job", true); collectorSyncJobExecutor = Executors.newScheduledThreadPool(1, threadFactory); - collectorSyncJobExecutor.scheduleWithFixedDelay(() -> { - refreshData(); - }, DEFAULT_SCHEDULE_INITIAL_DELAY, DEFAULT_SCHEDULE_PERIOD, TimeUnit.SECONDS); + collectorSyncJobExecutor.scheduleWithFixedDelay(this::refreshData, DEFAULT_SCHEDULE_INITIAL_DELAY, DEFAULT_SCHEDULE_PERIOD, TimeUnit.SECONDS); } + @SuppressWarnings({"unchecked", "rawtypes"}) public void refreshData() { collectors.forEach(collector -> { List samples = collector.collect(); @@ -152,7 +154,7 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { tags.add(Tag.of(k, v)); }); - Gauge.builder(gaugeSample.getName(), gaugeSample.getSupplier()) + Gauge.builder(gaugeSample.getName(), gaugeSample.getValue(), gaugeSample.getApply()) .description(gaugeSample.getDescription()).tags(tags).register(compositeRegistry); break; case COUNTER: diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java index 3aedcfc5f3..eeb07827ca 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/service/DefaultMetricsService.java @@ -33,6 +33,7 @@ import java.util.Map; */ public class DefaultMetricsService implements MetricsService { + @SuppressWarnings("rawtypes") protected final List collectors = new ArrayList<>(); public DefaultMetricsService(ApplicationModel applicationModel) { @@ -52,7 +53,7 @@ public class DefaultMetricsService implements MetricsService { @Override public Map> getMetricsByCategories(String serviceUniqueName, String methodName, Class[] parameterTypes, List categories) { Map> result = new HashMap<>(); - for (MetricsCollector collector : collectors) { + for (MetricsCollector collector : collectors) { List samples = collector.collect(); for (MetricSample sample : samples) { if (categories.contains(sample.getCategory())) { @@ -65,6 +66,7 @@ public class DefaultMetricsService implements MetricsService { return result; } + @SuppressWarnings({"unchecked", "rawtypes"}) private MetricsEntity sampleToEntity(MetricSample sample) { MetricsEntity entity = new MetricsEntity(); @@ -74,7 +76,7 @@ public class DefaultMetricsService implements MetricsService { switch (sample.getType()) { case GAUGE: GaugeMetricSample gaugeSample = (GaugeMetricSample) sample; - entity.setValue(gaugeSample.getSupplier().get()); + entity.setValue(gaugeSample.getApply().applyAsDouble(gaugeSample.getValue())); break; case COUNTER: case LONG_TASK_TIMER: diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java index bba5f0a1ee..c4232f0039 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java @@ -31,6 +31,7 @@ import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcInvocation; import org.apache.dubbo.rpc.model.ApplicationModel; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -105,13 +106,13 @@ class AggregateMetricsCollectorTest { defaultCollector.setApplicationName(applicationName); MethodMetricsSampler methodMetricsCountSampler = defaultCollector.getMethodSampler(); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.UNKNOWN_FAILED); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.BUSINESS_FAILED); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.NETWORK_EXCEPTION); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.SERVICE_UNAVAILABLE); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.CODEC_EXCEPTION); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.UNKNOWN_FAILED); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.BUSINESS_FAILED); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.NETWORK_EXCEPTION); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SERVICE_UNAVAILABLE); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.CODEC_EXCEPTION); List samples = collector.collect(); @@ -125,10 +126,9 @@ class AggregateMetricsCollectorTest { } samples = collector.collect(); - Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + + @SuppressWarnings("rawtypes") + Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_AGG.getNameByType(side)), 1L); Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_SUCCEED_AGG.getNameByType(side)), 1L); @@ -162,10 +162,8 @@ class AggregateMetricsCollectorTest { Assertions.assertEquals(tags.get(TAG_VERSION_KEY), version); } - Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + @SuppressWarnings("rawtypes") + Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertTrue(sampleMap.containsKey(MetricsKey.METRIC_RT_P99.getNameByType(side))); Assertions.assertTrue(sampleMap.containsKey(MetricsKey.METRIC_RT_P95.getNameByType(side))); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java index 11029fef55..41b92f1bd9 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java @@ -187,10 +187,10 @@ class MetricsFilterTest { Assertions.assertTrue(metricsMap.containsKey(MetricsKey.METRIC_REQUESTS_TOTAL_FAILED.getNameByType(side))); MetricSample timeoutSample = metricsMap.get(MetricsKey.METRIC_REQUESTS_TIMEOUT.getNameByType(side)); - Assertions.assertSame(((GaugeMetricSample) timeoutSample).getSupplier().get().longValue(), count); + Assertions.assertSame(((GaugeMetricSample) timeoutSample).applyAsLong(), count); GaugeMetricSample failedSample = (GaugeMetricSample) metricsMap.get(MetricsKey.METRIC_REQUESTS_TOTAL_FAILED.getNameByType(side)); - Assertions.assertSame(failedSample.getSupplier().get().longValue(), count); + Assertions.assertSame(failedSample.applyAsLong(), count); } @Test @@ -215,7 +215,7 @@ class MetricsFilterTest { MetricSample sample = metricsMap.get(MetricsKey.METRIC_REQUESTS_LIMIT.getNameByType(side)); - Assertions.assertSame(((GaugeMetricSample) sample).getSupplier().get().longValue(), count); + Assertions.assertSame(((GaugeMetricSample) sample).applyAsLong(), count); } @Test @@ -297,7 +297,7 @@ class MetricsFilterTest { MetricSample sample = metricsMap.get(metricsKey.getName()); - Assertions.assertSame(((GaugeMetricSample) sample).getSupplier().get().longValue(), count); + Assertions.assertSame(((GaugeMetricSample) sample).applyAsLong(), count); teardown(); } @@ -322,7 +322,7 @@ class MetricsFilterTest { MetricSample sample = metricsMap.get(metricsKey.getName()); - Assertions.assertSame(((GaugeMetricSample) sample).getSupplier().get().longValue(), count); + Assertions.assertSame(((GaugeMetricSample) sample).applyAsLong(), count); Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName())); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java index 1dad4e792d..7a1d238b3f 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java @@ -34,6 +34,7 @@ import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcInvocation; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -41,7 +42,6 @@ import org.junit.jupiter.api.Test; import java.util.List; import java.util.Map; -import java.util.function.Supplier; import java.util.stream.Collectors; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; @@ -83,7 +83,7 @@ class DefaultMetricsCollectorTest { side = CommonConstants.CONSUMER; invocation.setInvoker(new TestMetricsInvoker(side)); - RpcContext.getServiceContext().setUrl(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&side="+side)); + RpcContext.getServiceContext().setUrl(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&side=" + side)); } @@ -93,6 +93,7 @@ class DefaultMetricsCollectorTest { } @Test + @SuppressWarnings("rawtypes") void testRequestsMetrics() { DefaultMetricsCollector collector = new DefaultMetricsCollector(); collector.setCollectEnabled(true); @@ -100,31 +101,28 @@ class DefaultMetricsCollectorTest { MethodMetricsSampler methodMetricsCountSampler = collector.getMethodSampler(); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.PROCESSING); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.UNKNOWN_FAILED); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.PROCESSING); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.UNKNOWN_FAILED); List samples = collector.collect(); for (MetricSample sample : samples) { Assertions.assertTrue(sample instanceof GaugeMetricSample); GaugeMetricSample gaugeSample = (GaugeMetricSample) sample; Map tags = gaugeSample.getTags(); - Supplier supplier = gaugeSample.getSupplier(); Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), interfaceName); Assertions.assertEquals(tags.get(TAG_METHOD_KEY), methodName); Assertions.assertEquals(tags.get(TAG_GROUP_KEY), group); Assertions.assertEquals(tags.get(TAG_VERSION_KEY), version); - Assertions.assertEquals(supplier.get().longValue(), 1); + Assertions.assertEquals(gaugeSample.applyAsLong(), 1); } - methodMetricsCountSampler.dec(invocation,MetricsEvent.Type.PROCESSING); + methodMetricsCountSampler.dec(invocation, MetricsEvent.Type.PROCESSING); samples = collector.collect(); - Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + + Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_REQUESTS_PROCESSING.getNameByType(side)), 0L); } @@ -151,10 +149,8 @@ class DefaultMetricsCollectorTest { Assertions.assertEquals(tags.get(TAG_VERSION_KEY), version); } - Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + @SuppressWarnings("rawtypes") + Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_RT_LAST.getNameByType(side)), 0L); Assertions.assertEquals(sampleMap.get(MetricsKey.METRIC_RT_MIN.getNameByType(side)), 0L); @@ -173,7 +169,7 @@ class DefaultMetricsCollectorTest { collector.addListener(mockListener); collector.setApplicationName(applicationModel.getApplicationName()); - methodMetricsCountSampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); Assertions.assertNotNull(mockListener.getCurEvent()); Assertions.assertTrue(mockListener.getCurEvent() instanceof RequestEvent); Assertions.assertEquals(((RequestEvent) mockListener.getCurEvent()).getType(), MetricsEvent.Type.TOTAL); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/sample/GaugeMetricSampleTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/sample/GaugeMetricSampleTest.java index 42aa87e8a1..d43e969370 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/sample/GaugeMetricSampleTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/model/sample/GaugeMetricSampleTest.java @@ -20,13 +20,15 @@ package org.apache.dubbo.metrics.metrics.model.sample; import org.apache.dubbo.metrics.model.MetricsCategory; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; -import java.util.function.Supplier; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.ToDoubleFunction; class GaugeMetricSampleTest { @@ -35,7 +37,8 @@ class GaugeMetricSampleTest { private static Map tags; private static MetricsCategory category; private static String baseUnit; - private static Supplier supplier; + private static AtomicLong value; + private static ToDoubleFunction apply; @BeforeAll public static void setup() { @@ -44,20 +47,21 @@ class GaugeMetricSampleTest { tags = new HashMap<>(); category = MetricsCategory.REQUESTS; baseUnit = "byte"; - supplier = () -> 1; + value = new AtomicLong(1); + apply = AtomicLong::longValue; } @Test void test() { - GaugeMetricSample sample = new GaugeMetricSample(name, description, tags, category, baseUnit, supplier); + GaugeMetricSample sample = new GaugeMetricSample<>(name, description, tags, category, baseUnit, value, apply); Assertions.assertEquals(sample.getName(), name); Assertions.assertEquals(sample.getDescription(), description); Assertions.assertEquals(sample.getTags(), tags); Assertions.assertEquals(sample.getType(), MetricSample.Type.GAUGE); Assertions.assertEquals(sample.getCategory(), category); Assertions.assertEquals(sample.getBaseUnit(), baseUnit); - Assertions.assertEquals(sample.getSupplier().get(), 1); - sample.setSupplier(() -> 2); - Assertions.assertEquals(sample.getSupplier().get(), 2); + Assertions.assertEquals(1, sample.applyAsLong()); + value.set(2); + Assertions.assertEquals(2, sample.applyAsLong()); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java index 98cab8f0d6..b1d701c903 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java @@ -25,6 +25,7 @@ import org.apache.dubbo.metrics.model.MetricsCategory; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; + import org.jetbrains.annotations.NotNull; import org.junit.Test; import org.junit.jupiter.api.Assertions; @@ -53,83 +54,78 @@ public class CountSamplerTest { String applicationName = "test"; sampler.addRT(applicationName, RTType.METHOD_REQUEST, 2L); + @SuppressWarnings("rawtypes") Map collect = getCollect(RTType.METHOD_REQUEST); Assertions.assertNotNull(collect); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( - MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 2); + MetricsKey.METRIC_RT_LAST.getName()).applyAsLong() == 2); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( - MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 2); + MetricsKey.METRIC_RT_MIN.getName()).applyAsLong() == 2); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( - MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 2); + MetricsKey.METRIC_RT_MAX.getName()).applyAsLong() == 2); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( - MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 2); + MetricsKey.METRIC_RT_AVG.getName()).applyAsLong() == 2); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( - MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 2); + MetricsKey.METRIC_RT_SUM.getName()).applyAsLong() == 2); sampler.addRT(applicationName, RTType.METHOD_REQUEST, 1L); collect = getCollect(RTType.METHOD_REQUEST); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( - MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 1); + MetricsKey.METRIC_RT_LAST.getName()).applyAsLong() == 1); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( - MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 1); + MetricsKey.METRIC_RT_MIN.getName()).applyAsLong() == 1); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( - MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 2); + MetricsKey.METRIC_RT_MAX.getName()).applyAsLong() == 2); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( - MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 1); + MetricsKey.METRIC_RT_AVG.getName()).applyAsLong() == 1); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( - MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 3); + MetricsKey.METRIC_RT_SUM.getName()).applyAsLong() == 3); sampler.addRT(applicationName, RTType.APPLICATION, 4L); collect = getCollect(RTType.APPLICATION); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( - MetricsKey.METRIC_RT_LAST.getName()).getSupplier().get().longValue() == 4); + MetricsKey.METRIC_RT_LAST.getName()).applyAsLong() == 4); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( - MetricsKey.METRIC_RT_MIN.getName()).getSupplier().get().longValue() == 4); + MetricsKey.METRIC_RT_MIN.getName()).applyAsLong() == 4); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( - MetricsKey.METRIC_RT_MAX.getName()).getSupplier().get().longValue() == 4); + MetricsKey.METRIC_RT_MAX.getName()).applyAsLong() == 4); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( - MetricsKey.METRIC_RT_AVG.getName()).getSupplier().get().longValue() == 4); + MetricsKey.METRIC_RT_AVG.getName()).applyAsLong() == 4); Assertions.assertTrue( null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( - MetricsKey.METRIC_RT_SUM.getName()).getSupplier().get().longValue() == 4); + MetricsKey.METRIC_RT_SUM.getName()).applyAsLong() == 4); } @NotNull + @SuppressWarnings("rawtypes") private Map getCollect(RTType rtType) { - List metricSamples = sampler.collectRT((key, metric, count) -> new GaugeMetricSample(key.formatName("consumer"), metric.getTags(), RT, () -> count),rtType); + List metricSamples = sampler.collectRT((key, metric, count) -> + new GaugeMetricSample<>(key.formatName("consumer"), metric.getTags(), RT, count, __ -> count), rtType); - Map collect = metricSamples.stream() + return metricSamples.stream() .collect(Collectors.toMap(MetricSample::getName, v -> v)); - return collect; - } - - private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey, MethodMetric methodMetric, - MetricsCategory metricsCategory, Supplier get) { - return new GaugeMetricSample(metricsKey.getNameByType(methodMetric.getSide()), metricsKey.getDescription(), - methodMetric.getTags(), metricsCategory, get); } - public class RequestMetricsCountSampler - extends SimpleMetricsCountSampler { + public class RequestMetricsCountSampler extends SimpleMetricsCountSampler { @Override public List sample() { @@ -156,21 +152,22 @@ public class CountSamplerTest { } } - static enum RTType{ + static enum RTType { METHOD_REQUEST, APPLICATION } static class RequestMethodMetrics implements Metric { - private String applicationName; + private final String applicationName; public RequestMethodMetrics(String applicationName) { - this.applicationName=applicationName; + this.applicationName = applicationName; } + @Override public Map getTags() { - Map tags = new HashMap<>(); + Map tags = new HashMap<>(); tags.put("serviceName", "test"); tags.put("version", "1.0.0"); tags.put("uptime", "20220202"); diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java index c017565158..2cb8b99298 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java @@ -94,6 +94,7 @@ public class MetadataStatComposite implements MetricsExport { } @Override + @SuppressWarnings("rawtypes") public List exportNumMetrics() { List list = new ArrayList<>(); for (MetadataEvent.Type type : numStats.keySet()) { @@ -106,19 +107,21 @@ public class MetadataStatComposite implements MetricsExport { } @Override + @SuppressWarnings("rawtypes") public List exportRtMetrics() { List list = new ArrayList<>(); for (LongContainer rtContainer : rtStats) { MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); for (Map.Entry entry : rtContainer.entrySet()) { - list.add(new GaugeMetricSample(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, () -> rtContainer.getValueSupplier().apply(entry.getKey()))); + list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, entry, value -> rtContainer.getValueSupplier().apply(value.getKey()))); } } return list; } + @SuppressWarnings("rawtypes") public GaugeMetricSample convertToSample(String applicationName, MetadataEvent.Type type, MetricsCategory category, AtomicLong targetNumber) { - return new GaugeMetricSample(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber::get); + return new GaugeMetricSample<>(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber, AtomicLong::get); } diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java index bf4cfcbdb6..1212c0f55b 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java @@ -28,6 +28,7 @@ import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -100,10 +101,9 @@ class MetadataMetricsCollectorTest { Map tags = sample.getTags(); Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationModel.getApplicationName()); } - Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + + @SuppressWarnings("rawtypes") + Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.METRIC_RT_LAST).targetKey()), lastTimePair.calc()); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_PUSH, MetricsKey.METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); @@ -150,10 +150,9 @@ class MetadataMetricsCollectorTest { Map tags = sample.getTags(); Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationModel.getApplicationName()); } - Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + + @SuppressWarnings("rawtypes") + Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.METRIC_RT_LAST).targetKey()), lastTimePair.calc()); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_SUBSCRIBE, MetricsKey.METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java index 16ad947a92..2e41f9274f 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java @@ -111,6 +111,7 @@ public class RegistryStatComposite implements MetricsExport { } @Override + @SuppressWarnings({"rawtypes"}) public List exportNumMetrics() { List list = new ArrayList<>(); for (RegistryEvent.Type type : numStats.keySet()) { @@ -123,30 +124,33 @@ public class RegistryStatComposite implements MetricsExport { } @Override + @SuppressWarnings({"rawtypes"}) public List exportRtMetrics() { List list = new ArrayList<>(); for (LongContainer rtContainer : rtStats) { MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); for (Map.Entry entry : rtContainer.entrySet()) { - list.add(new GaugeMetricSample(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, () -> rtContainer.getValueSupplier().apply(entry.getKey()))); + list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, entry, value -> rtContainer.getValueSupplier().apply(value.getKey()))); } } return list; } + @SuppressWarnings({"rawtypes"}) public List exportSkMetrics() { List list = new ArrayList<>(); for (RegistryEvent.Type type : skStats.keySet()) { Map stringAtomicLongMap = skStats.get(type); for (ServiceKeyMetric serviceKeyMetric : stringAtomicLongMap.keySet()) { - list.add(new GaugeMetricSample(type.getMetricsKey(), serviceKeyMetric.getTags(), MetricsCategory.REGISTRY, stringAtomicLongMap.get(serviceKeyMetric)::get)); + list.add(new GaugeMetricSample<>(type.getMetricsKey(), serviceKeyMetric.getTags(), MetricsCategory.REGISTRY, stringAtomicLongMap, value -> value.get(serviceKeyMetric).get())); } } return list; } + @SuppressWarnings({"rawtypes"}) public GaugeMetricSample convertToSample(String applicationName, RegistryEvent.Type type, MetricsCategory category, AtomicLong targetNumber) { - return new GaugeMetricSample(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber::get); + return new GaugeMetricSample<>(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber, AtomicLong::get); } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java index 2789758812..b5a0b1c19d 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java @@ -98,10 +98,9 @@ class RegistryMetricsCollectorTest { Map tags = sample.getTags(); Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationModel.getApplicationName()); } - Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + + @SuppressWarnings("rawtypes") + Map sampleMap = metricSamples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_LAST).targetKey()), lastTimePair.calc()); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(OP_TYPE_REGISTER, MetricsKey.METRIC_RT_MIN).targetKey()), Math.min(c1, c2)); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java index 87c89ec4f2..759b4dae31 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java @@ -74,10 +74,8 @@ class RegistryMetricsSampleTest { Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationName); } - Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> { - Number number = ((GaugeMetricSample) k).getSupplier().get(); - return number.longValue(); - })); + @SuppressWarnings("rawtypes") + Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.METRIC_RT_LAST).targetKey()), 0L); Assertions.assertEquals(sampleMap.get(new MetricsKeyWrapper(RegistryStatComposite.OP_TYPE_REGISTER, MetricsKey.METRIC_RT_MIN).targetKey()), 0L); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java index bfa6d2e176..4931e24c13 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java @@ -26,7 +26,9 @@ import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; +import java.util.function.ToDoubleFunction; class GaugeMetricSampleTest { @@ -35,7 +37,8 @@ class GaugeMetricSampleTest { private static Map tags; private static MetricsCategory category; private static String baseUnit; - private static Supplier supplier; + private static AtomicLong value; + private static ToDoubleFunction apply; @BeforeAll public static void setup() { @@ -44,20 +47,21 @@ class GaugeMetricSampleTest { tags = new HashMap<>(); category = MetricsCategory.REQUESTS; baseUnit = "byte"; - supplier = () -> 1; + value = new AtomicLong(1); + apply = AtomicLong::longValue; } @Test void test() { - GaugeMetricSample sample = new GaugeMetricSample(name, description, tags, category, baseUnit, supplier); + GaugeMetricSample sample = new GaugeMetricSample<>(name, description, tags, category, baseUnit, value, apply); Assertions.assertEquals(sample.getName(), name); Assertions.assertEquals(sample.getDescription(), description); Assertions.assertEquals(sample.getTags(), tags); Assertions.assertEquals(sample.getType(), MetricSample.Type.GAUGE); Assertions.assertEquals(sample.getCategory(), category); Assertions.assertEquals(sample.getBaseUnit(), baseUnit); - Assertions.assertEquals(sample.getSupplier().get(), 1); - sample.setSupplier(() -> 2); - Assertions.assertEquals(sample.getSupplier().get(), 2); + Assertions.assertEquals(1, sample.applyAsLong()); + value.set(2); + Assertions.assertEquals(2, sample.applyAsLong()); } } From 34981c9606facf63000264a71d2a69b93afe2fd1 Mon Sep 17 00:00:00 2001 From: ShenFeng312 <49786112+ShenFeng312@users.noreply.github.com> Date: Thu, 2 Mar 2023 06:37:06 +0800 Subject: [PATCH 051/144] add dubbo-spring-boot-observability-starter (#11579) * add dubbo-spring-boot-observability-starter * add License and fix codestyle * Add License * Add dubbo-spring-boot-observability-starter to dubbo-dependencies-all * Changes following review * Changes following review * Polish pom * Changes following review * Add dubbo-metrics-default in dubbo-spring-boot-observability-starter * Remove author tag * Polish pom --- .../dubbo-demo-spring-boot-consumer/pom.xml | 9 +- .../consumer/ObservationConfiguration.java | 215 --------------- .../dubbo-demo-spring-boot-provider/pom.xml | 8 +- .../provider/ObservationConfiguration.java | 214 -------------- dubbo-demo/dubbo-demo-spring-boot/pom.xml | 20 ++ dubbo-dependencies-bom/pom.xml | 1 + dubbo-distribution/dubbo-bom/pom.xml | 5 + .../pom.xml | 77 ++++++ .../ConditionalOnDubboTracingEnable.java | 34 +++ ...bboMicrometerTracingAutoConfiguration.java | 78 ++++++ .../DubboObservationAutoConfiguration.java | 153 ++++++++++ .../ObservationHandlerGrouping.java | 74 +++++ .../ObservationRegistryPostProcessor.java | 54 ++++ .../brave/BraveAutoConfiguration.java | 261 ++++++++++++++++++ .../otel/OpenTelemetryAutoConfiguration.java | 257 +++++++++++++++++ .../config/DubboTracingProperties.java | 191 +++++++++++++ .../spring-configuration-metadata.json | 82 ++++++ .../main/resources/META-INF/spring.factories | 6 + ...ot.autoconfigure.AutoConfiguration.imports | 4 + dubbo-spring-boot/pom.xml | 7 + dubbo-test/dubbo-dependencies-all/pom.xml | 5 + 21 files changed, 1318 insertions(+), 437 deletions(-) delete mode 100644 dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/src/main/java/org/apache/dubbo/springboot/demo/consumer/ObservationConfiguration.java delete mode 100644 dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ObservationConfiguration.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/annotation/ConditionalOnDubboTracingEnable.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboMicrometerTracingAutoConfiguration.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationHandlerGrouping.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationRegistryPostProcessor.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/config/DubboTracingProperties.java create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring-configuration-metadata.json create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring.factories create mode 100644 dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml index 6eec35ee18..626b9d9825 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml @@ -134,15 +134,16 @@ - - org.apache.dubbo - dubbo-metrics-default - io.micrometer micrometer-tracing-bridge-otel + + org.apache.dubbo + dubbo-spring-boot-observability-starter + + diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/src/main/java/org/apache/dubbo/springboot/demo/consumer/ObservationConfiguration.java b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/src/main/java/org/apache/dubbo/springboot/demo/consumer/ObservationConfiguration.java deleted file mode 100644 index 717e36a8f9..0000000000 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/src/main/java/org/apache/dubbo/springboot/demo/consumer/ObservationConfiguration.java +++ /dev/null @@ -1,215 +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.springboot.demo.consumer; - - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import io.micrometer.observation.ObservationHandler; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.tracing.Tracer; -import io.micrometer.tracing.handler.DefaultTracingObservationHandler; -import io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler; -import io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler; -import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; -import io.micrometer.tracing.otel.bridge.ArrayListSpanProcessor; -import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper; -import io.micrometer.tracing.otel.bridge.OtelBaggageManager; -import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; -import io.micrometer.tracing.otel.bridge.OtelPropagator; -import io.micrometer.tracing.otel.bridge.OtelTracer; -import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener; -import io.micrometer.tracing.otel.bridge.Slf4JEventListener; -import io.micrometer.tracing.propagation.Propagator; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.ContextStorage; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.extension.trace.propagation.B3Propagator; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import java.util.Collections; - -import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn; - -@Configuration -public class ObservationConfiguration { - /** - * Default value for application name if {@code spring.application.name} is not set. - */ - private static final String DEFAULT_APPLICATION_NAME = "application"; - - @javax.annotation.Resource - private ApplicationModel applicationModel; - - @Bean - ObservationRegistry observationRegistry() { - ObservationRegistry observationRegistry = ObservationRegistry.create(); - applicationModel.getBeanFactory().registerBean(observationRegistry); - return observationRegistry; - - } - - @Bean - MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(); - } - - @Bean - ArrayListSpanProcessor spanExporter() { - return new ArrayListSpanProcessor(); - } - - @Bean - SdkTracerProvider sdkTracerProvider(Environment environment) { - String applicationName = environment.getProperty("dubbo.application.name", DEFAULT_APPLICATION_NAME); - return SdkTracerProvider.builder().setSampler(alwaysOn()) - .addSpanProcessor(BatchSpanProcessor.builder(spanExporter()).build()) - .setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))) - .build(); - } - - @Bean - ContextPropagators contextPropagators() { - return ContextPropagators.create(B3Propagator.injectingSingleHeader()); - } - - @Bean - OpenTelemetrySdk openTelemetrySdk(SdkTracerProvider sdkTracerProvider) { - return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider) - .setPropagators(contextPropagators()).build(); - } - - @Bean - io.opentelemetry.api.trace.Tracer otelTracer(OpenTelemetrySdk openTelemetrySdk) { - return openTelemetrySdk.getTracerProvider() - .get("io.micrometer.micrometer-tracing"); - } - - @Bean - OtelCurrentTraceContext otelCurrentTraceContext() { - return new OtelCurrentTraceContext(); - } - - Slf4JEventListener slf4JEventListener() { - return new Slf4JEventListener(); - } - - Slf4JBaggageEventListener slf4JBaggageEventListener() { - return new Slf4JBaggageEventListener(Collections.emptyList()); - } - - @Bean - OtelTracer tracer(io.opentelemetry.api.trace.Tracer otelTracer, OtelCurrentTraceContext otelCurrentTraceContext) { - Slf4JEventListener slf4JEventListener = slf4JEventListener(); - Slf4JBaggageEventListener slf4JBaggageEventListener = slf4JBaggageEventListener(); - OtelTracer.EventPublisher eventPublisher = event -> { - slf4JEventListener.onEvent(event); - slf4JBaggageEventListener.onEvent(event); - }; - ContextStorage.addWrapper(new EventPublishingContextWrapper(eventPublisher)); - return new OtelTracer(otelTracer, otelCurrentTraceContext, eventPublisher, new OtelBaggageManager(otelCurrentTraceContext, Collections.emptyList(), Collections.emptyList())); - } - - @Bean - Propagator propagator(io.opentelemetry.api.trace.Tracer otelTracer) { - return new OtelPropagator(contextPropagators(), otelTracer); - } - - @Bean - ObservationHandlerRegistrar observationHandlerRegistrar(ObservationRegistry observationRegistry, OtelTracer tracer, Propagator propagator, MeterRegistry meterRegistry) { - return new ObservationHandlerRegistrar(observationRegistry, tracer, propagator, meterRegistry); - } - - @Bean - MetricsDumper metricsDumper(MeterRegistry meterRegistry) { - return new MetricsDumper(meterRegistry); - } - - @Bean - TracesDumper tracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) { - return new TracesDumper(arrayListSpanProcessor); - } - - static class ObservationHandlerRegistrar { - - private final ObservationRegistry observationRegistry; - - private final Tracer tracer; - - private final Propagator propagator; - - private final MeterRegistry meterRegistry; - - ObservationHandlerRegistrar(ObservationRegistry observationRegistry, Tracer tracer, Propagator propagator, MeterRegistry meterRegistry) { - this.observationRegistry = observationRegistry; - this.tracer = tracer; - this.propagator = propagator; - this.meterRegistry = meterRegistry; - } - - @PostConstruct - void setup() { - observationRegistry.observationConfig().observationHandler(new TracingAwareMeterObservationHandler<>(new DefaultMeterObservationHandler(meterRegistry), tracer)); - observationRegistry.observationConfig() - .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler(new PropagatingReceiverTracingObservationHandler<>(tracer, propagator), new PropagatingSenderTracingObservationHandler<>(tracer, propagator), new DefaultTracingObservationHandler(tracer))); - } - } - - - static class MetricsDumper { - private final MeterRegistry meterRegistry; - - MetricsDumper(MeterRegistry meterRegistry) { - this.meterRegistry = meterRegistry; - } - - @PreDestroy - void dumpMetrics() { - System.out.println("==== METRICS ===="); - this.meterRegistry.getMeters().forEach(meter -> System.out.println(" - Metric type \t[" + meter.getId().getType() + "],\tname [" + meter.getId().getName() + "],\ttags " + meter.getId().getTags() + ",\tmeasurements " + meter.measure())); - System.out.println("================="); - } - } - - - static class TracesDumper { - private final ArrayListSpanProcessor arrayListSpanProcessor; - - TracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) { - this.arrayListSpanProcessor = arrayListSpanProcessor; - } - - @PreDestroy - void dumpTraces() { - System.out.println("==== TRACES ===="); - this.arrayListSpanProcessor.spans().forEach(System.out::println); - System.out.println("================="); - } - } -} diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml index fcb8ec1b11..ba32f8c70e 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml @@ -133,14 +133,14 @@ - - org.apache.dubbo - dubbo-metrics-default - io.micrometer micrometer-tracing-bridge-otel + + org.apache.dubbo + dubbo-spring-boot-observability-starter + diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ObservationConfiguration.java b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ObservationConfiguration.java deleted file mode 100644 index 722427fcc5..0000000000 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ObservationConfiguration.java +++ /dev/null @@ -1,214 +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.springboot.demo.provider; - - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import io.micrometer.observation.ObservationHandler; -import io.micrometer.observation.ObservationRegistry; -import io.micrometer.tracing.Tracer; -import io.micrometer.tracing.handler.DefaultTracingObservationHandler; -import io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler; -import io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler; -import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; -import io.micrometer.tracing.otel.bridge.ArrayListSpanProcessor; -import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper; -import io.micrometer.tracing.otel.bridge.OtelBaggageManager; -import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; -import io.micrometer.tracing.otel.bridge.OtelPropagator; -import io.micrometer.tracing.otel.bridge.OtelTracer; -import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener; -import io.micrometer.tracing.otel.bridge.Slf4JEventListener; -import io.micrometer.tracing.propagation.Propagator; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.context.ContextStorage; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.extension.trace.propagation.B3Propagator; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import java.util.Collections; - -import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn; - -@Configuration -public class ObservationConfiguration { - - /** - * Default value for application name if {@code spring.application.name} is not set. - */ - private static final String DEFAULT_APPLICATION_NAME = "application"; - @javax.annotation.Resource - private ApplicationModel applicationModel; - - @Bean - ObservationRegistry observationRegistry() { - ObservationRegistry observationRegistry = ObservationRegistry.create(); - applicationModel.getBeanFactory().registerBean(observationRegistry); - return observationRegistry; - } - - @Bean - MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(); - } - - @Bean - ArrayListSpanProcessor spanExporter() { - return new ArrayListSpanProcessor(); - } - - @Bean - SdkTracerProvider sdkTracerProvider(Environment environment) { - String applicationName = environment.getProperty("dubbo.application.name", DEFAULT_APPLICATION_NAME); - return SdkTracerProvider.builder().setSampler(alwaysOn()) - .addSpanProcessor(BatchSpanProcessor.builder(spanExporter()).build()) - .setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))) - .build(); - } - - @Bean - ContextPropagators contextPropagators() { - return ContextPropagators.create(B3Propagator.injectingSingleHeader()); - } - - @Bean - OpenTelemetrySdk openTelemetrySdk(SdkTracerProvider sdkTracerProvider) { - return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider) - .setPropagators(contextPropagators()).build(); - } - - @Bean - io.opentelemetry.api.trace.Tracer otelTracer(OpenTelemetrySdk openTelemetrySdk) { - return openTelemetrySdk.getTracerProvider() - .get("io.micrometer.micrometer-tracing"); - } - - @Bean - OtelCurrentTraceContext otelCurrentTraceContext() { - return new OtelCurrentTraceContext(); - } - - Slf4JEventListener slf4JEventListener() { - return new Slf4JEventListener(); - } - - Slf4JBaggageEventListener slf4JBaggageEventListener() { - return new Slf4JBaggageEventListener(Collections.emptyList()); - } - - @Bean - OtelTracer tracer(io.opentelemetry.api.trace.Tracer otelTracer, OtelCurrentTraceContext otelCurrentTraceContext) { - Slf4JEventListener slf4JEventListener = slf4JEventListener(); - Slf4JBaggageEventListener slf4JBaggageEventListener = slf4JBaggageEventListener(); - OtelTracer.EventPublisher eventPublisher = event -> { - slf4JEventListener.onEvent(event); - slf4JBaggageEventListener.onEvent(event); - }; - ContextStorage.addWrapper(new EventPublishingContextWrapper(eventPublisher)); - return new OtelTracer(otelTracer, otelCurrentTraceContext, eventPublisher, new OtelBaggageManager(otelCurrentTraceContext, Collections.emptyList(), Collections.emptyList())); - } - - @Bean - Propagator propagator(io.opentelemetry.api.trace.Tracer otelTracer) { - return new OtelPropagator(contextPropagators(), otelTracer); - } - - @Bean - ObservationHandlerRegistrar observationHandlerRegistrar(ObservationRegistry observationRegistry, OtelTracer tracer, Propagator propagator, MeterRegistry meterRegistry) { - return new ObservationHandlerRegistrar(observationRegistry, tracer, propagator, meterRegistry); - } - - @Bean - MetricsDumper metricsDumper(MeterRegistry meterRegistry) { - return new MetricsDumper(meterRegistry); - } - - @Bean - TracesDumper tracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) { - return new TracesDumper(arrayListSpanProcessor); - } - - static class ObservationHandlerRegistrar { - - private final ObservationRegistry observationRegistry; - - private final Tracer tracer; - - private final Propagator propagator; - - private final MeterRegistry meterRegistry; - - ObservationHandlerRegistrar(ObservationRegistry observationRegistry, Tracer tracer, Propagator propagator, MeterRegistry meterRegistry) { - this.observationRegistry = observationRegistry; - this.tracer = tracer; - this.propagator = propagator; - this.meterRegistry = meterRegistry; - } - - @PostConstruct - void setup() { - observationRegistry.observationConfig().observationHandler(new TracingAwareMeterObservationHandler<>(new DefaultMeterObservationHandler(meterRegistry), tracer)); - observationRegistry.observationConfig() - .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler(new PropagatingReceiverTracingObservationHandler<>(tracer, propagator), new PropagatingSenderTracingObservationHandler<>(tracer, propagator), new DefaultTracingObservationHandler(tracer))); - } - } - - - static class MetricsDumper { - private final MeterRegistry meterRegistry; - - MetricsDumper(MeterRegistry meterRegistry) { - this.meterRegistry = meterRegistry; - } - - @PreDestroy - void dumpMetrics() { - System.out.println("==== METRICS ===="); - this.meterRegistry.getMeters().forEach(meter -> System.out.println(" - Metric type \t[" + meter.getId().getType() + "],\tname [" + meter.getId().getName() + "],\ttags " + meter.getId().getTags() + ",\tmeasurements " + meter.measure())); - System.out.println("================="); - } - } - - - static class TracesDumper { - private final ArrayListSpanProcessor arrayListSpanProcessor; - - TracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) { - this.arrayListSpanProcessor = arrayListSpanProcessor; - } - - @PreDestroy - void dumpTraces() { - System.out.println("==== TRACES ===="); - this.arrayListSpanProcessor.spans().forEach(System.out::println); - System.out.println("================="); - } - } -} diff --git a/dubbo-demo/dubbo-demo-spring-boot/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/pom.xml index 4cd2703b11..18546bdbec 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/pom.xml @@ -36,7 +36,27 @@ 8 8 true + 2.7.8 2.7.8 + 1.10.4 + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + io.micrometer + micrometer-core + ${micrometer-core.version} + + + + + diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 7208334a6e..e5d57f3907 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -135,6 +135,7 @@ 1.8.0 0.1.35 1.10.4 + 1.0.2 3.3 0.16.0 diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml index 988e6cc411..9e04c68747 100644 --- a/dubbo-distribution/dubbo-bom/pom.xml +++ b/dubbo-distribution/dubbo-bom/pom.xml @@ -487,6 +487,11 @@ pom ${project.version} + + org.apache.dubbo + dubbo-spring-boot-observability-starter + ${project.version} + diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml new file mode 100644 index 0000000000..5922c1450c --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml @@ -0,0 +1,77 @@ + + + + + org.apache.dubbo + dubbo-spring-boot + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-spring-boot-observability-starter + + + + io.micrometer + micrometer-tracing + + + io.micrometer + micrometer-observation + + + io.micrometer + micrometer-core + + + org.springframework.boot + spring-boot-autoconfigure + true + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.apache.dubbo + dubbo-common + ${project.version} + true + + + io.micrometer + micrometer-tracing-bridge-otel + true + + + io.micrometer + micrometer-tracing-bridge-brave + true + + + org.apache.dubbo + dubbo-metrics-default + ${project.version} + + + + diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/annotation/ConditionalOnDubboTracingEnable.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/annotation/ConditionalOnDubboTracingEnable.java new file mode 100644 index 0000000000..5e6d05f9ce --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/annotation/ConditionalOnDubboTracingEnable.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.spring.boot.observability.annotation; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE,ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +@ConditionalOnProperty(prefix = "dubbo.tracing", name = "enabled", matchIfMissing = true) +public @interface ConditionalOnDubboTracingEnable { +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboMicrometerTracingAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboMicrometerTracingAutoConfiguration.java new file mode 100644 index 0000000000..a1f44a1867 --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboMicrometerTracingAutoConfiguration.java @@ -0,0 +1,78 @@ +/* + * 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.spring.boot.observability.autoconfigure; + +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.handler.DefaultTracingObservationHandler; +import io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler; +import io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler; +import io.micrometer.tracing.propagation.Propagator; +import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.core.annotation.Order; + +/** + * copy from {@link org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration} + * this class is available starting from Boot 3.0. It's not available if you're using Boot < 3.0 + */ +@ConditionalOnClass(Tracer.class) +@ConditionalOnDubboTracingEnable +@AutoConfigureAfter(name = "org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration") +public class DubboMicrometerTracingAutoConfiguration { + + /** + * {@code @Order} value of + * {@link #propagatingReceiverTracingObservationHandler(Tracer, Propagator)}. + */ + public static final int RECEIVER_TRACING_OBSERVATION_HANDLER_ORDER = 1000; + + /** + * {@code @Order} value of + * {@link #propagatingSenderTracingObservationHandler(Tracer, Propagator)}. + */ + public static final int SENDER_TRACING_OBSERVATION_HANDLER_ORDER = 2000; + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Tracer.class) + public DefaultTracingObservationHandler defaultTracingObservationHandler(Tracer tracer) { + return new DefaultTracingObservationHandler(tracer); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean({Tracer.class, Propagator.class}) + @Order(SENDER_TRACING_OBSERVATION_HANDLER_ORDER) + public PropagatingSenderTracingObservationHandler propagatingSenderTracingObservationHandler(Tracer tracer, + Propagator propagator) { + return new PropagatingSenderTracingObservationHandler<>(tracer, propagator); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean({Tracer.class, Propagator.class}) + @Order(RECEIVER_TRACING_OBSERVATION_HANDLER_ORDER) + public PropagatingReceiverTracingObservationHandler propagatingReceiverTracingObservationHandler(Tracer tracer, + Propagator propagator) { + return new PropagatingReceiverTracingObservationHandler<>(tracer, propagator); + } + +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java new file mode 100644 index 0000000000..d50881e3c4 --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java @@ -0,0 +1,153 @@ +/* + * 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.spring.boot.observability.autoconfigure; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; +import io.micrometer.tracing.handler.TracingObservationHandler; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.SmartInitializingSingleton; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Arrays; + +/** + * Register observationRegistry to ApplicationModel. + * Create observationRegistry when you are using Boot <3.0 or you are not using spring-boot-starter-actuator + */ +@AutoConfiguration(after =DubboMicrometerTracingAutoConfiguration.class,afterName = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration") +@ConditionalOnDubboTracingEnable +public class DubboObservationAutoConfiguration implements BeanFactoryAware, SmartInitializingSingleton { + + public DubboObservationAutoConfiguration(ApplicationModel applicationModel) { + this.applicationModel = applicationModel; + } + + private final ApplicationModel applicationModel; + + private BeanFactory beanFactory; + + @Bean + @ConditionalOnMissingBean + ObservationRegistry observationRegistry() { + return ObservationRegistry.create(); + } + + @Bean + @ConditionalOnMissingBean(type = "org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor") + public ObservationRegistryPostProcessor dubboObservationRegistryPostProcessor(ObjectProvider observationHandlerGrouping, + ObjectProvider> observationHandlers) { + return new ObservationRegistryPostProcessor(observationHandlerGrouping, observationHandlers); + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + @Override + public void afterSingletonsInstantiated() { + applicationModel.getBeanFactory().registerBean(beanFactory.getBean(ObservationRegistry.class)); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(MeterRegistry.class) + @ConditionalOnMissingClass("io.micrometer.tracing.Tracer") + @ConditionalOnMissingBean(type = "org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor") + static class OnlyMetricsConfiguration { + + @Bean + ObservationHandlerGrouping metricsObservationHandlerGrouping() { + return new ObservationHandlerGrouping(MeterObservationHandler.class); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(Tracer.class) + @ConditionalOnMissingClass("io.micrometer.core.instrument.MeterRegistry") + @ConditionalOnMissingBean(type = "org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor") + static class OnlyTracingConfiguration { + + @Bean + ObservationHandlerGrouping tracingObservationHandlerGrouping() { + return new ObservationHandlerGrouping(TracingObservationHandler.class); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ MeterRegistry.class, Tracer.class }) + @ConditionalOnMissingBean(type = "org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor") + static class MetricsWithTracingConfiguration { + + @Bean + ObservationHandlerGrouping metricsAndTracingObservationHandlerGrouping() { + return new ObservationHandlerGrouping( + Arrays.asList(TracingObservationHandler.class, MeterObservationHandler.class)); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnBean(MeterRegistry.class) + @ConditionalOnMissingBean(MeterObservationHandler.class) + static class MeterObservationHandlerConfiguration { + + @ConditionalOnMissingBean(type = "io.micrometer.tracing.Tracer") + @Configuration(proxyBeanMethods = false) + static class OnlyMetricsMeterObservationHandlerConfiguration { + + @Bean + DefaultMeterObservationHandler defaultMeterObservationHandler(MeterRegistry meterRegistry) { + return new DefaultMeterObservationHandler(meterRegistry); + } + + } + + @ConditionalOnBean(Tracer.class) + @Configuration(proxyBeanMethods = false) + static class TracingAndMetricsObservationHandlerConfiguration { + + @Bean + TracingAwareMeterObservationHandler tracingAwareMeterObservationHandler( + MeterRegistry meterRegistry, Tracer tracer) { + DefaultMeterObservationHandler delegate = new DefaultMeterObservationHandler(meterRegistry); + return new TracingAwareMeterObservationHandler<>(delegate, tracer); + } + + } + + } +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationHandlerGrouping.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationHandlerGrouping.java new file mode 100644 index 0000000000..1c3df96886 --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationHandlerGrouping.java @@ -0,0 +1,74 @@ +/* + * 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.spring.boot.observability.autoconfigure; + +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationRegistry; +import org.springframework.util.CollectionUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.Collections; +import java.util.List; + +/** + * Groups {@link ObservationHandler ObservationHandlers} by type. + * copy from {@link org.springframework.boot.actuate.autoconfigure.observation.ObservationHandlerGrouping} + * this class is available starting from Boot 3.0. It's not available if you're using Boot < 3.0 + * + * @author Andy Wilkinson + */ +class ObservationHandlerGrouping { + + private final List> categories; + + ObservationHandlerGrouping(Class category) { + this(Collections.singletonList(category)); + } + + ObservationHandlerGrouping(List> categories) { + this.categories = categories; + } + + void apply(List> handlers, ObservationRegistry.ObservationConfig config) { + MultiValueMap, ObservationHandler> groupings = new LinkedMultiValueMap<>(); + for (ObservationHandler handler : handlers) { + Class category = findCategory(handler); + if (category != null) { + groupings.add(category, handler); + } else { + config.observationHandler(handler); + } + } + for (Class category : this.categories) { + List> handlerGroup = groupings.get(category); + if (!CollectionUtils.isEmpty(handlerGroup)) { + config.observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler(handlerGroup)); + } + } + } + + private Class findCategory(ObservationHandler handler) { + for (Class category : this.categories) { + if (category.isInstance(handler)) { + return category; + } + } + return null; + } + +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationRegistryPostProcessor.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationRegistryPostProcessor.java new file mode 100644 index 0000000000..47344b3f40 --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationRegistryPostProcessor.java @@ -0,0 +1,54 @@ +/* + * 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.spring.boot.observability.autoconfigure; + +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationRegistry; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.config.BeanPostProcessor; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * registry observationHandlers to observationConfig + */ +public class ObservationRegistryPostProcessor implements BeanPostProcessor { + private final ObjectProvider observationHandlerGrouping; + private final ObjectProvider> observationHandlers; + + public ObservationRegistryPostProcessor(ObjectProvider observationHandlerGrouping, + ObjectProvider> observationHandlers){ + this.observationHandlerGrouping = observationHandlerGrouping; + this.observationHandlers = observationHandlers; + + } + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if(bean instanceof ObservationRegistry){ + ObservationRegistry observationRegistry = (ObservationRegistry) bean; + List> observationHandlerList = + observationHandlers.orderedStream().collect(Collectors.toList()); + observationHandlerGrouping.ifAvailable(grouping->{ + grouping.apply(observationHandlerList, + observationRegistry.observationConfig()); + }); + } + return bean; + } +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java new file mode 100644 index 0000000000..dd6c1cc6cc --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java @@ -0,0 +1,261 @@ +/* + * 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.spring.boot.observability.autoconfigure.brave; + +import brave.CurrentSpanCustomizer; +import brave.SpanCustomizer; +import brave.Tracing; +import brave.TracingCustomizer; +import brave.baggage.BaggageField; +import brave.baggage.BaggagePropagation; +import brave.baggage.BaggagePropagationConfig; +import brave.baggage.BaggagePropagationCustomizer; +import brave.baggage.CorrelationScopeConfig; +import brave.baggage.CorrelationScopeCustomizer; +import brave.baggage.CorrelationScopeDecorator; +import brave.context.slf4j.MDCScopeDecorator; +import brave.handler.SpanHandler; +import brave.propagation.B3Propagation; +import brave.propagation.CurrentTraceContext; +import brave.propagation.CurrentTraceContextCustomizer; +import brave.propagation.Propagation; +import brave.propagation.ThreadLocalCurrentTraceContext; +import brave.sampler.Sampler; +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.brave.bridge.BraveBaggageManager; +import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext; +import io.micrometer.tracing.brave.bridge.BravePropagator; +import io.micrometer.tracing.brave.bridge.BraveSpanCustomizer; +import io.micrometer.tracing.brave.bridge.BraveTracer; +import io.micrometer.tracing.brave.bridge.CompositeSpanHandler; +import io.micrometer.tracing.brave.bridge.W3CPropagation; +import io.micrometer.tracing.exporter.SpanExportingPredicate; +import io.micrometer.tracing.exporter.SpanFilter; +import io.micrometer.tracing.exporter.SpanReporter; +import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable; +import org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration; +import org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * provider Brave when you are using Boot <3.0 or you are not using spring-boot-starter-actuator + */ +@AutoConfiguration(before = DubboMicrometerTracingAutoConfiguration.class, afterName = "org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration") +@ConditionalOnClass({Tracer.class, BraveTracer.class}) +@EnableConfigurationProperties(DubboTracingProperties.class) +@ConditionalOnDubboTracingEnable +public class BraveAutoConfiguration { + + private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager(); + + /** + * Default value for application name if {@code spring.application.name} is not set. + */ + private static final String DEFAULT_APPLICATION_NAME = "application"; + + @Bean + @ConditionalOnMissingBean + @Order(Ordered.HIGHEST_PRECEDENCE) + CompositeSpanHandler compositeSpanHandler(ObjectProvider predicates, + ObjectProvider reporters, ObjectProvider filters) { + return new CompositeSpanHandler(predicates.orderedStream().collect(Collectors.toList()), + reporters.orderedStream().collect(Collectors.toList()), + filters.orderedStream().collect(Collectors.toList())); + } + + @Bean + @ConditionalOnMissingBean + public Tracing braveTracing(Environment environment, List spanHandlers, + List tracingCustomizers, CurrentTraceContext currentTraceContext, + Propagation.Factory propagationFactory, Sampler sampler) { + String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); + Tracing.Builder builder = Tracing.newBuilder().currentTraceContext(currentTraceContext).traceId128Bit(true) + .supportsJoin(false).propagationFactory(propagationFactory).sampler(sampler) + .localServiceName(applicationName); + spanHandlers.forEach(builder::addSpanHandler); + for (TracingCustomizer tracingCustomizer : tracingCustomizers) { + tracingCustomizer.customize(builder); + } + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + public brave.Tracer braveTracer(Tracing tracing) { + return tracing.tracer(); + } + + @Bean + @ConditionalOnMissingBean + public CurrentTraceContext braveCurrentTraceContext(List scopeDecorators, + List currentTraceContextCustomizers) { + ThreadLocalCurrentTraceContext.Builder builder = ThreadLocalCurrentTraceContext.newBuilder(); + scopeDecorators.forEach(builder::addScopeDecorator); + for (CurrentTraceContextCustomizer currentTraceContextCustomizer : currentTraceContextCustomizers) { + currentTraceContextCustomizer.customize(builder); + } + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + public Sampler braveSampler(DubboTracingProperties properties) { + return Sampler.create(properties.getSampling().getProbability()); + } + + @Bean + @ConditionalOnMissingBean(io.micrometer.tracing.Tracer.class) + BraveTracer braveTracerBridge(brave.Tracer tracer, CurrentTraceContext currentTraceContext) { + return new BraveTracer(tracer, new BraveCurrentTraceContext(currentTraceContext), BRAVE_BAGGAGE_MANAGER); + } + + @Bean + @ConditionalOnMissingBean + BravePropagator bravePropagator(Tracing tracing) { + return new BravePropagator(tracing); + } + + @Bean + @ConditionalOnMissingBean(SpanCustomizer.class) + CurrentSpanCustomizer currentSpanCustomizer(Tracing tracing) { + return CurrentSpanCustomizer.create(tracing); + } + + @Bean + @ConditionalOnMissingBean(io.micrometer.tracing.SpanCustomizer.class) + BraveSpanCustomizer braveSpanCustomizer(SpanCustomizer spanCustomizer) { + return new BraveSpanCustomizer(spanCustomizer); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(value = "dubbo.tracing.baggage.enabled", havingValue = "false") + static class BraveNoBaggageConfiguration { + + @Bean + @ConditionalOnMissingBean + Propagation.Factory propagationFactory(DubboTracingProperties tracing) { + DubboTracingProperties.Propagation.PropagationType type = tracing.getPropagation().getType(); + switch (type) { + case B3: + return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build(); + case W3C: + return new W3CPropagation(); + default: + throw new IllegalArgumentException("UnSupport propagation type"); + } + } + + } + + @ConditionalOnProperty(value = "dubbo.tracing.baggage.enabled", matchIfMissing = true) + @Configuration(proxyBeanMethods = false) + static class BraveBaggageConfiguration { + private final DubboTracingProperties dubboTracingProperties; + + public BraveBaggageConfiguration(DubboTracingProperties dubboTracingProperties) { + this.dubboTracingProperties = dubboTracingProperties; + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", value = "type", havingValue = "B3") + BaggagePropagation.FactoryBuilder b3PropagationFactoryBuilder( + ObjectProvider baggagePropagationCustomizers) { + Propagation.Factory delegate = + B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build(); + + BaggagePropagation.FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(delegate); + baggagePropagationCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); + return builder; + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", value = "type", havingValue = "W3C", matchIfMissing = true) + BaggagePropagation.FactoryBuilder w3cPropagationFactoryBuilder( + ObjectProvider baggagePropagationCustomizers) { + Propagation.Factory delegate = new W3CPropagation(BRAVE_BAGGAGE_MANAGER, Collections.emptyList()); + + BaggagePropagation.FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(delegate); + baggagePropagationCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); + return builder; + } + + @Bean + @ConditionalOnMissingBean + @Order(0) + BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() { + return (builder) -> { + List remoteFields = dubboTracingProperties.getBaggage().getRemoteFields(); + for (String fieldName : remoteFields) { + builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName))); + } + }; + } + + @Bean + @ConditionalOnMissingBean + Propagation.Factory propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) { + return factoryBuilder.build(); + } + + @Bean + @ConditionalOnMissingBean + CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder( + ObjectProvider correlationScopeCustomizers) { + CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder(); + correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); + return builder; + } + + @Bean + @Order(0) + @ConditionalOnProperty(prefix = "dubbo.tracing.baggage.correlation", name = "enabled", + matchIfMissing = true) + CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() { + return (builder) -> { + List correlationFields = this.dubboTracingProperties.getBaggage().getCorrelation().getFields(); + for (String field : correlationFields) { + builder.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create(field)) + .flushOnUpdate().build()); + } + }; + } + + @Bean + @ConditionalOnMissingBean(CurrentTraceContext.ScopeDecorator.class) + CurrentTraceContext.ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) { + return builder.build(); + } + + } + +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java new file mode 100644 index 0000000000..c2903fa46d --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java @@ -0,0 +1,257 @@ +/* + * 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.spring.boot.observability.autoconfigure.otel; + +import io.micrometer.tracing.SpanCustomizer; +import io.micrometer.tracing.exporter.SpanExportingPredicate; +import io.micrometer.tracing.exporter.SpanFilter; +import io.micrometer.tracing.exporter.SpanReporter; +import io.micrometer.tracing.otel.bridge.CompositeSpanExporter; +import io.micrometer.tracing.otel.bridge.EventListener; +import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper; +import io.micrometer.tracing.otel.bridge.OtelBaggageManager; +import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; +import io.micrometer.tracing.otel.bridge.OtelPropagator; +import io.micrometer.tracing.otel.bridge.OtelSpanCustomizer; +import io.micrometer.tracing.otel.bridge.OtelTracer; +import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener; +import io.micrometer.tracing.otel.bridge.Slf4JEventListener; +import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.ContextStorage; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.extension.trace.propagation.B3Propagator; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; +import org.apache.dubbo.common.Version; +import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable; +import org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration; +import org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * provider OpenTelemetry when you are using Boot <3.0 or you are not using spring-boot-starter-actuator + */ +@AutoConfiguration(before = DubboMicrometerTracingAutoConfiguration.class, afterName = "org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration") +@ConditionalOnDubboTracingEnable +@ConditionalOnClass({OtelTracer.class, SdkTracerProvider.class, OpenTelemetry.class}) +@EnableConfigurationProperties(DubboTracingProperties.class) +public class OpenTelemetryAutoConfiguration { + + /** + * Default value for application name if {@code spring.application.name} is not set. + */ + private static final String DEFAULT_APPLICATION_NAME = "application"; + + private final DubboTracingProperties dubboTracingProperties; + + OpenTelemetryAutoConfiguration(DubboTracingProperties dubboTracingProperties) { + this.dubboTracingProperties = dubboTracingProperties; + } + + @Bean + @ConditionalOnMissingBean + OpenTelemetry openTelemetry(SdkTracerProvider sdkTracerProvider, ContextPropagators contextPropagators) { + return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).setPropagators(contextPropagators) + .build(); + } + + @Bean + @ConditionalOnMissingBean + SdkTracerProvider otelSdkTracerProvider(Environment environment, ObjectProvider spanProcessors, + Sampler sampler) { + String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME); + SdkTracerProviderBuilder builder = SdkTracerProvider.builder().setSampler(sampler) + .setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))); + spanProcessors.orderedStream().forEach(builder::addSpanProcessor); + return builder.build(); + } + + @Bean + @ConditionalOnMissingBean + ContextPropagators otelContextPropagators(ObjectProvider textMapPropagators) { + return ContextPropagators.create(TextMapPropagator.composite(textMapPropagators.orderedStream().collect(Collectors.toList()))); + } + + @Bean + @ConditionalOnMissingBean + Sampler otelSampler() { + Sampler rootSampler = Sampler.traceIdRatioBased(this.dubboTracingProperties.getSampling().getProbability()); + return Sampler.parentBased(rootSampler); + } + + @Bean + @ConditionalOnMissingBean + SpanProcessor otelSpanProcessor(ObjectProvider spanExporters, + ObjectProvider spanExportingPredicates, ObjectProvider spanReporters, + ObjectProvider spanFilters) { + return BatchSpanProcessor.builder(new CompositeSpanExporter(spanExporters.orderedStream().collect(Collectors.toList()), + spanExportingPredicates.orderedStream().collect(Collectors.toList()), spanReporters.orderedStream().collect(Collectors.toList()), + spanFilters.orderedStream().collect(Collectors.toList()))).build(); + } + + @Bean + @ConditionalOnMissingBean + Tracer otelTracer(OpenTelemetry openTelemetry) { + return openTelemetry.getTracer("org.apache.dubbo", Version.getVersion()); + } + + @Bean + @ConditionalOnMissingBean(io.micrometer.tracing.Tracer.class) + OtelTracer micrometerOtelTracer(Tracer tracer, OtelTracer.EventPublisher eventPublisher, + OtelCurrentTraceContext otelCurrentTraceContext) { + return new OtelTracer(tracer, otelCurrentTraceContext, eventPublisher, + new OtelBaggageManager(otelCurrentTraceContext, this.dubboTracingProperties.getBaggage().getRemoteFields(), + Collections.emptyList())); + } + + @Bean + @ConditionalOnMissingBean + OtelPropagator otelPropagator(ContextPropagators contextPropagators, Tracer tracer) { + return new OtelPropagator(contextPropagators, tracer); + } + + @Bean + @ConditionalOnMissingBean + OtelTracer.EventPublisher otelTracerEventPublisher(List eventListeners) { + return new OTelEventPublisher(eventListeners); + } + + @Bean + @ConditionalOnMissingBean + OtelCurrentTraceContext otelCurrentTraceContext(OtelTracer.EventPublisher publisher) { + ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher)); + return new OtelCurrentTraceContext(); + } + + @Bean + @ConditionalOnMissingBean + Slf4JEventListener otelSlf4JEventListener() { + return new Slf4JEventListener(); + } + + @Bean + @ConditionalOnMissingBean(SpanCustomizer.class) + OtelSpanCustomizer otelSpanCustomizer() { + return new OtelSpanCustomizer(); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(prefix = "dubbo.tracing.baggage", name = "enabled", matchIfMissing = true) + static class BaggageConfiguration { + + private final DubboTracingProperties tracingProperties; + + BaggageConfiguration(DubboTracingProperties tracingProperties) { + this.tracingProperties = tracingProperties; + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "W3C", + matchIfMissing = true) + TextMapPropagator w3cTextMapPropagatorWithBaggage(OtelCurrentTraceContext otelCurrentTraceContext) { + List remoteFields = this.tracingProperties.getBaggage().getRemoteFields(); + return TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), + W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields, + new OtelBaggageManager(otelCurrentTraceContext, remoteFields, Collections.emptyList()))); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "B3") + TextMapPropagator b3BaggageTextMapPropagator(OtelCurrentTraceContext otelCurrentTraceContext) { + List remoteFields = this.tracingProperties.getBaggage().getRemoteFields(); + return TextMapPropagator.composite(B3Propagator.injectingSingleHeader(), + new BaggageTextMapPropagator(remoteFields, + new OtelBaggageManager(otelCurrentTraceContext, remoteFields, Collections.emptyList()))); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "dubbo.tracing.baggage.correlation", name = "enabled", + matchIfMissing = true) + Slf4JBaggageEventListener otelSlf4JBaggageEventListener() { + return new Slf4JBaggageEventListener(this.tracingProperties.getBaggage().getCorrelation().getFields()); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(prefix = "dubbo.tracing.baggage", name = "enabled", havingValue = "false") + static class NoBaggageConfiguration { + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "B3") + B3Propagator b3TextMapPropagator() { + return B3Propagator.injectingSingleHeader(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "W3C", + matchIfMissing = true) + W3CTraceContextPropagator w3cTextMapPropagatorWithoutBaggage() { + return W3CTraceContextPropagator.getInstance(); + } + + } + + static class OTelEventPublisher implements OtelTracer.EventPublisher { + + private final List listeners; + + OTelEventPublisher(List listeners) { + this.listeners = listeners; + } + + @Override + public void publishEvent(Object event) { + for (EventListener listener : this.listeners) { + listener.onEvent(event); + } + } + + } + +} + diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/config/DubboTracingProperties.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/config/DubboTracingProperties.java new file mode 100644 index 0000000000..72d4b967df --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/config/DubboTracingProperties.java @@ -0,0 +1,191 @@ +/* + * 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.spring.boot.observability.config; + + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.ArrayList; +import java.util.List; + +@ConfigurationProperties("dubbo.tracing") +public class DubboTracingProperties { + + /** + * Whether auto-configuration of tracing is enabled. + */ + private boolean enabled = true; + + /** + * Sampling configuration. + */ + private final Sampling sampling = new Sampling(); + + /** + * Baggage configuration. + */ + private final Baggage baggage = new Baggage(); + + /** + * Propagation configuration. + */ + private final Propagation propagation = new Propagation(); + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Sampling getSampling() { + return this.sampling; + } + + public Baggage getBaggage() { + return this.baggage; + } + + public Propagation getPropagation() { + return this.propagation; + } + + public static class Sampling { + + /** + * Probability in the range from 0.0 to 1.0 that a trace will be sampled. + */ + private float probability = 0.10f; + + public float getProbability() { + return this.probability; + } + + public void setProbability(float probability) { + this.probability = probability; + } + + } + + public static class Baggage { + + /** + * Whether to enable Micrometer Tracing baggage propagation. + */ + private boolean enabled = true; + + /** + * Correlation configuration. + */ + private Correlation correlation = new Correlation(); + + /** + * List of fields that are referenced the same in-process as it is on the wire. + * For example, the field "x-vcap-request-id" would be set as-is including the + * prefix. + */ + private List remoteFields = new ArrayList<>(); + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Correlation getCorrelation() { + return this.correlation; + } + + public void setCorrelation(Correlation correlation) { + this.correlation = correlation; + } + + public List getRemoteFields() { + return this.remoteFields; + } + + public void setRemoteFields(List remoteFields) { + this.remoteFields = remoteFields; + } + + public static class Correlation { + + /** + * Whether to enable correlation of the baggage context with logging contexts. + */ + private boolean enabled = true; + + /** + * List of fields that should be correlated with the logging context. That + * means that these fields would end up as key-value pairs in e.g. MDC. + */ + private List fields = new ArrayList<>(); + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public List getFields() { + return this.fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + } + + } + + public static class Propagation { + + /** + * Tracing context propagation type. + */ + private PropagationType type = PropagationType.W3C; + + public PropagationType getType() { + return this.type; + } + + public void setType(PropagationType type) { + this.type = type; + } + + public enum PropagationType { + + /** + * B3 propagation type. + */ + B3, + + /** + * W3C propagation type. + */ + W3C + + } + + } +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring-configuration-metadata.json b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring-configuration-metadata.json new file mode 100644 index 0000000000..3ae084b1f1 --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring-configuration-metadata.json @@ -0,0 +1,82 @@ +{ + "groups": [ + { + "name": "dubbo.tracing", + "type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties" + }, + { + "name": "dubbo.tracing.baggage", + "type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties", + "sourceMethod": "getBaggage()" + }, + { + "name": "dubbo.tracing.baggage.correlation", + "type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage", + "sourceMethod": "getCorrelation()" + }, + { + "name": "dubbo.tracing.propagation", + "type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties", + "sourceMethod": "getPropagation()" + }, + { + "name": "dubbo.tracing.sampling", + "type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Sampling", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties", + "sourceMethod": "getSampling()" + } + ], + "properties": [ + { + "name": "dubbo.tracing.baggage.correlation.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable correlation of the baggage context with logging contexts.", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation", + "defaultValue": true + }, + { + "name": "dubbo.tracing.baggage.correlation.fields", + "type": "java.util.List", + "description": "List of fields that should be correlated with the logging context. That means that these fields would end up as key-value pairs in e.g. MDC.", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation" + }, + { + "name": "dubbo.tracing.baggage.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Micrometer Tracing baggage propagation.", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage", + "defaultValue": true + }, + { + "name": "dubbo.tracing.baggage.remote-fields", + "type": "java.util.List", + "description": "List of fields that are referenced the same in-process as it is on the wire. For example, the field \"x-vcap-request-id\" would be set as-is including the prefix.", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage" + }, + { + "name": "dubbo.tracing.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of tracing is enabled.", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties", + "defaultValue": true + }, + { + "name": "dubbo.tracing.propagation.type", + "type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation$PropagationType", + "description": "Tracing context propagation type.", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation" + }, + { + "name": "dubbo.tracing.sampling.probability", + "type": "java.lang.Float", + "description": "Probability in the range from 0.0 to 1.0 that a trace will be sampled.", + "sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Sampling", + "defaultValue": 0.1 + } + ], + "hints": [] +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring.factories b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..b7a570ea76 --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.apache.dubbo.spring.boot.observability.autoconfigure.otel.OpenTelemetryAutoConfiguration,\ +org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration,\ +org.apache.dubbo.spring.boot.observability.autoconfigure.DubboObservationAutoConfiguration,\ +org.apache.dubbo.spring.boot.observability.autoconfigure.brave.BraveAutoConfiguration + diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000000..9d3769fc9c --- /dev/null +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,4 @@ +org.apache.dubbo.spring.boot.observability.autoconfigure.otel.OpenTelemetryAutoConfiguration +org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration +org.apache.dubbo.spring.boot.observability.autoconfigure.DubboObservationAutoConfiguration +org.apache.dubbo.spring.boot.observability.autoconfigure.brave.BraveAutoConfiguration diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index 4c43c07955..2d6991aac4 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -36,6 +36,7 @@ dubbo-spring-boot-autoconfigure dubbo-spring-boot-compatible dubbo-spring-boot-starter + dubbo-spring-boot-observability-starter @@ -45,6 +46,7 @@ 2.19.0 1.13.0 + 1.10.4 @@ -57,6 +59,11 @@ pom import + + io.micrometer + micrometer-core + ${micrometer-core.version} + diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index 5e9a515d5a..90e91d7e4d 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -318,6 +318,11 @@ dubbo-spring-boot-starter + + org.apache.dubbo + dubbo-spring-boot-observability-starter + + org.apache.dubbo From 6d6e3a5e9e1caa712308ea25ed6b8fef04d15c92 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 2 Mar 2023 06:42:47 +0800 Subject: [PATCH 052/144] Refactor metrics TimeWindow (#11638) * Add TimeUtils * Abstract sliding window * Refactor TimeWindow Counter and Quantile * Add license header * Fix sonar problem * Fix sonar problem * Fix sonar check bug * Start the ticker on demand * Fallback when ticker exception --- .../apache/dubbo/common/utils/TimeUtils.java | 75 +++++ .../dubbo/common/utils/TimeUtilsTest.java | 30 ++ .../apache/dubbo/metrics/aggregate/Pane.java | 126 ++++++++ .../metrics/aggregate/SlidingWindow.java | 300 ++++++++++++++++++ .../metrics/aggregate/TimeWindowCounter.java | 81 +++-- .../metrics/aggregate/TimeWindowQuantile.java | 69 ++-- .../dubbo/metrics/aggregate/PaneTest.java | 72 +++++ .../metrics/aggregate/SlidingWindowTest.java | 137 ++++++++ .../aggregate/TimeWindowCounterTest.java | 4 +- .../aggregate/TimeWindowQuantileTest.java | 4 +- 10 files changed, 818 insertions(+), 80 deletions(-) create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java create mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/utils/TimeUtilsTest.java create mode 100755 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/Pane.java create mode 100755 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java create mode 100644 dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/PaneTest.java create mode 100644 dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/SlidingWindowTest.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java new file mode 100644 index 0000000000..79974d1864 --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.utils; + +import java.util.concurrent.TimeUnit; + +/** + * Provide currentTimeMillis acquisition for high-frequency access scenarios. + */ +public final class TimeUtils { + + private static volatile long currentTimeMillis; + + private static volatile boolean isTickerAlive = false; + + private static volatile boolean isFallback = false; + + private TimeUtils() { + } + + public static long currentTimeMillis() { + // When an exception occurs in the Ticker mechanism, fall back. + if (isFallback) { + return System.currentTimeMillis(); + } + + if (!isTickerAlive) { + try { + startTicker(); + } catch (Exception e) { + isFallback = true; + } + } + return currentTimeMillis; + } + + private static synchronized void startTicker() { + if (!isTickerAlive) { + currentTimeMillis = System.currentTimeMillis(); + Thread ticker = new Thread(() -> { + while (isTickerAlive) { + currentTimeMillis = System.currentTimeMillis(); + try { + TimeUnit.MILLISECONDS.sleep(1); + } catch (InterruptedException e) { + isTickerAlive = false; + Thread.currentThread().interrupt(); + } catch (Exception ignored) { + // + } + } + }); + ticker.setDaemon(true); + ticker.setName("time-millis-ticker-thread"); + ticker.start(); + Runtime.getRuntime().addShutdownHook(new Thread(ticker::interrupt)); + isTickerAlive = true; + } + } +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/TimeUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/TimeUtilsTest.java new file mode 100644 index 0000000000..c51e8786a7 --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/TimeUtilsTest.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.utils; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TimeUtilsTest { + + @Test + void testCurrentTimeMillis() { + assertTrue(0 < TimeUtils.currentTimeMillis()); + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/Pane.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/Pane.java new file mode 100755 index 0000000000..af7908d026 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/Pane.java @@ -0,0 +1,126 @@ +/* + * 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.metrics.aggregate; + +/** + * The pane represents a window over a period of time. + * + * @param The type of value the pane statistics. + */ +public class Pane { + + /** + * Time interval of the pane in milliseconds. + */ + private final long intervalInMs; + + /** + * Start timestamp of the pane in milliseconds. + */ + private volatile long startInMs; + + /** + * End timestamp of the pane in milliseconds. + *

+ * endInMs = startInMs + intervalInMs + */ + private volatile long endInMs; + + /** + * Pane statistics value. + */ + private T value; + + /** + * @param intervalInMs interval of the pane in milliseconds. + * @param startInMs start timestamp of the pane in milliseconds. + * @param value the pane value. + */ + public Pane(long intervalInMs, long startInMs, T value) { + this.intervalInMs = intervalInMs; + this.startInMs = startInMs; + this.endInMs = this.startInMs + this.intervalInMs; + this.value = value; + } + + /** + * Get the interval of the pane in milliseconds. + * + * @return the interval of the pane in milliseconds. + */ + public long getIntervalInMs() { + return this.intervalInMs; + } + + /** + * Get start timestamp of the pane in milliseconds. + * + * @return the start timestamp of the pane in milliseconds. + */ + public long getStartInMs() { + return this.startInMs; + } + + /** + * Get end timestamp of the pane in milliseconds. + * + * @return the end timestamp of the pane in milliseconds. + */ + public long getEndInMs() { + return this.endInMs; + } + + /** + * Get the pane statistics value. + * + * @return the pane statistics value. + */ + public T getValue() { + return this.value; + } + + /** + * Set the new start timestamp to the pane, for reset the instance. + * + * @param newStartInMs the new start timestamp. + */ + public void setStartInMs(long newStartInMs) { + this.startInMs = newStartInMs; + this.endInMs = this.startInMs + this.intervalInMs; + } + + /** + * Set new value to the pane, for reset the instance. + * + * @param newData the new value. + */ + public void setValue(T newData) { + this.value = newData; + } + + /** + * Check whether given timestamp is in current pane. + * + * @param timeMillis timestamp in milliseconds. + * @return true if the given time is in current pane, otherwise false + */ + public boolean isTimeInWindow(long timeMillis) { + // [) + return startInMs <= timeMillis && timeMillis < endInMs; + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java new file mode 100755 index 0000000000..de1fd09583 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java @@ -0,0 +1,300 @@ +/* + * 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.metrics.aggregate; + +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.common.utils.TimeUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.concurrent.locks.ReentrantLock; + +/** + * SlidingWindow adopts sliding window algorithm for statistics. + *

+ * A window contains {@code paneCount} panes, + * {@code intervalInMs} = {@code paneCount} * {@code paneIntervalInMs} + * + * @param Value type for window statistics. + */ +public abstract class SlidingWindow { + + /** + * The number of panes the sliding window contains. + */ + protected int paneCount; + + /** + * Total time interval of the sliding window in milliseconds. + */ + protected long intervalInMs; + + /** + * Time interval of a pane in milliseconds. + */ + protected long paneIntervalInMs; + + /** + * The panes reference, supports atomic operations. + */ + protected final AtomicReferenceArray> referenceArray; + + /** + * The lock is used only when current pane is deprecated. + */ + private final ReentrantLock updateLock = new ReentrantLock(); + + protected SlidingWindow(int paneCount, long intervalInMs) { + Assert.assertTrue(paneCount > 0, "pane count is invalid: " + paneCount); + Assert.assertTrue(intervalInMs > 0, "total time interval of the sliding window should be positive"); + Assert.assertTrue(intervalInMs % paneCount == 0, "total time interval needs to be evenly divided"); + + this.paneCount = paneCount; + this.intervalInMs = intervalInMs; + this.paneIntervalInMs = intervalInMs / paneCount; + this.referenceArray = new AtomicReferenceArray<>(paneCount); + } + + /** + * Get the pane at the current timestamp. + * + * @return the pane at current timestamp. + */ + public Pane currentPane() { + return currentPane(TimeUtils.currentTimeMillis()); + } + + /** + * Get the pane at the specified timestamp in milliseconds. + * + * @param timeMillis a timestamp in milliseconds. + * @return the pane at the specified timestamp if the time is valid; null if time is invalid. + */ + public Pane currentPane(long timeMillis) { + if (timeMillis < 0) { + return null; + } + + int paneIdx = calculatePaneIdx(timeMillis); + long paneStartInMs = calculatePaneStart(timeMillis); + + while (true) { + Pane oldPane = referenceArray.get(paneIdx); + + // Create a pane instance when the pane does not exist. + if (oldPane == null) { + Pane pane = new Pane<>(paneIntervalInMs, paneStartInMs, newEmptyValue(timeMillis)); + if (referenceArray.compareAndSet(paneIdx, null, pane)) { + return pane; + } else { + // Contention failed, the thread will yield its time slice to wait for pane available. + Thread.yield(); + } + } + // + else if (paneStartInMs == oldPane.getStartInMs()) { + return oldPane; + } + // The pane has deprecated. To avoid the overhead of creating a new instance, reset the original pane directly. + else if (paneStartInMs > oldPane.getStartInMs()) { + if (updateLock.tryLock()) { + try { + return resetPaneTo(oldPane, paneStartInMs); + } finally { + updateLock.unlock(); + } + } else { + // Contention failed, the thread will yield its time slice to wait for pane available. + Thread.yield(); + } + } + // The specified timestamp has passed. + else if (paneStartInMs < oldPane.getStartInMs()) { + return new Pane<>(paneIntervalInMs, paneStartInMs, newEmptyValue(timeMillis)); + } + } + } + + /** + * Get statistic value from pane at the specified timestamp. + * + * @param timeMillis the specified timestamp in milliseconds. + * @return the statistic value if pane at the specified timestamp is up-to-date; otherwise null. + */ + public T getPaneValue(long timeMillis) { + if (timeMillis < 0) { + return null; + } + + int paneIdx = calculatePaneIdx(timeMillis); + + Pane pane = referenceArray.get(paneIdx); + + if (pane == null || !pane.isTimeInWindow(timeMillis)) { + return null; + } + + return pane.getValue(); + } + + /** + * Create a new statistic value for pane. + * + * @param timeMillis the specified timestamp in milliseconds. + * @return new empty statistic value. + */ + public abstract T newEmptyValue(long timeMillis); + + /** + * Reset given pane to the specified start time and reset the value. + * + * @param pane the given pane. + * @param startInMs the start timestamp of the pane in milliseconds. + * @return reset pane. + */ + protected abstract Pane resetPaneTo(final Pane pane, long startInMs); + + /** + * Calculate the pane index corresponding to the specified timestamp. + * + * @param timeMillis the specified timestamp. + * @return the pane index corresponding to the specified timestamp. + */ + private int calculatePaneIdx(long timeMillis) { + return (int) ((timeMillis / paneIntervalInMs) % paneCount); + } + + /** + * Calculate the pane start corresponding to the specified timestamp. + * + * @param timeMillis the specified timestamp. + * @return the pane start corresponding to the specified timestamp. + */ + protected long calculatePaneStart(long timeMillis) { + return timeMillis - timeMillis % paneIntervalInMs; + } + + /** + * Checks if the specified pane is deprecated at the current timestamp. + * + * @param pane the specified pane. + * @return true if the pane is deprecated; otherwise false. + */ + public boolean isPaneDeprecated(final Pane pane) { + return isPaneDeprecated(TimeUtils.currentTimeMillis(), pane); + } + + /** + * Checks if the specified pane is deprecated at the specified timestamp. + * + * @param timeMillis the specified time. + * @param pane the specified pane. + * @return true if the pane is deprecated; otherwise false. + */ + public boolean isPaneDeprecated(long timeMillis, final Pane pane) { + // the pane is '[)' + return (timeMillis - pane.getStartInMs()) > intervalInMs; + } + + /** + * Get valid pane list for entire sliding window at the current time. + * The list will only contain "valid" panes. + * + * @return valid pane list for entire sliding window. + */ + public List> list() { + return list(TimeUtils.currentTimeMillis()); + } + + /** + * Get valid pane list for entire sliding window at the specified time. + * The list will only contain "valid" panes. + * + * @param timeMillis the specified time. + * @return valid pane list for entire sliding window. + */ + public List> list(long timeMillis) { + if (timeMillis < 0) { + return new ArrayList<>(); + } + + List> result = new ArrayList<>(paneCount); + + for (int idx = 0; idx < paneCount; idx++) { + Pane pane = referenceArray.get(idx); + if (pane == null || isPaneDeprecated(timeMillis, pane)) { + continue; + } + result.add(pane); + } + + return result; + } + + /** + * Get aggregated value list for entire sliding window at the current time. + * The list will only contain value from "valid" panes. + * + * @return aggregated value list for entire sliding window. + */ + public List values() { + return values(TimeUtils.currentTimeMillis()); + } + + /** + * Get aggregated value list for entire sliding window at the specified time. + * The list will only contain value from "valid" panes. + * + * @return aggregated value list for entire sliding window. + */ + public List values(long timeMillis) { + if (timeMillis < 0) { + return new ArrayList<>(); + } + + List result = new ArrayList<>(paneCount); + + for (int idx = 0; idx < paneCount; idx++) { + Pane pane = referenceArray.get(idx); + if (pane == null || isPaneDeprecated(timeMillis, pane)) { + continue; + } + result.add(pane.getValue()); + } + return result; + } + + /** + * Get total interval of the sliding window in milliseconds. + * + * @return the total interval in milliseconds. + */ + public long getIntervalInMs() { + return intervalInMs; + } + + /** + * Get pane interval of the sliding window in milliseconds. + * + * @return the interval of a pane in milliseconds. + */ + public long getPaneIntervalInMs() { + return paneIntervalInMs; + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounter.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounter.java index 3dc3666602..ee15210066 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounter.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounter.java @@ -17,74 +17,69 @@ package org.apache.dubbo.metrics.aggregate; +import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.LongAdder; /** * Wrapper around Counter like Long and Integer. - *

- * Maintains a ring buffer of Counter to provide count over a sliding windows of time. */ public class TimeWindowCounter { - private final Long[] ringBuffer; - private final Long[] bucketStartTimeMillis; - private int currentBucket; - private long lastRotateTimestampMillis; - private final long durationBetweenRotatesMillis; + + private final LongAdderSlidingWindow slidingWindow; public TimeWindowCounter(int bucketNum, int timeWindowSeconds) { - this.ringBuffer = new Long[bucketNum]; - this.bucketStartTimeMillis = new Long[bucketNum]; - for (int i = 0; i < bucketNum; i++) { - this.ringBuffer[i] = 0L; - this.bucketStartTimeMillis[i] = System.currentTimeMillis(); - } - - this.currentBucket = 0; - this.lastRotateTimestampMillis = System.currentTimeMillis(); - this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(timeWindowSeconds) / bucketNum; + this.slidingWindow = new LongAdderSlidingWindow(bucketNum, TimeUnit.SECONDS.toMillis(timeWindowSeconds)); } - public synchronized double get() { - return rotate(); + public double get() { + double result = 0.0; + List windows = this.slidingWindow.values(); + for (LongAdder window : windows) { + result += window.sum(); + } + return result; } public long bucketLivedSeconds() { - return TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - bucketStartTimeMillis[currentBucket]); + return TimeUnit.MILLISECONDS.toSeconds(this.slidingWindow.values().size() * this.slidingWindow.getPaneIntervalInMs()); } - public synchronized void increment() { + public void increment() { this.increment(1L); } - public synchronized void increment(Long step) { - rotate(); - for (int i = 0; i < ringBuffer.length; i++) { - ringBuffer[i] = ringBuffer[i] + step; - } + public void increment(Long step) { + this.slidingWindow.currentPane().getValue().add(step); } - public synchronized void decrement() { + public void decrement() { this.decrement(1L); } - public synchronized void decrement(Long step) { - rotate(); - for (int i = 0; i < ringBuffer.length; i++) { - ringBuffer[i] = ringBuffer[i] - step; - } + public void decrement(Long step) { + this.slidingWindow.currentPane().getValue().add(-step); } - private Long rotate() { - long timeSinceLastRotateMillis = System.currentTimeMillis() - lastRotateTimestampMillis; - while (timeSinceLastRotateMillis > durationBetweenRotatesMillis) { - ringBuffer[currentBucket] = 0L; - bucketStartTimeMillis[currentBucket] = lastRotateTimestampMillis + durationBetweenRotatesMillis; - if (++currentBucket >= ringBuffer.length) { - currentBucket = 0; - } - timeSinceLastRotateMillis -= durationBetweenRotatesMillis; - lastRotateTimestampMillis += durationBetweenRotatesMillis; + /** + * Sliding window of type LongAdder. + */ + private static class LongAdderSlidingWindow extends SlidingWindow { + + public LongAdderSlidingWindow(int sampleCount, long intervalInMs) { + super(sampleCount, intervalInMs); + } + + @Override + public LongAdder newEmptyValue(long timeMillis) { + return new LongAdder(); + } + + @Override + protected Pane resetPaneTo(final Pane pane, long startTime) { + pane.setStartInMs(startTime); + pane.getValue().reset(); + return pane; } - return ringBuffer[currentBucket]; } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantile.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantile.java index 86249c88a2..823024344d 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantile.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantile.java @@ -19,57 +19,60 @@ package org.apache.dubbo.metrics.aggregate; import com.tdunning.math.stats.TDigest; +import java.util.List; import java.util.concurrent.TimeUnit; /** * Wrapper around TDigest. - *

- * Maintains a ring buffer of TDigest to provide quantiles over a sliding windows of time. */ public class TimeWindowQuantile { + private final double compression; - private final TDigest[] ringBuffer; - private int currentBucket; - private long lastRotateTimestampMillis; - private final long durationBetweenRotatesMillis; + + private final DigestSlidingWindow slidingWindow; public TimeWindowQuantile(double compression, int bucketNum, int timeWindowSeconds) { this.compression = compression; - this.ringBuffer = new TDigest[bucketNum]; - for (int i = 0; i < bucketNum; i++) { - this.ringBuffer[i] = TDigest.createDigest(compression); - } - - this.currentBucket = 0; - this.lastRotateTimestampMillis = System.currentTimeMillis(); - this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(timeWindowSeconds) / bucketNum; + this.slidingWindow = new DigestSlidingWindow(compression, bucketNum, TimeUnit.SECONDS.toMillis(timeWindowSeconds)); } - public synchronized double quantile(double q) { - TDigest currentBucket = rotate(); - + public double quantile(double q) { + TDigest mergeDigest = TDigest.createDigest(compression); + List validWindows = this.slidingWindow.values(); + for (TDigest window : validWindows) { + mergeDigest.add(window); + } // This may return Double.NaN, and it's correct behavior. // see: https://github.com/prometheus/client_golang/issues/85 - return currentBucket.quantile(q); + return mergeDigest.quantile(q); } - public synchronized void add(double value) { - rotate(); - for (TDigest bucket : ringBuffer) { - bucket.add(value); - } + public void add(double value) { + this.slidingWindow.currentPane().getValue().add(value); } - private TDigest rotate() { - long timeSinceLastRotateMillis = System.currentTimeMillis() - lastRotateTimestampMillis; - while (timeSinceLastRotateMillis > durationBetweenRotatesMillis) { - ringBuffer[currentBucket] = TDigest.createDigest(compression); - if (++currentBucket >= ringBuffer.length) { - currentBucket = 0; - } - timeSinceLastRotateMillis -= durationBetweenRotatesMillis; - lastRotateTimestampMillis += durationBetweenRotatesMillis; + /** + * Sliding window of type TDigest. + */ + private static class DigestSlidingWindow extends SlidingWindow { + + private final double compression; + + public DigestSlidingWindow(double compression, int sampleCount, long intervalInMs) { + super(sampleCount, intervalInMs); + this.compression = compression; + } + + @Override + public TDigest newEmptyValue(long timeMillis) { + return TDigest.createDigest(compression); + } + + @Override + protected Pane resetPaneTo(final Pane pane, long startTime) { + pane.setStartInMs(startTime); + pane.setValue(TDigest.createDigest(compression)); + return pane; } - return ringBuffer[currentBucket]; } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/PaneTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/PaneTest.java new file mode 100644 index 0000000000..bbce54ec84 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/PaneTest.java @@ -0,0 +1,72 @@ +/* + * 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.metrics.aggregate; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.atomic.LongAdder; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class PaneTest { + + @Test + void testIntervalInMs() { + Pane pane = mock(Pane.class); + when(pane.getIntervalInMs()).thenReturn(100L); + assertEquals(100L, pane.getIntervalInMs()); + } + + @Test + void testStartInMs() { + Pane pane = mock(Pane.class); + long startTime = System.currentTimeMillis(); + when(pane.getStartInMs()).thenReturn(startTime); + assertEquals(startTime, pane.getStartInMs()); + } + + @Test + void testEndInMs() { + long startTime = System.currentTimeMillis(); + Pane pane = new Pane<>(10, startTime, new Object()); + assertEquals(startTime + 10, pane.getEndInMs()); + } + + @Test + @SuppressWarnings("unchecked") + void testValue() { + Pane pane = mock(Pane.class); + LongAdder count = new LongAdder(); + when(pane.getValue()).thenReturn(count); + assertEquals(count, pane.getValue()); + when(pane.getValue()).thenReturn(null); + assertNotEquals(count, pane.getValue()); + } + + @Test + void testIsTimeInWindow() { + Pane pane = new Pane<>(10, System.currentTimeMillis(), new Object()); + assertTrue(pane.isTimeInWindow(System.currentTimeMillis())); + assertFalse(pane.isTimeInWindow(System.currentTimeMillis() + 10)); + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/SlidingWindowTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/SlidingWindowTest.java new file mode 100644 index 0000000000..58b74b604f --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/SlidingWindowTest.java @@ -0,0 +1,137 @@ +/* + * 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.metrics.aggregate; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.atomic.LongAdder; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SlidingWindowTest { + + static final int paneCount = 10; + + static final long intervalInMs = 2000; + + TestSlidingWindow window; + + @BeforeEach + void setup() { + window = new TestSlidingWindow(paneCount, intervalInMs); + } + + @Test + void testCurrentPane() { + assertNull(window.currentPane(/* invalid time*/-1L)); + long timeInMs = System.currentTimeMillis(); + Pane currentPane = window.currentPane(timeInMs); + assertNotNull(currentPane); + // reuse test + assertEquals(currentPane, + window.currentPane(1 + timeInMs + window.getPaneIntervalInMs() * paneCount)); + } + + @Test + void testGetPaneData() { + assertNull(window.getPaneValue(/* invalid time*/-1L)); + window.currentPane(); + assertNotNull(window.getPaneValue(System.currentTimeMillis())); + assertNull(window.getPaneValue(System.currentTimeMillis() + window.getPaneIntervalInMs())); + } + + @Test + void testNewEmptyValue() { + assertEquals(0L, window.newEmptyValue(System.currentTimeMillis()).sum()); + } + + @Test + void testResetPaneTo() { + Pane currentPane = window.currentPane(); + currentPane.getValue().add(2); + currentPane.getValue().add(1); + assertEquals(3, currentPane.getValue().sum()); + window.resetPaneTo(currentPane, System.currentTimeMillis()); + assertEquals(0, currentPane.getValue().sum()); + currentPane.getValue().add(1); + assertEquals(1, currentPane.getValue().sum()); + } + + @Test + void testCalculatePaneStart() { + long time = System.currentTimeMillis(); + assertTrue(window.calculatePaneStart(time) <= time); + assertTrue(time < window.calculatePaneStart(time) + window.getPaneIntervalInMs()); + } + + @Test + void testIsPaneDeprecated() { + Pane currentPane = window.currentPane(); + currentPane.setStartInMs(1000000L); + assertTrue(window.isPaneDeprecated(currentPane)); + } + + @Test + void testList() { + window.currentPane(); + assertTrue(0 < window.list().size()); + } + + @Test + void testValues() { + window.currentPane().getValue().add(10); + long sum = 0; + for (LongAdder value : window.values()) { + sum += value.sum(); + } + assertEquals(10, sum); + } + + @Test + void testGetIntervalInMs() { + assertEquals(intervalInMs, window.getIntervalInMs()); + } + + @Test + void testGetPaneIntervalInMs() { + assertEquals(intervalInMs / paneCount, window.getPaneIntervalInMs()); + } + + private static class TestSlidingWindow extends SlidingWindow { + + public TestSlidingWindow(int paneCount, long intervalInMs) { + super(paneCount, intervalInMs); + } + + @Override + public LongAdder newEmptyValue(long timeMillis) { + return new LongAdder(); + } + + @Override + protected Pane resetPaneTo(Pane pane, long startInMs) { + pane.setStartInMs(startInMs); + pane.getValue().reset(); + return pane; + } + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java index 4ff6758020..6cac0d60d8 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java @@ -24,7 +24,7 @@ class TimeWindowCounterTest { @Test void test() throws Exception { - TimeWindowCounter counter = new TimeWindowCounter(12, 1); + TimeWindowCounter counter = new TimeWindowCounter(10, 1); counter.increment(); Assertions.assertEquals(counter.get(), 1); counter.decrement(); @@ -34,4 +34,4 @@ class TimeWindowCounterTest { Assertions.assertEquals(counter.get(), 0); Assertions.assertTrue(counter.bucketLivedSeconds() < 1); } -} \ No newline at end of file +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java index 7e1d416652..36ee690b01 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java @@ -24,7 +24,7 @@ class TimeWindowQuantileTest { @Test void test() throws Exception { - TimeWindowQuantile quantile = new TimeWindowQuantile(100, 12, 1); + TimeWindowQuantile quantile = new TimeWindowQuantile(100, 10, 1); for (int i = 1; i <= 100; i++) { quantile.add(i); } @@ -34,4 +34,4 @@ class TimeWindowQuantileTest { Thread.sleep(1000); Assertions.assertEquals(quantile.quantile(0.99), Double.NaN); } -} \ No newline at end of file +} From 10681947b664890870c661733df8a18c989092be Mon Sep 17 00:00:00 2001 From: songxiaosheng <81170548+songxiaosheng@users.noreply.github.com> Date: Thu, 2 Mar 2023 07:03:32 +0800 Subject: [PATCH 053/144] add core thread pool meter (#11693) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix MetericsService resource location bug * :art:为jvm指标增加dubbo应用名称 * :art: jvm meter add application name label * fix unit test failure * :bug: fix metrics filter path * :bento: :bento: provider collector to FrameworkModel scope * :bento:provider collector to FrameworkModel scope * :bento:provider collector to FrameworkModel scope * :bento:provider collector to FrameworkModel scope * :bento:provider collector to FrameworkModel scope * :bento:provider collector to FrameworkModel scope * :bento:provider collector to FrameworkModel scope * resolve pr conflicts * resolve pr conflicts * :sparkles: add application meter and fix pull delay * :sparkles: add application meter and fix pull delay * :sparkles: add application meter and fix pull delay * :sparkles: add application meter and fix pull delay * :sparkles: add application meter and fix pull delay * ✨ add application meter and fix pull delay * ✨ add application meter and fix pull delay * :white_check_mark: fix unit test error * Optimize the data synchronization of dubbo indicators to the third-party (spring boot) registry without refreshing data * :recycle:refact metrics key and meter unit * The indicator of the application is removed first, and then the switch judgment is added for that indicator of the application * add core thread pool metric --------- Co-authored-by: dongdong.yang --- .../sample/ThreadPoolMetricsSampler.java | 25 +++++++++++++++++-- .../metrics/filter/MetricsFilterTest.java | 10 +++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java index 7495b5a884..b83e111706 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java @@ -18,12 +18,15 @@ package org.apache.dubbo.metrics.collector.sample; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.store.DataStore; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.ThreadPoolMetric; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; +import org.apache.dubbo.rpc.model.ApplicationModel; + import java.util.ArrayList; import java.util.List; @@ -34,6 +37,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; +import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY; + import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION; import static org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL; @@ -43,6 +48,7 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { private final DefaultMetricsCollector collector; private FrameworkExecutorRepository frameworkExecutorRepository; + private DataStore dataStore; private final Map sampleThreadPoolExecutor = new ConcurrentHashMap<>(); public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) { @@ -82,15 +88,30 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { } private void registryDefaultSampleThreadPoolExecutor() { + ApplicationModel applicationModel = collector.getApplicationModel(); + if (applicationModel == null) { + return; + } try { if (this.frameworkExecutorRepository == null) { - this.frameworkExecutorRepository = collector.getApplicationModel() - .getFrameworkModel().getBeanFactory() + this.frameworkExecutorRepository = collector.getApplicationModel().getBeanFactory() .getBean(FrameworkExecutorRepository.class); } } catch (Exception ex) { logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", "ThreadPoolMetricsSampler! frameworkExecutorRepository non-init"); } + if (this.dataStore == null) { + this.dataStore = collector.getApplicationModel().getExtensionLoader(DataStore.class).getDefaultExtension(); + } + if (dataStore != null) { + Map executors = dataStore.get(EXECUTOR_SERVICE_COMPONENT_KEY); + for (Map.Entry entry : executors.entrySet()) { + ExecutorService executor = (ExecutorService) entry.getValue(); + if (executor instanceof ThreadPoolExecutor) { + this.addExecutors(entry.getKey(), executor); + } + } + } if (this.frameworkExecutorRepository != null) { this.addExecutors("sharedExecutor", frameworkExecutorRepository.getSharedExecutor()); this.addExecutors("mappingRefreshingExecutor", frameworkExecutorRepository.getMappingRefreshingExecutor()); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java index 41b92f1bd9..0dcf43c04b 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java @@ -41,6 +41,7 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.stream.Collectors; @@ -73,6 +74,8 @@ class MetricsFilterTest { private static final String VERSION = "1.0.0"; private String side; + private AtomicBoolean initApplication = new AtomicBoolean(false); + @BeforeEach public void setup() { @@ -87,6 +90,10 @@ class MetricsFilterTest { filter = new MetricsFilter(); collector = applicationModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class); + if(!initApplication.get()) { + collector.collectApplication(applicationModel); + initApplication.set(true); + } filter.setApplicationModel(applicationModel); side = CommonConstants.CONSUMER; invocation.setInvoker(new TestMetricsInvoker(side)); @@ -107,6 +114,7 @@ class MetricsFilterTest { filter.invoke(invoker, invocation); Map metricsMap = getMetricsMap(); + metricsMap.remove(MetricsKey.APPLICATION_METRIC_INFO.getName()); Assertions.assertTrue(metricsMap.isEmpty()); } @@ -277,7 +285,7 @@ class MetricsFilterTest { } private void testClusterFilterError(int errorCode,MetricsKey metricsKey){ - setup(); +// setup(); collector.setCollectEnabled(true); given(invoker.invoke(invocation)).willThrow(new RpcException(errorCode)); initParam(); From a293e7e7c86fc7b179159634cde9c32c752174fb Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 2 Mar 2023 20:14:01 +0800 Subject: [PATCH 054/144] Implement service-level payload (#11517) --- .../common/constants/CommonConstants.java | 2 ++ .../dubbo/config/AbstractServiceConfig.java | 12 ++++++++ .../dubbo/config/annotation/DubboService.java | 5 ++++ .../src/main/resources/META-INF/dubbo.xsd | 10 +++---- .../dubbo/metadata/MetadataInfoTest.java | 17 +++++++++++ .../dubbo/remoting/exchange/Request.java | 16 +++++++++-- .../exchange/codec/ExchangeCodec.java | 2 +- .../support/header/HeaderExchangeChannel.java | 17 +++++++---- .../remoting/transport/AbstractCodec.java | 13 +++++++++ .../dubbo/remoting/exchange/RequestTest.java | 2 ++ .../remoting/transport/AbstractCodecTest.java | 28 +++++++++++++++++++ .../protocol/dubbo/ChannelWrappedInvoker.java | 17 +++++++++-- .../rpc/protocol/dubbo/DubboInvoker.java | 19 +++++++++++-- 13 files changed, 142 insertions(+), 18 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java index a356b4cae6..62ff4beeeb 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java @@ -619,4 +619,6 @@ public interface CommonConstants { String ENCODE_IN_IO_THREAD_KEY = "encode.in.io"; boolean DEFAULT_ENCODE_IN_IO_THREAD = false; + + String PAYLOAD = "payload"; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java index 474c362cfe..6b5545c62f 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java @@ -150,6 +150,11 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig { */ private Executor executor; + /** + * Payload max length. + */ + private Integer payload; + public AbstractServiceConfig() { } @@ -377,4 +382,11 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig { return executor; } + public Integer getPayload() { + return payload; + } + + public void setPayload(Integer payload) { + this.payload = payload; + } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java index c13c6c97e9..d2d3cb69f0 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java @@ -323,4 +323,9 @@ public @interface DubboService { * @return */ String executor() default ""; + + /** + * Payload max length. + */ + String payload() default ""; } diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index 457ebfe6d3..9241700cd4 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -371,6 +371,11 @@ + + + + + @@ -1594,11 +1599,6 @@ - - - - - diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java index 544aaa5721..3d0177ef78 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java @@ -36,6 +36,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PAYLOAD; import static org.apache.dubbo.metadata.RevisionResolver.EMPTY_REVISION; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -66,6 +67,12 @@ class MetadataInfoTest { "&metadata-type=remote&methods=sayHello&sayHello.timeout=7000&pid=36621&release=&revision=1.0.0&service-name-mapping=true" + "&side=provider&timeout=5000×tamp=1629970068002&version=1.0.0¶ms-filter=-customized,excluded"); + private static URL url4 = URL.valueOf("dubbo://30.225.21.30:20880/org.apache.dubbo.registry.service.DemoService?" + + "REGISTRY_CLUSTER=registry1&anyhost=true&application=demo-provider2&delay=5000&deprecated=false&dubbo=2.0.2" + + "&dynamic=true&generic=false&group=greeting&interface=org.apache.dubbo.registry.service.DemoService" + + "&metadata-type=remote&methods=sayHello&sayHello.timeout=7000&pid=36621&release=&revision=1.0.0&service-name-mapping=true" + + "&side=provider&timeout=5000×tamp=1629970068002&version=1.0.0¶ms-filter=-customized,excluded&payload=1024"); + @Test void testEmptyRevision() { MetadataInfo metadataInfo = new MetadataInfo("demo"); @@ -215,4 +222,14 @@ class MetadataInfoTest { assertNull(ret.get("content")); assertNull(ret.get("rawMetadataInfo")); } + + @Test + void testPayload() { + MetadataInfo metadataInfo = new MetadataInfo("demo"); + + metadataInfo.addService(url4); + MetadataInfo.ServiceInfo serviceInfo4 = metadataInfo.getServiceInfo(url4.getProtocolServiceKey()); + assertNotNull(serviceInfo4); + assertEquals("1024", serviceInfo4.getParameter(PAYLOAD)); + } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Request.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Request.java index d75a21a323..4e47aed49d 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Request.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Request.java @@ -39,6 +39,8 @@ public class Request { private boolean mBroken = false; + private int mPayload; + private Object mData; public Request() { @@ -61,7 +63,7 @@ public class Request { try { return data.toString(); - } catch (Throwable e) { + } catch (Exception e) { return ""; } } @@ -107,6 +109,14 @@ public class Request { this.mBroken = mBroken; } + public int getPayload() { + return mPayload; + } + + public void setPayload(int mPayload) { + this.mPayload = mPayload; + } + public Object getData() { return mData; } @@ -131,6 +141,7 @@ public class Request { copy.mTwoWay = this.mTwoWay; copy.mEvent = this.mEvent; copy.mBroken = this.mBroken; + copy.mPayload = this.mPayload; copy.mData = this.mData; return copy; } @@ -141,12 +152,13 @@ public class Request { copy.mTwoWay = this.mTwoWay; copy.mEvent = this.mEvent; copy.mBroken = this.mBroken; + copy.mPayload = this.mPayload; return copy; } @Override public String toString() { return "Request [id=" + mId + ", version=" + mVersion + ", twoWay=" + mTwoWay + ", event=" + mEvent - + ", broken=" + mBroken + ", data=" + (mData == this ? "this" : safeToString(mData)) + "]"; + + ", broken=" + mBroken + ", mPayload=" + mPayload + ", data=" + (mData == this ? "this" : safeToString(mData)) + "]"; } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java index 9937c573fb..7a92b0202a 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java @@ -273,7 +273,7 @@ public class ExchangeCodec extends TelnetCodec { bos.flush(); bos.close(); int len = bos.writtenBytes(); - checkPayload(channel, len); + checkPayload(channel, req.getPayload(), len); Bytes.int2bytes(len, header, 12); // write diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java index 787130ed56..ab576db76a 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java @@ -126,11 +126,16 @@ final class HeaderExchangeChannel implements ExchangeChannel { if (closed) { throw new RemotingException(this.getLocalAddress(), null, "Failed to send request " + request + ", cause: The channel " + this + " is closed!"); } - // create request. - Request req = new Request(); - req.setVersion(Version.getProtocolVersion()); - req.setTwoWay(true); - req.setData(request); + Request req; + if (request instanceof Request) { + req = (Request) request; + } else { + // create request. + req = new Request(); + req.setVersion(Version.getProtocolVersion()); + req.setTwoWay(true); + req.setData(request); + } DefaultFuture future = DefaultFuture.newFuture(channel, req, timeout, executor); try { channel.send(req); @@ -156,7 +161,7 @@ final class HeaderExchangeChannel implements ExchangeChannel { // graceful close DefaultFuture.closeChannel(channel); channel.close(); - } catch (Throwable e) { + } catch (Exception e) { logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e); } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java index aabf6ee3b0..144e352bb2 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractCodec.java @@ -63,6 +63,19 @@ public abstract class AbstractCodec implements Codec2, ScopeModelAware { } } + protected static void checkPayload(Channel channel, int payload, long size) throws IOException { + if (payload <= 0) { + payload = getPayload(channel); + } + boolean overPayload = isOverPayload(payload, size); + if (overPayload) { + ExceedPayloadLimitException e = new ExceedPayloadLimitException( + "Data length too large: " + size + ", max payload: " + payload + ", channel: " + channel); + logger.error(TRANSPORT_EXCEED_PAYLOAD_LIMIT, "", "", e.getMessage(), e); + throw e; + } + } + protected static int getPayload(Channel channel) { if (channel != null && channel.getUrl() != null) { return channel.getUrl().getParameter(Constants.PAYLOAD_KEY, Constants.DEFAULT_PAYLOAD); diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/RequestTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/RequestTest.java index f0a8988ee7..138ffd8955 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/RequestTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/RequestTest.java @@ -29,6 +29,7 @@ class RequestTest { request.setVersion("1.0.0"); request.setEvent(true); request.setData("data"); + request.setPayload(1024); Assertions.assertTrue(request.isTwoWay()); Assertions.assertTrue(request.isBroken()); @@ -36,6 +37,7 @@ class RequestTest { Assertions.assertEquals(request.getVersion(), "1.0.0"); Assertions.assertEquals(request.getData(), "data"); Assertions.assertTrue(request.getId() >= 0); + Assertions.assertEquals(1024, request.getPayload()); request.setHeartbeat(true); Assertions.assertTrue(request.isHeartbeat()); diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java index 7dd38a60d2..973af20a58 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/transport/AbstractCodecTest.java @@ -55,6 +55,34 @@ class AbstractCodecTest { verify(channel, VerificationModeFactory.atLeastOnce()).getUrl(); } + @Test + void testCheckProviderPayload() throws Exception { + Channel channel = mock(Channel.class); + given(channel.getUrl()).willReturn(URL.valueOf("dubbo://1.1.1.1")); + + AbstractCodec.checkPayload(channel, 1024 * 1024 + 1, 1024 * 1024); + + try { + AbstractCodec.checkPayload(channel, 1024 * 1024, 1024 * 1024); + } catch (IOException expected) { + assertThat(expected.getMessage(), allOf( + containsString("Data length too large: "), + containsString("max payload: " + 1024 * 1024) + )); + } + + try { + AbstractCodec.checkPayload(channel, 0, 15 * 1024 * 1024); + } catch (IOException expected) { + assertThat(expected.getMessage(), allOf( + containsString("Data length too large: "), + containsString("max payload: " + 8 * 1024 * 1024) + )); + } + + verify(channel, VerificationModeFactory.atLeastOnce()).getUrl(); + } + @Test void tesCheckPayloadMinusPayloadNoLimit() throws Exception { Channel channel = mock(Channel.class); diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java index 120c3f8d42..1b1b9a5999 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java @@ -17,11 +17,13 @@ package org.apache.dubbo.rpc.protocol.dubbo; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.Version; import org.apache.dubbo.remoting.Channel; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.TimeoutException; import org.apache.dubbo.remoting.exchange.ExchangeClient; +import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeClient; import org.apache.dubbo.remoting.transport.ClientDelegate; import org.apache.dubbo.rpc.AppResponse; @@ -38,6 +40,7 @@ import java.util.concurrent.CompletableFuture; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PAYLOAD; import static org.apache.dubbo.remoting.Constants.SENT_KEY; import static org.apache.dubbo.rpc.Constants.TOKEN_KEY; import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY; @@ -60,18 +63,28 @@ class ChannelWrappedInvoker extends AbstractInvoker { } @Override + @SuppressWarnings("deprecation") protected Result doInvoke(Invocation invocation) throws Throwable { RpcInvocation inv = (RpcInvocation) invocation; // use interface's name as service path to export if it's not found on client side inv.setAttachment(PATH_KEY, getInterface().getName()); inv.setAttachment(CALLBACK_SERVICE_KEY, serviceKey); + Integer payload = getUrl().getParameter(PAYLOAD, Integer.class); + + Request request = new Request(); + if (payload != null) { + request.setPayload(payload); + } + request.setData(inv); + request.setVersion(Version.getProtocolVersion()); + try { if (RpcUtils.isOneway(getUrl(), inv)) { // may have concurrency issue - currentClient.send(inv, getUrl().getMethodParameter(invocation.getMethodName(), SENT_KEY, false)); + currentClient.send(request, getUrl().getMethodParameter(invocation.getMethodName(), SENT_KEY, false)); return AsyncRpcResult.newDefaultAsyncResult(invocation); } else { - CompletableFuture appResponseFuture = currentClient.request(inv).thenApply(obj -> (AppResponse) obj); + CompletableFuture appResponseFuture = currentClient.request(request).thenApply(AppResponse.class::cast); return new AsyncRpcResult(appResponseFuture, inv); } } catch (RpcException e) { diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java index 8204d3b033..91d0976ac8 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java @@ -17,12 +17,14 @@ package org.apache.dubbo.rpc.protocol.dubbo; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.Version; import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.utils.AtomicPositiveInteger; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.TimeoutException; import org.apache.dubbo.remoting.exchange.ExchangeClient; +import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.FutureContext; @@ -45,6 +47,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PAYLOAD; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_CLOSE_CLIENT; import static org.apache.dubbo.rpc.Constants.TOKEN_KEY; @@ -99,14 +102,26 @@ public class DubboInvoker extends AbstractInvoker { } invocation.setAttachment(TIMEOUT_KEY, String.valueOf(timeout)); + + Integer payload = getUrl().getParameter(PAYLOAD, Integer.class); + + Request request = new Request(); + if (payload != null) { + request.setPayload(payload); + } + request.setData(inv); + request.setVersion(Version.getProtocolVersion()); + if (isOneway) { boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false); - currentClient.send(inv, isSent); + request.setTwoWay(false); + currentClient.send(request, isSent); return AsyncRpcResult.newDefaultAsyncResult(invocation); } else { + request.setTwoWay(true); ExecutorService executor = getCallbackExecutor(getUrl(), inv); CompletableFuture appResponseFuture = - currentClient.request(inv, timeout, executor).thenApply(obj -> (AppResponse) obj); + currentClient.request(request, timeout, executor).thenApply(AppResponse.class::cast); // save for 2.6.x compatibility, for example, TraceFilter in Zipkin uses com.alibaba.xxx.FutureAdapter FutureContext.getContext().setCompatibleFuture(appResponseFuture); AsyncRpcResult result = new AsyncRpcResult(appResponseFuture, inv); From 3902dc7b363ff047b57b528fe383db956d99e5c7 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 2 Mar 2023 20:22:44 +0800 Subject: [PATCH 055/144] Rt metrics bugfix (#11694) --- .../sample/MethodMetricsSampler.java | 16 ++++++--- .../collector/sample/MetricsCountSampler.java | 5 +-- .../sample/SimpleMetricsCountSampler.java | 35 +++++++++---------- .../metrics/sampler/CountSamplerTest.java | 17 +++++---- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java index 186a691f90..b5a9af0157 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java @@ -31,6 +31,7 @@ import org.apache.dubbo.rpc.Invocation; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicLong; import java.util.function.ToDoubleFunction; import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; @@ -64,7 +65,12 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler getGaugeMetricSample(key, metric, RT, count, Number::longValue))); + this.collectRT(new MetricSampleFactory>() { + @Override + public GaugeMetricSample newInstance(MetricsKey key, MethodMetric metric, T value, ToDoubleFunction apply) { + return getGaugeMetricSample(key, metric, RT, value, apply); + } + })); return metricSamples; } @@ -84,11 +90,11 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler getGaugeMetricSample(MetricsKey metricsKey, + private GaugeMetricSample getGaugeMetricSample(MetricsKey metricsKey, MethodMetric methodMetric, MetricsCategory metricsCategory, - Number value, - ToDoubleFunction apply) { + T value, + ToDoubleFunction apply) { return new GaugeMetricSample<>( metricsKey.getNameByType(methodMetric.getSide()), metricsKey.getDescription(), @@ -101,6 +107,6 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler void count(List list, MetricsEvent.Type eventType, MetricsKey metricsKey) { getCount(eventType).filter(e -> !e.isEmpty()) .ifPresent(map -> map.forEach((k, v) -> - list.add(getGaugeMetricSample(metricsKey, k, REQUESTS, v, value -> v.get())))); + list.add(getGaugeMetricSample(metricsKey, k, REQUESTS, v, AtomicLong::get)))); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java index 3fbd3da676..353a04fe99 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MetricsCountSampler.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.ToDoubleFunction; public interface MetricsCountSampler extends MetricsSampler { @@ -44,9 +45,9 @@ public interface MetricsCountSampler extends MetricsSamp List collectRT(MetricSampleFactory factory); - List collectRT(MetricSampleFactory factory,K metricName); + List collectRT(MetricSampleFactory factory, K metricName); interface MetricSampleFactory { - R newInstance(MetricsKey key, M metric, Long count); + R newInstance(MetricsKey key, M metric, T value, ToDoubleFunction apply); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java index 7580cee6c3..6fd84204e0 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/SimpleMetricsCountSampler.java @@ -50,9 +50,9 @@ public abstract class SimpleMetricsCountSampler private final ConcurrentMap minRT = new ConcurrentHashMap<>(); private final ConcurrentMap maxRT = new ConcurrentHashMap<>(); - private final ConcurrentMap> rtGroupSample = new ConcurrentHashMap<>(); - private final ConcurrentMap> groupMinRT = new ConcurrentHashMap<>(); - private final ConcurrentMap> groupMaxRT = new ConcurrentHashMap<>(); + private final ConcurrentMap> rtGroupSample = new ConcurrentHashMap<>(); + private final ConcurrentMap> groupMinRT = new ConcurrentHashMap<>(); + private final ConcurrentMap> groupMaxRT = new ConcurrentHashMap<>(); @Override public void inc(S source, K metricName) { @@ -85,6 +85,7 @@ public abstract class SimpleMetricsCountSampler return true; }); } + @Override public void addRT(S source, Long rt) { MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); @@ -121,7 +122,7 @@ public abstract class SimpleMetricsCountSampler @Override public void addRT(S source, K metricName, Long rt) { - MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); + MetricsCountSampleConfigurer sampleConfigure = new MetricsCountSampleConfigurer<>(); sampleConfigure.setSource(source); sampleConfigure.setMetricsName(metricName); @@ -135,7 +136,7 @@ public abstract class SimpleMetricsCountSampler ConcurrentHashMap calculator = new ConcurrentHashMap<>(); calculator.put(metric, new AtomicLongArray(4)); - rtGroupSample.put(metricName,calculator); + rtGroupSample.put(metricName, calculator); nameToCalculator = rtGroupSample.get(metricName); } @@ -174,32 +175,30 @@ public abstract class SimpleMetricsCountSampler return collect(factory, rtSample, this.minRT, this.maxRT); } - public List collectRT(MetricSampleFactory factory,K metricName){ - return collect(factory, rtGroupSample.get(metricName), groupMinRT.get(metricName), - groupMaxRT.get(metricName)); + @Override + public List collectRT(MetricSampleFactory factory, K metricName) { + return collect(factory, rtGroupSample.get(metricName), groupMinRT.get(metricName), groupMaxRT.get(metricName)); } private List collect(MetricSampleFactory factory, - ConcurrentMap rtSample, - ConcurrentMap min, - ConcurrentMap max){ + ConcurrentMap rtSample, + ConcurrentMap min, + ConcurrentMap max) { final List result = new ArrayList<>(); rtSample.forEach((k, v) -> { // lastRT - result.add(factory.newInstance(MetricsKey.METRIC_RT_LAST, k, v.get(0))); + result.add(factory.newInstance(MetricsKey.METRIC_RT_LAST, k, v, value -> value.get(0))); // totalRT - long totalRT = v.get(1); - long rtCount = v.get(2); - result.add(factory.newInstance(MetricsKey.METRIC_RT_SUM, k, totalRT)); + result.add(factory.newInstance(MetricsKey.METRIC_RT_SUM, k, v, value -> value.get(1))); // avgRT - result.add(factory.newInstance(MetricsKey.METRIC_RT_AVG, k, Math.floorDiv(totalRT, rtCount))); + result.add(factory.newInstance(MetricsKey.METRIC_RT_AVG, k, v, value -> Math.floorDiv(value.get(1), value.get(2)))); }); min.forEach((k, v) -> - result.add(factory.newInstance(MetricsKey.METRIC_RT_MIN, k, v.get()))); + result.add(factory.newInstance(MetricsKey.METRIC_RT_MIN, k, v, LongAccumulator::get))); max.forEach((k, v) -> - result.add(factory.newInstance(MetricsKey.METRIC_RT_MAX, k, v.get()))); + result.add(factory.newInstance(MetricsKey.METRIC_RT_MAX, k, v, LongAccumulator::get))); return result; } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java index b1d701c903..d592176515 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java @@ -18,10 +18,9 @@ package org.apache.dubbo.metrics.sampler; import org.apache.dubbo.metrics.collector.sample.MetricsCountSampleConfigurer; +import org.apache.dubbo.metrics.collector.sample.MetricsCountSampler; import org.apache.dubbo.metrics.collector.sample.SimpleMetricsCountSampler; -import org.apache.dubbo.metrics.model.MethodMetric; import org.apache.dubbo.metrics.model.Metric; -import org.apache.dubbo.metrics.model.MetricsCategory; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; @@ -35,7 +34,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.function.Supplier; +import java.util.function.ToDoubleFunction; import java.util.stream.Collectors; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; @@ -117,14 +116,18 @@ public class CountSamplerTest { @NotNull @SuppressWarnings("rawtypes") private Map getCollect(RTType rtType) { - List metricSamples = sampler.collectRT((key, metric, count) -> - new GaugeMetricSample<>(key.formatName("consumer"), metric.getTags(), RT, count, __ -> count), rtType); + List> metricSamples = sampler.collectRT( + new MetricsCountSampler.MetricSampleFactory>() { + @Override + public GaugeMetricSample newInstance(MetricsKey key, RequestMethodMetrics metric, T value, ToDoubleFunction apply) { + return new GaugeMetricSample<>(key.formatName("consumer"), metric.getTags(), RT, value, apply); + } + }, rtType); return metricSamples.stream() .collect(Collectors.toMap(MetricSample::getName, v -> v)); } - public class RequestMetricsCountSampler extends SimpleMetricsCountSampler { @Override @@ -152,7 +155,7 @@ public class CountSamplerTest { } } - static enum RTType { + enum RTType { METHOD_REQUEST, APPLICATION } From ef29a41e58497a2d0a64d52ba1da5e9758a82e8f Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Fri, 3 Mar 2023 06:42:00 +0800 Subject: [PATCH 056/144] Optimize the code of metrics registry&metadata (#11659) * registry&metadata opt * add licence * fix sonar * fix enable failed * fix enable failed * add registry&metadata in spring/xsd --------- Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../src/main/resources/META-INF/dubbo.xsd | 12 ++ .../model/container/AtomicLongContainer.java | 35 ++++++ .../container/LongAccumulatorContainer.java | 28 +++++ .../model/container/LongContainer.java | 112 ++++++++++++++++++ .../collector/stat/MetadataStatComposite.java | 96 +-------------- .../MetadataMetricsCollectorTest.java | 14 +-- .../metadata/MetadataStatCompositeTest.java | 67 +++++++++++ .../collector/RegistryMetricsCollector.java | 6 +- .../collector/stat/RegistryStatComposite.java | 95 +-------------- .../collector/stat/ServiceKeyMetric.java | 4 - .../RegistryMetricsCollectorTest.java | 7 +- .../collector/RegistryStatCompositeTest.java | 67 +++++++++++ .../metrics/model/MethodMetricTest.java | 79 ------------ .../model/sample/GaugeMetricSampleTest.java | 67 ----------- 14 files changed, 341 insertions(+), 348 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/AtomicLongContainer.java create mode 100644 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongAccumulatorContainer.java create mode 100644 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongContainer.java rename dubbo-metrics/dubbo-metrics-metadata/src/test/java/{metrics/metrics/collector => org/apache/dubbo/metrics/metadata}/MetadataMetricsCollectorTest.java (95%) create mode 100644 dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java delete mode 100644 dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java delete mode 100644 dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index 9241700cd4..2ff4ebddbd 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -1027,6 +1027,18 @@ + + + + + + + + + + + + diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/AtomicLongContainer.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/AtomicLongContainer.java new file mode 100644 index 0000000000..45a1920bb1 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/AtomicLongContainer.java @@ -0,0 +1,35 @@ +/* + * 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.metrics.model.container; + +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.BiConsumer; + +public class AtomicLongContainer extends LongContainer { + + public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper) { + super(metricsKeyWrapper, AtomicLong::new, (responseTime, longAccumulator) -> longAccumulator.set(responseTime)); + } + + public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper, BiConsumer consumerFunc) { + super(metricsKeyWrapper, AtomicLong::new, consumerFunc); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongAccumulatorContainer.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongAccumulatorContainer.java new file mode 100644 index 0000000000..a3f1a21dfb --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongAccumulatorContainer.java @@ -0,0 +1,28 @@ +/* + * 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.metrics.model.container; + +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; + +import java.util.concurrent.atomic.LongAccumulator; + +public class LongAccumulatorContainer extends LongContainer { + public LongAccumulatorContainer(MetricsKeyWrapper metricsKeyWrapper, LongAccumulator accumulator) { + super(metricsKeyWrapper, () -> accumulator, (responseTime, longAccumulator) -> longAccumulator.accumulate(responseTime)); + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongContainer.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongContainer.java new file mode 100644 index 0000000000..2de2d15ee9 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/container/LongContainer.java @@ -0,0 +1,112 @@ +/* + * 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.metrics.model.container; + +import org.apache.dubbo.metrics.model.MetricsKey; +import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Long type data container + * @param + */ +public class LongContainer extends ConcurrentHashMap { + + /** + * Provide the metric type name + */ + private final transient MetricsKeyWrapper metricsKeyWrapper; + /** + * The initial value corresponding to the key is generally 0 of different data types + */ + private final transient Function initFunc; + /** + * Statistical data calculation function, which can be self-increment, self-decrement, or more complex avg function + */ + private final transient BiConsumer consumerFunc; + /** + * Data output function required by {@link GaugeMetricSample GaugeMetricSample} + */ + private transient Function valueSupplier; + + + public LongContainer(MetricsKeyWrapper metricsKeyWrapper, Supplier initFunc, BiConsumer consumerFunc) { + this.metricsKeyWrapper = metricsKeyWrapper; + this.initFunc = s -> initFunc.get(); + this.consumerFunc = consumerFunc; + this.valueSupplier = k -> this.get(k).longValue(); + } + + public boolean specifyType(String type) { + return type.equals(getMetricsKeyWrapper().getType()); + } + + public MetricsKeyWrapper getMetricsKeyWrapper() { + return metricsKeyWrapper; + } + + public boolean isKeyWrapper(MetricsKey metricsKey, String registryOpType) { + return metricsKeyWrapper.isKey(metricsKey, registryOpType); + } + + public Function getInitFunc() { + return initFunc; + } + + public BiConsumer getConsumerFunc() { + return consumerFunc; + } + + public Function getValueSupplier() { + return valueSupplier; + } + + public void setValueSupplier(Function valueSupplier) { + this.valueSupplier = valueSupplier; + } + + @Override + public String toString() { + return "LongContainer{" + + "metricsKeyWrapper=" + metricsKeyWrapper + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + LongContainer that = (LongContainer) o; + + return metricsKeyWrapper.equals(that.metricsKeyWrapper); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + metricsKeyWrapper.hashCode(); + return result; + } +} diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java index 2cb8b99298..bfb4b07c7e 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java @@ -19,12 +19,15 @@ package org.apache.dubbo.metrics.metadata.collector.stat; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.metrics.collector.MetricsCollector; +import org.apache.dubbo.metrics.metadata.event.MetadataEvent; import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.MetricsCategory; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.container.AtomicLongContainer; +import org.apache.dubbo.metrics.model.container.LongAccumulatorContainer; +import org.apache.dubbo.metrics.model.container.LongContainer; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; -import org.apache.dubbo.metrics.metadata.event.MetadataEvent; import org.apache.dubbo.metrics.report.MetricsExport; import java.util.ArrayList; @@ -33,9 +36,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAccumulator; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -124,92 +124,4 @@ public class MetadataStatComposite implements MetricsExport { return new GaugeMetricSample<>(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber, AtomicLong::get); } - - /** - * Collect Number type data - * - * @param - */ - public static class LongContainer extends ConcurrentHashMap { - - /** - * Provide the metric type name - */ - private final MetricsKeyWrapper metricsKeyWrapper; - /** - * The initial value corresponding to the key is generally 0 of different data types - */ - private final Function initFunc; - /** - * Statistical data calculation function, which can be self-increment, self-decrement, or more complex avg function - */ - private final BiConsumer consumerFunc; - /** - * Data output function required by {@link GaugeMetricSample GaugeMetricSample} - */ - private Function valueSupplier; - - - public LongContainer(MetricsKeyWrapper metricsKeyWrapper, Supplier initFunc, BiConsumer consumerFunc) { - this.metricsKeyWrapper = metricsKeyWrapper; - this.initFunc = s -> initFunc.get(); - this.consumerFunc = consumerFunc; - this.valueSupplier = k -> this.get(k).longValue(); - } - - public boolean specifyType(String type) { - return type.equals(getMetricsKeyWrapper().getType()); - } - - public MetricsKeyWrapper getMetricsKeyWrapper() { - return metricsKeyWrapper; - } - - public boolean isKeyWrapper(MetricsKey metricsKey, String registryOpType) { - return metricsKeyWrapper.isKey(metricsKey,registryOpType); - } - - public Function getInitFunc() { - return initFunc; - } - - public BiConsumer getConsumerFunc() { - return consumerFunc; - } - - public Function getValueSupplier() { - return valueSupplier; - } - - public void setValueSupplier(Function valueSupplier) { - this.valueSupplier = valueSupplier; - } - - @Override - public String toString() { - return "LongContainer{" + - "metricsKeyWrapper=" + metricsKeyWrapper + - '}'; - } - } - - public static class AtomicLongContainer extends LongContainer { - - public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper) { - super(metricsKeyWrapper, AtomicLong::new, (responseTime, longAccumulator) -> longAccumulator.set(responseTime)); - } - - public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper, BiConsumer consumerFunc) { - super(metricsKeyWrapper, AtomicLong::new, consumerFunc); - } - - } - - public static class LongAccumulatorContainer extends LongContainer { - public LongAccumulatorContainer(MetricsKeyWrapper metricsKeyWrapper, LongAccumulator accumulator) { - super(metricsKeyWrapper, () -> accumulator, (responseTime, longAccumulator) -> longAccumulator.accumulate(responseTime)); - } - } - - } diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataMetricsCollectorTest.java similarity index 95% rename from dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java rename to dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataMetricsCollectorTest.java index 1212c0f55b..0b6d44c2b1 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/metrics/metrics/collector/MetadataMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataMetricsCollectorTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package metrics.metrics.collector; +package org.apache.dubbo.metrics.metadata; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; @@ -75,7 +75,7 @@ class MetadataMetricsCollectorTest { List metricSamples = collector.collect(); // push success +1 - Assertions.assertEquals(metricSamples.size(), 1); + Assertions.assertEquals(1, metricSamples.size()); Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.METADATA_PUSH_METRIC_NUM.getName()); @@ -83,7 +83,7 @@ class MetadataMetricsCollectorTest { // push finish rt +1 metricSamples = collector.collect(); //num(total+success) + rt(5) = 7 - Assertions.assertEquals(metricSamples.size(), 7); + Assertions.assertEquals(7, metricSamples.size()); long c1 = timePair.calc(); TimePair lastTimePair = TimePair.start(); eventMulticaster.publishEvent(new MetadataEvent.PushEvent(applicationModel, lastTimePair)); @@ -94,7 +94,7 @@ class MetadataMetricsCollectorTest { metricSamples = collector.collect(); // num(total+success+error) + rt(5) - Assertions.assertEquals(metricSamples.size(), 8); + Assertions.assertEquals(8, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -124,7 +124,7 @@ class MetadataMetricsCollectorTest { List metricSamples = collector.collect(); // push success +1 - Assertions.assertEquals(metricSamples.size(), 1); + Assertions.assertEquals(1, metricSamples.size()); Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); Assertions.assertEquals(metricSamples.get(0).getName(), MetricsKey.METADATA_SUBSCRIBE_METRIC_NUM.getName()); @@ -132,7 +132,7 @@ class MetadataMetricsCollectorTest { // push finish rt +1 metricSamples = collector.collect(); //num(total+success) + rt(5) = 7 - Assertions.assertEquals(metricSamples.size(), 7); + Assertions.assertEquals(7, metricSamples.size()); long c1 = timePair.calc(); TimePair lastTimePair = TimePair.start(); eventMulticaster.publishEvent(new MetadataEvent.SubscribeEvent(applicationModel, lastTimePair)); @@ -143,7 +143,7 @@ class MetadataMetricsCollectorTest { metricSamples = collector.collect(); // num(total+success+error) + rt(5) - Assertions.assertEquals(metricSamples.size(), 8); + Assertions.assertEquals(8, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java new file mode 100644 index 0000000000..66906decce --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-metadata/src/test/java/org/apache/dubbo/metrics/metadata/MetadataStatCompositeTest.java @@ -0,0 +1,67 @@ +/* + * 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.metrics.metadata; + +import org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite; +import org.apache.dubbo.metrics.metadata.event.MetadataEvent; +import org.apache.dubbo.metrics.model.container.LongContainer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +import static org.apache.dubbo.metrics.metadata.collector.stat.MetadataStatComposite.OP_TYPE_SUBSCRIBE; + +public class MetadataStatCompositeTest { + + private final String applicationName = "app1"; + + @Test + void testInit() { + MetadataStatComposite statComposite = new MetadataStatComposite(); + Assertions.assertEquals(statComposite.numStats.size(), MetadataEvent.Type.values().length); + //(rt)5 * (push,subscribe)2 + Assertions.assertEquals(5 * 2, statComposite.rtStats.size()); + statComposite.numStats.values().forEach((v -> + Assertions.assertEquals(v, new ConcurrentHashMap<>()))); + statComposite.rtStats.forEach(rtContainer -> + { + for (Map.Entry entry : rtContainer.entrySet()) { + Assertions.assertEquals(0L, rtContainer.getValueSupplier().apply(entry.getKey())); + } + }); + } + + @Test + void testIncrement() { + MetadataStatComposite statComposite = new MetadataStatComposite(); + statComposite.increment(MetadataEvent.Type.P_TOTAL, applicationName); + Assertions.assertEquals(1L, statComposite.numStats.get(MetadataEvent.Type.P_TOTAL).get(applicationName).get()); + } + + @Test + void testCalcRt() { + MetadataStatComposite statComposite = new MetadataStatComposite(); + statComposite.calcRt(applicationName, OP_TYPE_SUBSCRIBE, 10L); + Assertions.assertTrue(statComposite.rtStats.stream().anyMatch(longContainer -> longContainer.specifyType(OP_TYPE_SUBSCRIBE))); + Optional> subContainer = statComposite.rtStats.stream().filter(longContainer -> longContainer.specifyType(OP_TYPE_SUBSCRIBE)).findFirst(); + subContainer.ifPresent(v -> Assertions.assertEquals(10L, v.get(applicationName).longValue())); + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java index c30b7c0f11..37ee237500 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/RegistryMetricsCollector.java @@ -89,10 +89,10 @@ public class RegistryMetricsCollector implements ApplicationMetricsCollector collect() { - if (!isCollectEnabled()) { - new ArrayList<>(); - } List list = new ArrayList<>(); + if (!isCollectEnabled()) { + return list; + } list.addAll(stats.exportNumMetrics()); list.addAll(stats.exportRtMetrics()); list.addAll(stats.exportSkMetrics()); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java index 2e41f9274f..3f97210876 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java @@ -23,6 +23,9 @@ import org.apache.dubbo.metrics.model.ApplicationMetric; import org.apache.dubbo.metrics.model.MetricsCategory; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.MetricsKeyWrapper; +import org.apache.dubbo.metrics.model.container.AtomicLongContainer; +import org.apache.dubbo.metrics.model.container.LongAccumulatorContainer; +import org.apache.dubbo.metrics.model.container.LongContainer; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.metrics.report.MetricsExport; @@ -33,9 +36,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAccumulator; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -152,93 +152,4 @@ public class RegistryStatComposite implements MetricsExport { public GaugeMetricSample convertToSample(String applicationName, RegistryEvent.Type type, MetricsCategory category, AtomicLong targetNumber) { return new GaugeMetricSample<>(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber, AtomicLong::get); } - - - /** - * Collect Number type data - * - * @param - */ - public static class LongContainer extends ConcurrentHashMap { - - /** - * Provide the metric type name - */ - private final MetricsKeyWrapper metricsKeyWrapper; - /** - * The initial value corresponding to the key is generally 0 of different data types - */ - private final Function initFunc; - /** - * Statistical data calculation function, which can be self-increment, self-decrement, or more complex avg function - */ - private final BiConsumer consumerFunc; - /** - * Data output function required by {@link GaugeMetricSample GaugeMetricSample} - */ - private Function valueSupplier; - - - public LongContainer(MetricsKeyWrapper metricsKeyWrapper, Supplier initFunc, BiConsumer consumerFunc) { - this.metricsKeyWrapper = metricsKeyWrapper; - this.initFunc = s -> initFunc.get(); - this.consumerFunc = consumerFunc; - this.valueSupplier = k -> this.get(k).longValue(); - } - - public boolean specifyType(String type) { - return type.equals(getMetricsKeyWrapper().getType()); - } - - public MetricsKeyWrapper getMetricsKeyWrapper() { - return metricsKeyWrapper; - } - - public boolean isKeyWrapper(MetricsKey metricsKey, String registryOpType) { - return metricsKeyWrapper.isKey(metricsKey,registryOpType); - } - - public Function getInitFunc() { - return initFunc; - } - - public BiConsumer getConsumerFunc() { - return consumerFunc; - } - - public Function getValueSupplier() { - return valueSupplier; - } - - public void setValueSupplier(Function valueSupplier) { - this.valueSupplier = valueSupplier; - } - - @Override - public String toString() { - return "LongContainer{" + - "metricsKeyWrapper=" + metricsKeyWrapper + - '}'; - } - } - - public static class AtomicLongContainer extends LongContainer { - - public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper) { - super(metricsKeyWrapper, AtomicLong::new, (responseTime, longAccumulator) -> longAccumulator.set(responseTime)); - } - - public AtomicLongContainer(MetricsKeyWrapper metricsKeyWrapper, BiConsumer consumerFunc) { - super(metricsKeyWrapper, AtomicLong::new, consumerFunc); - } - - } - - public static class LongAccumulatorContainer extends LongContainer { - public LongAccumulatorContainer(MetricsKeyWrapper metricsKeyWrapper, LongAccumulator accumulator) { - super(metricsKeyWrapper, () -> accumulator, (responseTime, longAccumulator) -> longAccumulator.accumulate(responseTime)); - } - } - - } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java index 0b39ff8376..f77fe9e5f1 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/ServiceKeyMetric.java @@ -41,10 +41,6 @@ public class ServiceKeyMetric implements Metric { this.serviceKey = serviceKey; } - public String getServiceKey() { - return serviceKey; - } - public Map getTags() { Map tags = new HashMap<>(); tags.put(TAG_IP, getLocalHost()); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java index b5a0b1c19d..6fee8f039a 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsCollectorTest.java @@ -73,14 +73,14 @@ class RegistryMetricsCollectorTest { List metricSamples = collector.collect(); // push success +1 - Assertions.assertEquals(metricSamples.size(), 1); + Assertions.assertEquals(1, metricSamples.size()); Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, timePair)); // push finish rt +1 metricSamples = collector.collect(); //num(total+success) + rt(5) = 7 - Assertions.assertEquals(metricSamples.size(), 7); + Assertions.assertEquals(7, metricSamples.size()); long c1 = timePair.calc(); TimePair lastTimePair = TimePair.start(); eventMulticaster.publishEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, lastTimePair)); @@ -91,7 +91,7 @@ class RegistryMetricsCollectorTest { metricSamples = collector.collect(); // num(total+success+error) + rt(5) - Assertions.assertEquals(metricSamples.size(), 8); + Assertions.assertEquals(8, metricSamples.size()); // calc rt for (MetricSample sample : metricSamples) { @@ -110,5 +110,4 @@ class RegistryMetricsCollectorTest { } - } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java new file mode 100644 index 0000000000..9829809243 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java @@ -0,0 +1,67 @@ +/* + * 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.metrics.registry.metrics.collector; + +import org.apache.dubbo.metrics.model.container.LongContainer; +import org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +import static org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_NOTIFY; + +public class RegistryStatCompositeTest { + + private final String applicationName = "app1"; + + @Test + void testInit() { + RegistryStatComposite statComposite = new RegistryStatComposite(); + Assertions.assertEquals(statComposite.numStats.size(), RegistryEvent.Type.values().length); + //(rt)5 * (register,subscribe,notify)3 + Assertions.assertEquals(5 * 3, statComposite.rtStats.size()); + statComposite.numStats.values().forEach((v -> + Assertions.assertEquals(v, new ConcurrentHashMap<>()))); + statComposite.rtStats.forEach(rtContainer -> + { + for (Map.Entry entry : rtContainer.entrySet()) { + Assertions.assertEquals(0L, rtContainer.getValueSupplier().apply(entry.getKey())); + } + }); + } + + @Test + void testIncrement() { + RegistryStatComposite statComposite = new RegistryStatComposite(); + statComposite.increment(RegistryEvent.Type.R_TOTAL, applicationName); + Assertions.assertEquals(1L, statComposite.numStats.get(RegistryEvent.Type.R_TOTAL).get(applicationName).get()); + } + + @Test + void testCalcRt() { + RegistryStatComposite statComposite = new RegistryStatComposite(); + statComposite.calcRt(applicationName, OP_TYPE_NOTIFY, 10L); + Assertions.assertTrue(statComposite.rtStats.stream().anyMatch(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY))); + Optional> subContainer = statComposite.rtStats.stream().filter(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY)).findFirst(); + subContainer.ifPresent(v -> Assertions.assertEquals(10L, v.get(applicationName).longValue())); + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java deleted file mode 100644 index 44beb3a608..0000000000 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/MethodMetricTest.java +++ /dev/null @@ -1,79 +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.metrics.registry.metrics.model; - -import org.apache.dubbo.metrics.model.MethodMetric; -import org.apache.dubbo.rpc.RpcInvocation; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.util.Map; - -import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_VERSION_KEY; -import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; -import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; - -class MethodMetricTest { - - private static final String applicationName = null; - private static String interfaceName; - private static String methodName; - private static String group; - private static String version; - private static RpcInvocation invocation; - - @BeforeAll - public static void setup() { - interfaceName = "org.apache.dubbo.MockInterface"; - methodName = "mockMethod"; - group = "mockGroup"; - version = "1.0.0"; - invocation = new RpcInvocation(methodName, interfaceName, "serviceKey", null, null); - invocation.setTargetServiceUniqueName(group + "/" + interfaceName + ":" + version); - invocation.setAttachment(GROUP_KEY, group); - invocation.setAttachment(VERSION_KEY, version); - } - - @Test - void test() { - MethodMetric metric = new MethodMetric(applicationName, invocation); - Assertions.assertEquals(metric.getInterfaceName(), interfaceName); - Assertions.assertEquals(metric.getMethodName(), methodName); - Assertions.assertEquals(metric.getGroup(), group); - Assertions.assertEquals(metric.getVersion(), version); - - Map tags = metric.getTags(); - Assertions.assertEquals(tags.get(TAG_IP), getLocalHost()); - Assertions.assertEquals(tags.get(TAG_HOSTNAME), getLocalHostName()); - Assertions.assertEquals(tags.get(TAG_APPLICATION_NAME), applicationName); - - Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), interfaceName); - Assertions.assertEquals(tags.get(TAG_METHOD_KEY), methodName); - Assertions.assertEquals(tags.get(TAG_GROUP_KEY), group); - Assertions.assertEquals(tags.get(TAG_VERSION_KEY), version); - } -} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java deleted file mode 100644 index 4931e24c13..0000000000 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/model/sample/GaugeMetricSampleTest.java +++ /dev/null @@ -1,67 +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.metrics.registry.metrics.model.sample; - -import org.apache.dubbo.metrics.model.MetricsCategory; -import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; -import org.apache.dubbo.metrics.model.sample.MetricSample; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Supplier; -import java.util.function.ToDoubleFunction; - -class GaugeMetricSampleTest { - - private static String name; - private static String description; - private static Map tags; - private static MetricsCategory category; - private static String baseUnit; - private static AtomicLong value; - private static ToDoubleFunction apply; - - @BeforeAll - public static void setup() { - name = "test"; - description = "test"; - tags = new HashMap<>(); - category = MetricsCategory.REQUESTS; - baseUnit = "byte"; - value = new AtomicLong(1); - apply = AtomicLong::longValue; - } - - @Test - void test() { - GaugeMetricSample sample = new GaugeMetricSample<>(name, description, tags, category, baseUnit, value, apply); - Assertions.assertEquals(sample.getName(), name); - Assertions.assertEquals(sample.getDescription(), description); - Assertions.assertEquals(sample.getTags(), tags); - Assertions.assertEquals(sample.getType(), MetricSample.Type.GAUGE); - Assertions.assertEquals(sample.getCategory(), category); - Assertions.assertEquals(sample.getBaseUnit(), baseUnit); - Assertions.assertEquals(1, sample.applyAsLong()); - value.set(2); - Assertions.assertEquals(2, sample.applyAsLong()); - } -} From c272af38c65649ec5dd4348ccf73fb699fa976a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=94=E7=AD=89=E5=90=8C=E5=AD=A6?= <37730787+erdengk@users.noreply.github.com> Date: Fri, 3 Mar 2023 06:43:37 +0800 Subject: [PATCH 057/144] Reactor some newInstance method (#11686) --- .../apache/dubbo/common/logger/LoggerFactory.java | 6 +++--- .../dubbo/common/utils/CompatibleTypeUtils.java | 6 +++--- .../org/apache/dubbo/common/utils/PojoUtils.java | 8 ++++---- .../dubbo/config/context/AbstractConfigManager.java | 2 +- .../dubbo/common/bytecode/ClassGeneratorTest.java | 6 +++--- .../compiler/support/AdaptiveCompilerTest.java | 4 ++-- .../compiler/support/JavassistCompilerTest.java | 10 +++++----- .../common/compiler/support/JdkCompilerTest.java | 12 ++++++------ .../dubbo/common/logger/LoggerAdapterTest.java | 11 ++++++----- .../org/apache/dubbo/common/logger/LoggerTest.java | 11 ++++++----- .../apache/dubbo/common/utils/ReflectUtilsTest.java | 8 ++++---- .../org/apache/dubbo/config/AbstractConfigTest.java | 2 +- .../org/apache/dubbo/config/ReferenceConfigTest.java | 6 +++--- .../validation/support/jvalidation/JValidator.java | 2 +- .../support/jvalidation/JValidatorNew.java | 2 +- .../spring/security/jackson/ObjectMapperCodec.java | 2 +- .../remoting/http/jetty/JettyLoggerAdapterTest.java | 4 ++-- .../remoting/transport/netty4/RpcMessageHandler.java | 2 +- .../apache/dubbo/rpc/filter/GenericImplFilter.java | 4 ++-- .../rpc/protocol/injvm/InjvmClassLoaderTest.java | 4 ++-- .../rpc/protocol/rest/util/MultiValueCreator.java | 2 +- 21 files changed, 58 insertions(+), 56 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/LoggerFactory.java b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/LoggerFactory.java index c718ae9e79..02e1cd7744 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/LoggerFactory.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/LoggerFactory.java @@ -75,7 +75,7 @@ public class LoggerFactory { // try to use the first available adapter for (Class clazz : candidates) { try { - LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance(); + LoggerAdapter loggerAdapter = clazz.getDeclaredConstructor().newInstance(); loggerAdapter.getLogger(LoggerFactory.class); if (loggerAdapter.isConfigured()) { setLoggerAdapter(loggerAdapter); @@ -93,7 +93,7 @@ public class LoggerFactory { System.err.println("Dubbo: Unable to find a proper configured logger to log out."); for (Class clazz : candidates) { try { - LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance(); + LoggerAdapter loggerAdapter = clazz.getDeclaredConstructor().newInstance(); loggerAdapter.getLogger(LoggerFactory.class); setLoggerAdapter(loggerAdapter); found = true; @@ -221,7 +221,7 @@ public class LoggerFactory { List result = new LinkedList<>(); for (Map.Entry, String> entry : candidates.entrySet()) { try { - LoggerAdapter loggerAdapter = entry.getKey().getConstructor().newInstance(); + LoggerAdapter loggerAdapter = entry.getKey().getDeclaredConstructor().newInstance(); loggerAdapter.getLogger(LoggerFactory.class); result.add(entry.getValue()); } catch (Exception ignored) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CompatibleTypeUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CompatibleTypeUtils.java index a57f53f82a..fb4d53ccbd 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CompatibleTypeUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CompatibleTypeUtils.java @@ -204,7 +204,7 @@ public class CompatibleTypeUtils { } if (!type.isInterface()) { try { - Collection result = (Collection) type.newInstance(); + Collection result = (Collection) type.getDeclaredConstructor().newInstance(); result.addAll(collection); return result; } catch (Throwable ignored) { @@ -222,8 +222,8 @@ public class CompatibleTypeUtils { Collection collection; if (!type.isInterface()) { try { - collection = (Collection) type.newInstance(); - } catch (Throwable e) { + collection = (Collection) type.getDeclaredConstructor().newInstance(); + } catch (Exception e) { collection = new ArrayList(length); } } else if (type == Set.class) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java index 016542e1dd..200aa7b1be 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java @@ -275,7 +275,7 @@ public class PojoUtils { } if (!type.isInterface() && !Modifier.isAbstract(type.getModifiers())) { try { - return (Collection) type.newInstance(); + return (Collection) type.getDeclaredConstructor().newInstance(); } catch (Exception e) { // ignore } @@ -306,7 +306,7 @@ public class PojoUtils { result = new ConcurrentSkipListMap(); } else { try { - result = cl.newInstance(); + result = cl.getDeclaredConstructor().newInstance(); } catch (Exception e) { /* ignore */ } if (result == null) { @@ -434,7 +434,7 @@ public class PojoUtils { // when return type is not the subclass of return type from the signature and not an interface if (!type.isInterface() && !type.isAssignableFrom(pojo.getClass())) { try { - map = (Map) type.newInstance(); + map = (Map) type.getDeclaredConstructor().newInstance(); Map mapPojo = (Map) pojo; map.putAll(mapPojo); if (GENERIC_WITH_CLZ) { @@ -596,7 +596,7 @@ public class PojoUtils { private static Object newInstance(Class cls) { try { - return cls.newInstance(); + return cls.getDeclaredConstructor().newInstance(); } catch (Throwable t) { Constructor[] constructors = cls.getDeclaredConstructors(); /* diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java index 82bdad15d2..76bd79672f 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java @@ -538,7 +538,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter { } private T createConfig(Class cls, ScopeModel scopeModel) throws ReflectiveOperationException { - T config = cls.newInstance(); + T config = cls.getDeclaredConstructor().newInstance(); config.setScopeModel(scopeModel); return config; } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/ClassGeneratorTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/ClassGeneratorTest.java index 9cef0a3468..607f6010c1 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/ClassGeneratorTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/bytecode/ClassGeneratorTest.java @@ -166,7 +166,7 @@ class ClassGeneratorTest { cl.getField("FNAME").set(null, fname); System.out.println(cl.getName()); - Builder builder = (Builder) cl.newInstance(); + Builder builder = (Builder) cl.getDeclaredConstructor().newInstance(); System.out.println(b.getName()); builder.setName(b, "ok"); System.out.println(b.getName()); @@ -192,7 +192,7 @@ class ClassGeneratorTest { cl.getField("FNAME").set(null, fname); System.out.println(cl.getName()); - Builder builder = (Builder) cl.newInstance(); + Builder builder = (Builder) cl.getDeclaredConstructor().newInstance(); System.out.println(b.getName()); builder.setName(b, "ok"); System.out.println(b.getName()); @@ -213,4 +213,4 @@ class Bean { } public static volatile String abc = "df"; -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/AdaptiveCompilerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/AdaptiveCompilerTest.java index 785ee82b16..9edc55804a 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/AdaptiveCompilerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/AdaptiveCompilerTest.java @@ -29,8 +29,8 @@ class AdaptiveCompilerTest extends JavaCodeTest { AdaptiveCompiler compiler = new AdaptiveCompiler(); compiler.setFrameworkModel(FrameworkModel.defaultModel()); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), AdaptiveCompiler.class.getClassLoader()); - HelloService helloService = (HelloService) clazz.newInstance(); + HelloService helloService = (HelloService) clazz.getDeclaredConstructor().newInstance(); Assertions.assertEquals("Hello world!", helloService.sayHello()); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java index 7d03b57ad4..9cfb667b39 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JavassistCompilerTest.java @@ -30,7 +30,7 @@ class JavassistCompilerTest extends JavaCodeTest { Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), JavassistCompiler.class.getClassLoader()); // Because javassist compiles using the caller class loader, we should't use HelloService directly - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); } @@ -48,7 +48,7 @@ class JavassistCompilerTest extends JavaCodeTest { Assertions.assertThrows(RuntimeException.class, () -> compiler.compile(null, getSimpleCodeWithoutPackage(), JavassistCompiler.class.getClassLoader())); } else { Class clazz = compiler.compile(null, getSimpleCodeWithoutPackage(), JavassistCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); } @@ -59,7 +59,7 @@ class JavassistCompilerTest extends JavaCodeTest { Assertions.assertThrows(IllegalStateException.class, () -> { JavassistCompiler compiler = new JavassistCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax0(), JavassistCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); }); @@ -69,7 +69,7 @@ class JavassistCompilerTest extends JavaCodeTest { void testCompileJavaClassWithImport() throws Exception { JavassistCompiler compiler = new JavassistCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithImports(), JavassistCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); } @@ -78,7 +78,7 @@ class JavassistCompilerTest extends JavaCodeTest { void testCompileJavaClassWithExtends() throws Exception { JavassistCompiler compiler = new JavassistCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithWithExtends(), JavassistCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world3!", sayHello.invoke(instance)); } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java index 1f330ffb81..61b8b81967 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/compiler/support/JdkCompilerTest.java @@ -27,7 +27,7 @@ class JdkCompilerTest extends JavaCodeTest { void test_compileJavaClass() throws Exception { JdkCompiler compiler = new JdkCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), JdkCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); } @@ -37,7 +37,7 @@ class JdkCompilerTest extends JavaCodeTest { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); }); @@ -48,7 +48,7 @@ class JdkCompilerTest extends JavaCodeTest { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler(); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); }); @@ -58,7 +58,7 @@ class JdkCompilerTest extends JavaCodeTest { void test_compileJavaClass_java8() throws Exception { JdkCompiler compiler = new JdkCompiler("1.8"); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), JdkCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); } @@ -68,7 +68,7 @@ class JdkCompilerTest extends JavaCodeTest { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler("1.8"); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); }); @@ -79,7 +79,7 @@ class JdkCompilerTest extends JavaCodeTest { Assertions.assertThrows(IllegalStateException.class, () -> { JdkCompiler compiler = new JdkCompiler("1.8"); Class clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader()); - Object instance = clazz.newInstance(); + Object instance = clazz.getDeclaredConstructor().newInstance(); Method sayHello = instance.getClass().getMethod("sayHello"); Assertions.assertEquals("Hello world!", sayHello.invoke(instance)); }); diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerAdapterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerAdapterTest.java index 7d5b82f840..afab9e4c7b 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerAdapterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerAdapterTest.java @@ -31,6 +31,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import java.lang.reflect.InvocationTargetException; import java.util.stream.Stream; import static org.hamcrest.CoreMatchers.is; @@ -49,8 +50,8 @@ class LoggerAdapterTest { @ParameterizedTest @MethodSource("data") - public void testGetLogger(Class loggerAdapterClass, Class loggerClass) throws IllegalAccessException, InstantiationException { - LoggerAdapter loggerAdapter = loggerAdapterClass.newInstance(); + void testGetLogger(Class loggerAdapterClass, Class loggerClass) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { + LoggerAdapter loggerAdapter = loggerAdapterClass.getDeclaredConstructor().newInstance(); Logger logger = loggerAdapter.getLogger(this.getClass()); assertThat(logger.getClass().isAssignableFrom(loggerClass), is(true)); @@ -61,11 +62,11 @@ class LoggerAdapterTest { @ParameterizedTest @MethodSource("data") - public void testLevel(Class loggerAdapterClass) throws IllegalAccessException, InstantiationException { - LoggerAdapter loggerAdapter = loggerAdapterClass.newInstance(); + void testLevel(Class loggerAdapterClass) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { + LoggerAdapter loggerAdapter = loggerAdapterClass.getDeclaredConstructor().newInstance(); for (Level targetLevel : Level.values()) { loggerAdapter.setLevel(targetLevel); assertThat(loggerAdapter.getLevel(), is(targetLevel)); } } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerTest.java index 98941fe686..e834433c94 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/logger/LoggerTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import java.lang.reflect.InvocationTargetException; import java.util.stream.Stream; import static org.hamcrest.CoreMatchers.not; @@ -47,8 +48,8 @@ class LoggerTest { @ParameterizedTest @MethodSource("data") - public void testAllLogMethod(Class loggerAdapter) throws Exception { - LoggerAdapter adapter = loggerAdapter.newInstance(); + void testAllLogMethod(Class loggerAdapter) throws Exception { + LoggerAdapter adapter = loggerAdapter.getDeclaredConstructor().newInstance(); adapter.setLevel(Level.ALL); Logger logger = adapter.getLogger(this.getClass()); logger.error("error"); @@ -72,8 +73,8 @@ class LoggerTest { @ParameterizedTest @MethodSource("data") - public void testLevelEnable(Class loggerAdapter) throws IllegalAccessException, InstantiationException { - LoggerAdapter adapter = loggerAdapter.newInstance(); + void testLevelEnable(Class loggerAdapter) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { + LoggerAdapter adapter = loggerAdapter.getDeclaredConstructor().newInstance(); adapter.setLevel(Level.ALL); Logger logger = adapter.getLogger(this.getClass()); assertThat(logger.isWarnEnabled(), not(nullValue())); @@ -82,4 +83,4 @@ class LoggerTest { assertThat(logger.isInfoEnabled(), not(nullValue())); assertThat(logger.isDebugEnabled(), not(nullValue())); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java index 2b2022e852..15257f253d 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java @@ -46,14 +46,14 @@ import static org.junit.jupiter.api.Assertions.fail; class ReflectUtilsTest { @Test - void testIsPrimitives() throws Exception { + void testIsPrimitives() { assertTrue(ReflectUtils.isPrimitives(boolean[].class)); assertTrue(ReflectUtils.isPrimitives(byte.class)); assertFalse(ReflectUtils.isPrimitive(Map[].class)); } @Test - void testIsPrimitive() throws Exception { + void testIsPrimitive() { assertTrue(ReflectUtils.isPrimitive(boolean.class)); assertTrue(ReflectUtils.isPrimitive(String.class)); assertTrue(ReflectUtils.isPrimitive(Boolean.class)); @@ -64,7 +64,7 @@ class ReflectUtilsTest { } @Test - void testGetBoxedClass() throws Exception { + void testGetBoxedClass() { assertThat(ReflectUtils.getBoxedClass(int.class), sameInstance(Integer.class)); assertThat(ReflectUtils.getBoxedClass(boolean.class), sameInstance(Boolean.class)); assertThat(ReflectUtils.getBoxedClass(long.class), sameInstance(Long.class)); @@ -544,4 +544,4 @@ class ReflectUtilsTest { } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java index 88b19cf1c4..02e93d69b2 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java @@ -1005,7 +1005,7 @@ class AbstractConfigTest { ModuleConfig.class, SslConfig.class, MetricsConfig.class, MonitorConfig.class, MethodConfig.class); for (Class configClass : configClasses) { - AbstractConfig config = configClass.newInstance(); + AbstractConfig config = configClass.getDeclaredConstructor().newInstance(); Map metaData = config.getMetaData(); Assertions.assertEquals(0, metaData.size(), "Expect empty metadata for new instance but found: "+metaData +" of "+configClass.getSimpleName()); System.out.println(configClass.getSimpleName() + " metadata is checked."); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java index b55af853c7..e810e35af9 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java @@ -1070,7 +1070,7 @@ class ReferenceConfigTest { classLoader1.loadedClass.put(resultClazzCustom1.getName(), resultClazzCustom1); AtomicReference innerRequestReference = new AtomicReference(); AtomicReference innerResultReference = new AtomicReference(); - innerResultReference.set(resultClazzCustom1.newInstance()); + innerResultReference.set(resultClazzCustom1.getDeclaredConstructor().newInstance()); Constructor declaredConstructor = clazz1impl.getDeclaredConstructor(AtomicReference.class, AtomicReference.class); ServiceConfig serviceConfig = new ServiceConfig<>(); @@ -1098,14 +1098,14 @@ class ReferenceConfigTest { java.lang.reflect.Method callBean1 = object1.getClass().getDeclaredMethod("call", requestClazzOrigin); callBean1.setAccessible(true); - Object result1 = callBean1.invoke(object1, requestClazzCustom2.newInstance()); + Object result1 = callBean1.invoke(object1, requestClazzCustom2.getDeclaredConstructor().newInstance()); Assertions.assertEquals(resultClazzCustom3, result1.getClass()); Assertions.assertNotEquals(classLoader2, result1.getClass().getClassLoader()); Assertions.assertEquals(classLoader1, innerRequestReference.get().getClass().getClassLoader()); Thread.currentThread().setContextClassLoader(classLoader1); - callBean1.invoke(object1, requestClazzCustom2.newInstance()); + callBean1.invoke(object1, requestClazzCustom2.getDeclaredConstructor().newInstance()); Assertions.assertEquals(classLoader1, Thread.currentThread().getContextClassLoader()); applicationModel.destroy(); diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java index 6c5e14e680..b63fb4b349 100644 --- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java +++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java @@ -111,7 +111,7 @@ public class JValidator implements Validator { } catch (ClassNotFoundException e) { parameterClass = generateMethodParameterClass(clazz, method, parameterClassName); } - Object parameterBean = parameterClass.newInstance(); + Object parameterBean = parameterClass.getDeclaredConstructor().newInstance(); for (int i = 0; i < args.length; i++) { Field field = parameterClass.getField(method.getName() + "Argument" + i); field.set(parameterBean, args[i]); diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java index 542bf33e3c..96dcc12666 100644 --- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java +++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java @@ -111,7 +111,7 @@ public class JValidatorNew implements Validator { } catch (ClassNotFoundException e) { parameterClass = generateMethodParameterClass(clazz, method, parameterClassName); } - Object parameterBean = parameterClass.newInstance(); + Object parameterBean = parameterClass.getDeclaredConstructor().newInstance(); for (int i = 0; i < args.length; i++) { Field field = parameterClass.getField(method.getName() + "Argument" + i); field.set(parameterBean, args[i]); diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java index d2ddab3d38..470ee6f57f 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java @@ -103,7 +103,7 @@ public class ObjectMapperCodec { for (String moduleClassName : jacksonModuleClassNameList) { try { SimpleModule objectMapperModule = (SimpleModule) ClassUtils.forName(moduleClassName, - ObjectMapperCodec.class.getClassLoader()).newInstance(); + ObjectMapperCodec.class.getClassLoader()).getDeclaredConstructor().newInstance(); mapper.registerModule(objectMapperModule); } catch (Throwable ex) { diff --git a/dubbo-remoting/dubbo-remoting-http/src/test/java/org/apache/dubbo/remoting/http/jetty/JettyLoggerAdapterTest.java b/dubbo-remoting/dubbo-remoting-http/src/test/java/org/apache/dubbo/remoting/http/jetty/JettyLoggerAdapterTest.java index b300b27279..8557f32e45 100644 --- a/dubbo-remoting/dubbo-remoting-http/src/test/java/org/apache/dubbo/remoting/http/jetty/JettyLoggerAdapterTest.java +++ b/dubbo-remoting/dubbo-remoting-http/src/test/java/org/apache/dubbo/remoting/http/jetty/JettyLoggerAdapterTest.java @@ -67,7 +67,7 @@ class JettyLoggerAdapterTest { void testSuccessLogger() throws Exception{ Logger successLogger = mock(Logger.class); Class clazz = Class.forName("org.apache.dubbo.remoting.http.jetty.JettyLoggerAdapter"); - JettyLoggerAdapter jettyLoggerAdapter = (JettyLoggerAdapter) clazz.newInstance(); + JettyLoggerAdapter jettyLoggerAdapter = (JettyLoggerAdapter) clazz.getDeclaredConstructor().newInstance(); Field loggerField = clazz.getDeclaredField("logger"); loggerField.setAccessible(true); @@ -116,7 +116,7 @@ class JettyLoggerAdapterTest { @Test void testLoggerFormat() throws Exception{ Class clazz = Class.forName("org.apache.dubbo.remoting.http.jetty.JettyLoggerAdapter"); - Object newInstance = clazz.newInstance(); + Object newInstance = clazz.getDeclaredConstructor().newInstance(); Method method = clazz.getDeclaredMethod("format", String.class, Object[].class); method.setAccessible(true); diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/RpcMessageHandler.java b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/RpcMessageHandler.java index 76e63bd7e1..6912a5b7a6 100755 --- a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/RpcMessageHandler.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/RpcMessageHandler.java @@ -34,7 +34,7 @@ public class RpcMessageHandler implements Replier { String impl = service + "Impl"; try { Class cl = Thread.currentThread().getContextClassLoader().loadClass(impl); - return cl.newInstance(); + return cl.getDeclaredConstructor().newInstance(); } catch (Exception e) { e.printStackTrace(); } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java index f2b5041f93..c21fa3d1f9 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java @@ -155,7 +155,7 @@ public class GenericImplFilter implements Filter, Filter.Listener { // find the real interface from url String realInterface = invoker.getUrl().getParameter(Constants.INTERFACE); invokerInterface = ReflectUtils.forName(realInterface); - } catch (Throwable e) { + } catch (Exception e) { // ignore } } @@ -186,7 +186,7 @@ public class GenericImplFilter implements Filter, Filter.Listener { Throwable targetException = null; Throwable lastException = null; try { - targetException = (Throwable) clazz.newInstance(); + targetException = (Throwable) clazz.getDeclaredConstructor().newInstance(); } catch (Throwable e) { lastException = e; for (Constructor constructor : clazz.getConstructors()) { diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmClassLoaderTest.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmClassLoaderTest.java index 98af4c313b..a12c1893a5 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmClassLoaderTest.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmClassLoaderTest.java @@ -75,7 +75,7 @@ class InjvmClassLoaderTest { // AtomicReference to cache request/response of provider AtomicReference innerRequestReference = new AtomicReference(); AtomicReference innerResultReference = new AtomicReference(); - innerResultReference.set(resultClazzCustom1.newInstance()); + innerResultReference.set(resultClazzCustom1.getDeclaredConstructor().newInstance()); Constructor declaredConstructor = clazz1impl.getDeclaredConstructor(AtomicReference.class, AtomicReference.class); @@ -116,7 +116,7 @@ class InjvmClassLoaderTest { java.lang.reflect.Method callBean1 = object1.getClass().getDeclaredMethod("call", requestClazzOrigin); callBean1.setAccessible(true); - Object result1 = callBean1.invoke(object1, requestClazzCustom2.newInstance()); + Object result1 = callBean1.invoke(object1, requestClazzCustom2.getDeclaredConstructor().newInstance()); // invoke result should load from classLoader3 ( sub classLoader of classLoader2 --> consumer side classLoader) Assertions.assertEquals(resultClazzCustom3, result1.getClass()); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java index 5c6bf2ac9e..e64f47af73 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/MultiValueCreator.java @@ -35,7 +35,7 @@ public class MultiValueCreator { public static Object createMultiValueMap() { try { - return multiValueMapClass.newInstance(); + return multiValueMapClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { } From 48bc7165f7d81535db35ca8f4eee871261dfb034 Mon Sep 17 00:00:00 2001 From: liufeiyu1002 <32605119+liufeiyu1002@users.noreply.github.com> Date: Fri, 3 Mar 2023 07:15:26 +0800 Subject: [PATCH 058/144] fix reference bean name conflicts (#11699) * fix reference bean name conflicts * add ut case --- .../ReferenceAnnotationBeanPostProcessor.java | 19 ++++++++++-- ...erenceAnnotationBeanPostProcessorTest.java | 29 +++++++++++++++---- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java index adee70d4cf..bc6ddabfbb 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java @@ -19,6 +19,7 @@ package org.apache.dubbo.config.spring.beans.factory.annotation; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.ArrayUtils; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -413,8 +414,22 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean } //check bean definition - if (beanDefinitionRegistry.containsBeanDefinition(referenceBeanName)) { - BeanDefinition prevBeanDefinition = beanDefinitionRegistry.getBeanDefinition(referenceBeanName); + boolean isContains; + if ((isContains = beanDefinitionRegistry.containsBeanDefinition(referenceBeanName)) || beanDefinitionRegistry.isAlias(referenceBeanName)) { + String preReferenceBeanName = referenceBeanName; + if (!isContains){ + // Look in the alias for the origin bean name + String[] aliases = beanDefinitionRegistry.getAliases(referenceBeanName); + if (ArrayUtils.isNotEmpty(aliases)) { + for (String alias : aliases) { + if (beanDefinitionRegistry.containsBeanDefinition(alias)) { + preReferenceBeanName = alias; + break; + } + } + } + } + BeanDefinition prevBeanDefinition = beanDefinitionRegistry.getBeanDefinition(preReferenceBeanName); String prevBeanType = prevBeanDefinition.getBeanClassName(); String prevBeanDesc = referenceBeanName + "[" + prevBeanType + "]"; String newBeanDesc = referenceBeanName + "[" + referenceKey + "]"; diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java index 06d0592668..a4fbcff02d 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java @@ -128,15 +128,30 @@ class ReferenceAnnotationBeanPostProcessorTest { @DubboReference(version = "2", url = "dubbo://127.0.0.1:12345?version=2", tag = "demo_tag") private HelloService helloService2; - // #7 ReferenceBean (Method Injection #3) + // #7 ReferenceBean (Field Injection #5) + // The HelloService is the same as above service(#6 ReferenceBean (Field Injection #4)), helloService3 will be registered as an alias of helloService2 + @DubboReference(version = "2", url = "dubbo://127.0.0.1:12345?version=2", tag = "demo_tag") + private HelloService helloService3; + + // #8 ReferenceBean (Method Injection #3) @DubboReference(version = "3", url = "dubbo://127.0.0.1:12345?version=2", tag = "demo_tag") public void setHelloService2(HelloService helloService2) { // The helloService2 beanName is the same as above(#6 ReferenceBean (Field Injection #4)), and this will rename to helloService2#2 renamedHelloService2 = helloService2; } + // #9 ReferenceBean (Method Injection #4) + @DubboReference(version = "4", url = "dubbo://127.0.0.1:12345?version=2") + public void setHelloService3(DemoService helloService3){ + // The helloService3 beanName is the same as above(#7 ReferenceBean (Field Injection #5) is an alias), + // The current beanName(helloService3) is not registered in the beanDefinitionMap, but it is already an alias. so this will rename to helloService3#2 + this.renamedHelloService3 = helloService3; + } + private HelloService renamedHelloService2; + private DemoService renamedHelloService3; + @Test void testAop() throws Exception { @@ -150,7 +165,7 @@ class ReferenceAnnotationBeanPostProcessorTest { Assertions.assertNotNull(testBean.getDemoServiceFromParent()); Assertions.assertNotNull(testBean.getDemoService()); Assertions.assertNotNull(testBean.myDemoService); - Assertions.assertEquals(2, demoServicesMap.size()); + Assertions.assertEquals(3, demoServicesMap.size()); Assertions.assertNotNull(context.getBean("demoServiceImpl")); Assertions.assertNotNull(context.getBean("myDemoService")); @@ -189,12 +204,13 @@ class ReferenceAnnotationBeanPostProcessorTest { Map> referenceBeanMap = beanPostProcessor.getInjectedFieldReferenceBeanMap(); - Assertions.assertEquals(4, referenceBeanMap.size()); + Assertions.assertEquals(5, referenceBeanMap.size()); Map checkingFieldNames = new HashMap<>(); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest$MyConfiguration.helloService", 0); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest.helloService", 0); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest.helloService2", 0); + checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest.helloService3", 0); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.DemoService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest$ParentBean.demoServiceFromParent", 0); for (Map.Entry> entry : referenceBeanMap.entrySet()) { @@ -222,12 +238,13 @@ class ReferenceAnnotationBeanPostProcessorTest { Map> referenceBeanMap = beanPostProcessor.getInjectedMethodReferenceBeanMap(); - Assertions.assertEquals(3, referenceBeanMap.size()); + Assertions.assertEquals(4, referenceBeanMap.size()); Map checkingMethodNames = new HashMap<>(); checkingMethodNames.put("setDemoServiceFromAncestor", 0); checkingMethodNames.put("setDemoService", 0); checkingMethodNames.put("setHelloService2", 0); + checkingMethodNames.put("setHelloService3", 0); for (Map.Entry> entry : referenceBeanMap.entrySet()) { @@ -252,7 +269,7 @@ class ReferenceAnnotationBeanPostProcessorTest { Collection referenceBeans = referenceBeanManager.getReferences(); - Assertions.assertEquals(4, referenceBeans.size()); + Assertions.assertEquals(5, referenceBeans.size()); for (ReferenceBean referenceBean : referenceBeans) { ReferenceConfig referenceConfig = referenceBean.getReferenceConfig(); @@ -350,4 +367,4 @@ class ReferenceAnnotationBeanPostProcessorTest { } } -} \ No newline at end of file +} From cd3ef2a27f1dba60d4b952c74b2f0ae24752ba90 Mon Sep 17 00:00:00 2001 From: icodening Date: Fri, 3 Mar 2023 16:38:11 +0800 Subject: [PATCH 059/144] tri create Http2StreamChannel async (#11698) * tri create Http2StreamChannel async * tri create Http2StreamChannel async * tri create Http2StreamChannel async --------- Co-authored-by: earthchen --- .../dubbo/rpc/protocol/tri/TripleInvoker.java | 2 +- .../tri/command/CancelQueueCommand.java | 10 +-- .../tri/command/CreateStreamQueueCommand.java | 61 ++++++++++++++++ .../tri/command/DataQueueCommand.java | 12 ++-- .../tri/command/EndStreamQueueCommand.java | 11 ++- .../tri/command/HeaderQueueCommand.java | 14 ++-- .../protocol/tri/command/QueuedCommand.java | 8 ++- .../tri/command/StreamQueueCommand.java | 47 ++++++++++++ .../tri/command/TextDataQueueCommand.java | 10 +-- .../tri/stream/TripleClientStream.java | 72 +++++++++---------- .../tri/stream/TripleServerStream.java | 14 ++-- .../tri/stream/TripleStreamChannelFuture.java | 66 +++++++++++++++++ .../tri/transport/TripleWriteQueue.java | 15 +++- .../tri/stream/TripleClientStreamTest.java | 22 +++--- .../tri/transport/WriteQueueTest.java | 21 ++++-- 15 files changed, 300 insertions(+), 85 deletions(-) create mode 100644 dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CreateStreamQueueCommand.java create mode 100644 dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/StreamQueueCommand.java create mode 100644 dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleStreamChannelFuture.java diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java index f35409a96a..b5e8466068 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java @@ -76,7 +76,7 @@ public class TripleInvoker extends AbstractInvoker { private final Set> invokers; private final ExecutorService streamExecutor; private final String acceptEncodings; - private final TripleWriteQueue writeQueue = new TripleWriteQueue(); + private final TripleWriteQueue writeQueue = new TripleWriteQueue(256); public TripleInvoker(Class serviceType, URL url, diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CancelQueueCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CancelQueueCommand.java index 98ad47a90d..eb8b249fd0 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CancelQueueCommand.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CancelQueueCommand.java @@ -21,16 +21,18 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http2.DefaultHttp2ResetFrame; import io.netty.handler.codec.http2.Http2Error; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; -public class CancelQueueCommand extends QueuedCommand { +public class CancelQueueCommand extends StreamQueueCommand { private final Http2Error error; - public CancelQueueCommand(Http2Error error) { + public CancelQueueCommand(TripleStreamChannelFuture streamChannelFuture, Http2Error error) { + super(streamChannelFuture); this.error = error; } - public static CancelQueueCommand createCommand(Http2Error error) { - return new CancelQueueCommand(error); + public static CancelQueueCommand createCommand(TripleStreamChannelFuture streamChannelFuture, Http2Error error) { + return new CancelQueueCommand(streamChannelFuture, error); } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CreateStreamQueueCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CreateStreamQueueCommand.java new file mode 100644 index 0000000000..7044926bc1 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/CreateStreamQueueCommand.java @@ -0,0 +1,61 @@ +/* + * 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.protocol.tri.command; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; +import io.netty.handler.codec.http2.Http2StreamChannel; +import io.netty.handler.codec.http2.Http2StreamChannelBootstrap; +import io.netty.util.concurrent.Future; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; + +public class CreateStreamQueueCommand extends QueuedCommand { + + private final Http2StreamChannelBootstrap bootstrap; + + private final TripleStreamChannelFuture streamChannelFuture; + + private CreateStreamQueueCommand(Http2StreamChannelBootstrap bootstrap, + TripleStreamChannelFuture streamChannelFuture) { + this.bootstrap = bootstrap; + this.streamChannelFuture = streamChannelFuture; + this.promise(streamChannelFuture.getParentChannel().newPromise()); + this.channel(streamChannelFuture.getParentChannel()); + } + + public static CreateStreamQueueCommand create(Http2StreamChannelBootstrap bootstrap, + TripleStreamChannelFuture streamChannelFuture) { + return new CreateStreamQueueCommand(bootstrap, streamChannelFuture); + } + + @Override + public void doSend(ChannelHandlerContext ctx, ChannelPromise promise) { + //NOOP + } + + @Override + public void run(Channel channel) { + //work in I/O thread + Future future = bootstrap.open(); + if (future.isSuccess()) { + streamChannelFuture.complete(future.getNow()); + } else { + streamChannelFuture.completeExceptionally(future.cause()); + } + } +} diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/DataQueueCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/DataQueueCommand.java index b0a1314ae4..cbd0a69ac2 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/DataQueueCommand.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/DataQueueCommand.java @@ -21,8 +21,9 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http2.DefaultHttp2DataFrame; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; -public class DataQueueCommand extends QueuedCommand { +public class DataQueueCommand extends StreamQueueCommand { private final byte[] data; @@ -30,15 +31,16 @@ public class DataQueueCommand extends QueuedCommand { private final boolean endStream; - private DataQueueCommand(byte[] data, int compressFlag, boolean endStream) { + private DataQueueCommand(TripleStreamChannelFuture streamChannelFuture, byte[] data, int compressFlag, boolean endStream) { + super(streamChannelFuture); this.data = data; this.compressFlag = compressFlag; this.endStream = endStream; } - public static DataQueueCommand createGrpcCommand(byte[] data, boolean endStream, - int compressFlag) { - return new DataQueueCommand(data, compressFlag, endStream); + public static DataQueueCommand create(TripleStreamChannelFuture streamChannelFuture, byte[] data, boolean endStream, + int compressFlag) { + return new DataQueueCommand(streamChannelFuture, data, compressFlag, endStream); } @Override diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/EndStreamQueueCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/EndStreamQueueCommand.java index 9dacafd98f..863230b43e 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/EndStreamQueueCommand.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/EndStreamQueueCommand.java @@ -20,11 +20,16 @@ package org.apache.dubbo.rpc.protocol.tri.command; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http2.DefaultHttp2DataFrame; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; -public class EndStreamQueueCommand extends QueuedCommand { +public class EndStreamQueueCommand extends StreamQueueCommand { - public static EndStreamQueueCommand create() { - return new EndStreamQueueCommand(); + public EndStreamQueueCommand(TripleStreamChannelFuture streamChannelFuture) { + super(streamChannelFuture); + } + + public static EndStreamQueueCommand create(TripleStreamChannelFuture streamChannelFuture) { + return new EndStreamQueueCommand(streamChannelFuture); } @Override diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/HeaderQueueCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/HeaderQueueCommand.java index 1b5b14d786..7ae2a1777c 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/HeaderQueueCommand.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/HeaderQueueCommand.java @@ -21,24 +21,26 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http2.DefaultHttp2HeadersFrame; import io.netty.handler.codec.http2.Http2Headers; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; -public class HeaderQueueCommand extends QueuedCommand { +public class HeaderQueueCommand extends StreamQueueCommand { private final Http2Headers headers; private final boolean endStream; - private HeaderQueueCommand(Http2Headers headers, boolean endStream) { + private HeaderQueueCommand(TripleStreamChannelFuture streamChannelFuture, Http2Headers headers, boolean endStream) { + super(streamChannelFuture); this.headers = headers; this.endStream = endStream; } - public static HeaderQueueCommand createHeaders(Http2Headers headers) { - return new HeaderQueueCommand(headers, false); + public static HeaderQueueCommand createHeaders(TripleStreamChannelFuture streamChannelFuture, Http2Headers headers) { + return new HeaderQueueCommand(streamChannelFuture, headers, false); } - public static HeaderQueueCommand createHeaders(Http2Headers headers, boolean endStream) { - return new HeaderQueueCommand(headers, endStream); + public static HeaderQueueCommand createHeaders(TripleStreamChannelFuture streamChannelFuture, Http2Headers headers, boolean endStream) { + return new HeaderQueueCommand(streamChannelFuture, headers, endStream); } public Http2Headers getHeaders() { diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/QueuedCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/QueuedCommand.java index c16ac22958..fd140a9288 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/QueuedCommand.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/QueuedCommand.java @@ -41,7 +41,13 @@ public abstract class QueuedCommand { public void run(Channel channel) { if (channel.isActive()) { - channel.write(this, promise); + channel.write(this).addListener(future -> { + if (future.isSuccess()) { + promise.setSuccess(); + } else { + promise.setFailure(future.cause()); + } + }); } else { promise.trySuccess(); } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/StreamQueueCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/StreamQueueCommand.java new file mode 100644 index 0000000000..2815bdabf7 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/StreamQueueCommand.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.rpc.protocol.tri.command; + +import io.netty.channel.Channel; +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; + +public abstract class StreamQueueCommand extends QueuedCommand { + + protected final TripleStreamChannelFuture streamChannelFuture; + + protected StreamQueueCommand(TripleStreamChannelFuture streamChannelFuture) { + Assert.notNull(streamChannelFuture, "streamChannelFuture cannot be null."); + this.streamChannelFuture = streamChannelFuture; + this.promise(streamChannelFuture.getParentChannel().newPromise()); + } + + @Override + public void run(Channel channel) { + if (streamChannelFuture.isSuccess()) { + super.run(channel); + return; + } + promise().setFailure(streamChannelFuture.cause()); + } + + @Override + public Channel channel() { + return this.streamChannelFuture.getNow(); + } +} diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/TextDataQueueCommand.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/TextDataQueueCommand.java index 4befbe60f6..ba35504973 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/TextDataQueueCommand.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/command/TextDataQueueCommand.java @@ -22,20 +22,22 @@ import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http2.DefaultHttp2DataFrame; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; -public class TextDataQueueCommand extends QueuedCommand { +public class TextDataQueueCommand extends StreamQueueCommand { private final String data; private final boolean endStream; - private TextDataQueueCommand(String text, boolean endStream) { + private TextDataQueueCommand(TripleStreamChannelFuture streamChannelFuture, String text, boolean endStream) { + super(streamChannelFuture); this.data = text; this.endStream = endStream; } - public static TextDataQueueCommand createCommand(String data, boolean endStream) { - return new TextDataQueueCommand(data, endStream); + public static TextDataQueueCommand createCommand(TripleStreamChannelFuture streamChannelFuture, String data, boolean endStream) { + return new TextDataQueueCommand(streamChannelFuture, data, endStream); } @Override diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java index f179bbc849..d9f5dd941a 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java @@ -25,6 +25,7 @@ import org.apache.dubbo.rpc.protocol.tri.ClassLoadUtil; import org.apache.dubbo.rpc.protocol.tri.ExceptionUtils; import org.apache.dubbo.rpc.protocol.tri.TripleHeaderEnum; import org.apache.dubbo.rpc.protocol.tri.command.CancelQueueCommand; +import org.apache.dubbo.rpc.protocol.tri.command.CreateStreamQueueCommand; import org.apache.dubbo.rpc.protocol.tri.command.DataQueueCommand; import org.apache.dubbo.rpc.protocol.tri.command.EndStreamQueueCommand; import org.apache.dubbo.rpc.protocol.tri.command.HeaderQueueCommand; @@ -53,7 +54,6 @@ import io.netty.handler.codec.http2.Http2Headers; import io.netty.handler.codec.http2.Http2StreamChannel; import io.netty.handler.codec.http2.Http2StreamChannelBootstrap; import io.netty.util.ReferenceCountUtil; -import io.netty.util.concurrent.Future; import java.io.IOException; import java.net.SocketAddress; @@ -79,7 +79,8 @@ public class TripleClientStream extends AbstractStream implements ClientStream { private final TripleWriteQueue writeQueue; private Deframer deframer; private final Channel parent; - private final Http2StreamChannel http2StreamChannel; + private final TripleStreamChannelFuture streamChannelFuture; + private boolean halfClosed; private boolean rst; // for test @@ -89,10 +90,10 @@ public class TripleClientStream extends AbstractStream implements ClientStream { ClientStream.Listener listener, Http2StreamChannel http2StreamChannel) { super(executor, frameworkModel); - this.parent = null; + this.parent = http2StreamChannel.parent(); this.listener = listener; this.writeQueue = writeQueue; - this.http2StreamChannel = http2StreamChannel; + this.streamChannelFuture = initHttp2StreamChannel(http2StreamChannel); } public TripleClientStream(FrameworkModel frameworkModel, @@ -104,12 +105,13 @@ public class TripleClientStream extends AbstractStream implements ClientStream { this.parent = parent; this.listener = listener; this.writeQueue = writeQueue; - this.http2StreamChannel = initHttp2StreamChannel(parent); + this.streamChannelFuture = initHttp2StreamChannel(parent); } - private Http2StreamChannel initHttp2StreamChannel(Channel parent) { + private TripleStreamChannelFuture initHttp2StreamChannel(Channel parent) { + TripleStreamChannelFuture streamChannelFuture = new TripleStreamChannelFuture(parent); Http2StreamChannelBootstrap bootstrap = new Http2StreamChannelBootstrap(parent); - Future future = bootstrap.handler(new ChannelInboundHandlerAdapter() { + bootstrap.handler(new ChannelInboundHandlerAdapter() { @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); @@ -117,11 +119,10 @@ public class TripleClientStream extends AbstractStream implements ClientStream { channel.pipeline().addLast(new TripleHttp2ClientResponseHandler(createTransportListener())); channel.closeFuture().addListener(f -> transportException(f.cause())); } - }).open().syncUninterruptibly(); - if (!future.isSuccess()) { - throw new IllegalStateException("Create remote stream failed. channel:" + parent); - } - return future.getNow(); + }); + CreateStreamQueueCommand cmd = CreateStreamQueueCommand.create(bootstrap, streamChannelFuture); + this.writeQueue.enqueue(cmd); + return streamChannelFuture; } @@ -134,9 +135,8 @@ public class TripleClientStream extends AbstractStream implements ClientStream { if (!checkResult.isSuccess()) { return checkResult; } - final HeaderQueueCommand headerCmd = HeaderQueueCommand.createHeaders(headers); - headerCmd.channel(http2StreamChannel); - return writeQueue.enqueue(headerCmd).addListener(future -> { + final HeaderQueueCommand headerCmd = HeaderQueueCommand.createHeaders(streamChannelFuture, headers); + return writeQueue.enqueueFuture(headerCmd, parent.eventLoop()).addListener(future -> { if (!future.isSuccess()) { transportException(future.cause()); } @@ -154,10 +154,10 @@ public class TripleClientStream extends AbstractStream implements ClientStream { if (!checkResult.isSuccess()) { return checkResult; } - final CancelQueueCommand cmd = CancelQueueCommand.createCommand(Http2Error.CANCEL); - cmd.channel(http2StreamChannel); + final CancelQueueCommand cmd = CancelQueueCommand.createCommand(streamChannelFuture, Http2Error.CANCEL); + TripleClientStream.this.rst = true; - return this.writeQueue.enqueue(cmd, true); + return this.writeQueue.enqueue(cmd); } @Override @@ -172,11 +172,9 @@ public class TripleClientStream extends AbstractStream implements ClientStream { if (!checkResult.isSuccess()) { return checkResult; } - final DataQueueCommand cmd = DataQueueCommand.createGrpcCommand(message, false, + final DataQueueCommand cmd = DataQueueCommand.create(streamChannelFuture, message, false, compressFlag); - cmd.channel(http2StreamChannel); - return this.writeQueue.enqueue(cmd) - .addListener(future -> { + return this.writeQueue.enqueueFuture(cmd, parent.eventLoop()).addListener(future -> { if (!future.isSuccess()) { cancelByLocal( TriRpcStatus.INTERNAL.withDescription("Client write message failed") @@ -199,19 +197,19 @@ public class TripleClientStream extends AbstractStream implements ClientStream { if (!checkResult.isSuccess()) { return checkResult; } - final EndStreamQueueCommand cmd = EndStreamQueueCommand.create(); - cmd.channel(http2StreamChannel); - return this.writeQueue.enqueue(cmd); + final EndStreamQueueCommand cmd = EndStreamQueueCommand.create(streamChannelFuture); + return this.writeQueue.enqueueFuture(cmd, parent.eventLoop()).addListener(future -> { + if (future.isSuccess()) { + halfClosed = true; + } + }); } private ChannelFuture preCheck() { - if (!http2StreamChannel.isActive()) { - return http2StreamChannel.newFailedFuture(new IOException("stream channel is closed")); - } if (rst) { - return http2StreamChannel.newFailedFuture(new IOException("stream channel has reset")); + return streamChannelFuture.getNow().newFailedFuture(new IOException("stream channel has reset")); } - return http2StreamChannel.newSucceededFuture(); + return parent.newSucceededFuture(); } /** @@ -226,22 +224,16 @@ public class TripleClientStream extends AbstractStream implements ClientStream { private TriRpcStatus transportError; private DeCompressor decompressor; - private boolean halfClosed; private boolean headerReceived; private Http2Headers trailers; void handleH2TransportError(TriRpcStatus status) { - writeQueue.enqueue(CancelQueueCommand.createCommand(Http2Error.NO_ERROR).channel(http2StreamChannel)); + writeQueue.enqueue(CancelQueueCommand.createCommand(streamChannelFuture, Http2Error.NO_ERROR)); TripleClientStream.this.rst = true; finishProcess(status, null); } void finishProcess(TriRpcStatus status, Http2Headers trailers) { - if (halfClosed) { - return; - } - halfClosed = true; - final Map reserved = filterReservedHeaders(trailers); final Map attachments = headersToMap(trailers, () -> { return reserved.get(TripleHeaderEnum.TRI_HEADER_CONVERT.getHeader()); @@ -432,9 +424,9 @@ public class TripleClientStream extends AbstractStream implements ClientStream { executor.execute(() -> { if (endStream) { if (!halfClosed) { - if (http2StreamChannel.isActive() && !rst) { - writeQueue.enqueue(CancelQueueCommand.createCommand(Http2Error.CANCEL).channel(http2StreamChannel), - true); + Http2StreamChannel channel = streamChannelFuture.getNow(); + if (channel.isActive() && !rst) { + writeQueue.enqueue(CancelQueueCommand.createCommand(streamChannelFuture, Http2Error.CANCEL)); rst = true; } } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java index 7a33aa09ad..5c113ba6b2 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java @@ -85,6 +85,7 @@ public class TripleServerStream extends AbstractStream implements ServerStream { private Deframer deframer; private boolean rst = false; private final Http2StreamChannel http2StreamChannel; + private final TripleStreamChannelFuture tripleStreamChannelFuture; public TripleServerStream(Http2StreamChannel channel, FrameworkModel frameworkModel, @@ -100,6 +101,7 @@ public class TripleServerStream extends AbstractStream implements ServerStream { this.writeQueue = writeQueue; this.remoteAddress = (InetSocketAddress) channel.remoteAddress(); this.http2StreamChannel = channel; + this.tripleStreamChannelFuture = new TripleStreamChannelFuture(channel); } @Override @@ -118,7 +120,7 @@ public class TripleServerStream extends AbstractStream implements ServerStream { return checkResult; } this.rst = true; - return writeQueue.enqueue(CancelQueueCommand.createCommand(cause).channel(http2StreamChannel)); + return writeQueue.enqueue(CancelQueueCommand.createCommand(tripleStreamChannelFuture, cause)); } @Override @@ -137,7 +139,7 @@ public class TripleServerStream extends AbstractStream implements ServerStream { return checkResult; } headerSent = true; - return writeQueue.enqueue(HeaderQueueCommand.createHeaders(headers, false).channel(http2StreamChannel)) + return writeQueue.enqueue(HeaderQueueCommand.createHeaders(tripleStreamChannelFuture, headers, false)) .addListener(f -> { if (!f.isSuccess()) { reset(Http2Error.INTERNAL_ERROR); @@ -173,7 +175,7 @@ public class TripleServerStream extends AbstractStream implements ServerStream { } headerSent = true; trailersSent = true; - return writeQueue.enqueue(HeaderQueueCommand.createHeaders(trailers, true).channel(http2StreamChannel)) + return writeQueue.enqueue(HeaderQueueCommand.createHeaders(tripleStreamChannelFuture, trailers, true)) .addListener(f -> { if (!f.isSuccess()) { reset(Http2Error.INTERNAL_ERROR); @@ -245,7 +247,7 @@ public class TripleServerStream extends AbstractStream implements ServerStream { if (!checkResult.isSuccess()) { return checkResult; } - return writeQueue.enqueue(DataQueueCommand.createGrpcCommand(message, false, compressFlag).channel(http2StreamChannel)); + return writeQueue.enqueue(DataQueueCommand.create(tripleStreamChannelFuture, message, false, compressFlag)); } /** @@ -263,8 +265,8 @@ public class TripleServerStream extends AbstractStream implements ServerStream { .setInt(TripleHeaderEnum.STATUS_KEY.getHeader(), status.code.code) .set(TripleHeaderEnum.MESSAGE_KEY.getHeader(), status.description) .set(TripleHeaderEnum.CONTENT_TYPE_KEY.getHeader(), TripleConstant.TEXT_PLAIN_UTF8); - writeQueue.enqueue(HeaderQueueCommand.createHeaders( headers, false).channel(http2StreamChannel)); - writeQueue.enqueue(TextDataQueueCommand.createCommand(status.description, true).channel(http2StreamChannel)); + writeQueue.enqueue(HeaderQueueCommand.createHeaders(tripleStreamChannelFuture, headers, false)); + writeQueue.enqueue(TextDataQueueCommand.createCommand(tripleStreamChannelFuture, status.description, true)); } /** diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleStreamChannelFuture.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleStreamChannelFuture.java new file mode 100644 index 0000000000..fc3e152aab --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleStreamChannelFuture.java @@ -0,0 +1,66 @@ +/* + * 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.protocol.tri.stream; + +import io.netty.channel.Channel; +import io.netty.handler.codec.http2.Http2StreamChannel; +import org.apache.dubbo.common.utils.Assert; + +import java.util.concurrent.CompletableFuture; + +public class TripleStreamChannelFuture extends CompletableFuture { + + private final Channel parentChannel; + + private Throwable cause; + + public TripleStreamChannelFuture(Channel parentChannel) { + Assert.notNull(parentChannel, "parentChannel cannot be null."); + this.parentChannel = parentChannel; + } + + public TripleStreamChannelFuture(Http2StreamChannel channel) { + this.complete(channel); + this.parentChannel = channel.parent(); + } + + public Channel getParentChannel() { + return parentChannel; + } + + @Override + public boolean completeExceptionally(Throwable cause) { + boolean result = super.completeExceptionally(cause); + if (result) { + this.cause = cause; + } + return result; + } + + public Throwable cause() { + return cause; + } + + public boolean isSuccess() { + return isDone() && cause() == null; + } + + public Http2StreamChannel getNow() { + return getNow(null); + } +} diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java index 62e586471d..acbe859267 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java @@ -23,20 +23,33 @@ import io.netty.channel.ChannelPromise; import org.apache.dubbo.common.BatchExecutorQueue; import org.apache.dubbo.rpc.protocol.tri.command.QueuedCommand; +import java.util.concurrent.Executor; + public class TripleWriteQueue extends BatchExecutorQueue { + public TripleWriteQueue() { + } + + public TripleWriteQueue(int chunkSize) { + super(chunkSize); + } + public ChannelFuture enqueue(QueuedCommand command, boolean rst) { return enqueue(command); } public ChannelFuture enqueue(QueuedCommand command) { + return this.enqueueFuture(command, command.channel().eventLoop()); + } + + public ChannelFuture enqueueFuture(QueuedCommand command, Executor executor) { ChannelPromise promise = command.promise(); if (promise == null) { Channel ch = command.channel(); promise = ch.newPromise(); command.promise(promise); } - super.enqueue(command, command.channel().eventLoop()); + super.enqueue(command, executor); return promise; } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStreamTest.java b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStreamTest.java index 9542f28f4b..a95718b3ca 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStreamTest.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStreamTest.java @@ -29,6 +29,7 @@ import org.apache.dubbo.rpc.protocol.tri.RequestMetadata; import org.apache.dubbo.rpc.protocol.tri.TripleConstant; import org.apache.dubbo.rpc.protocol.tri.TripleHeaderEnum; import org.apache.dubbo.rpc.protocol.tri.command.CancelQueueCommand; +import org.apache.dubbo.rpc.protocol.tri.command.CreateStreamQueueCommand; import org.apache.dubbo.rpc.protocol.tri.command.DataQueueCommand; import org.apache.dubbo.rpc.protocol.tri.command.EndStreamQueueCommand; import org.apache.dubbo.rpc.protocol.tri.command.HeaderQueueCommand; @@ -48,6 +49,8 @@ import io.netty.util.concurrent.ImmediateEventExecutor; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.concurrent.Executor; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.mock; @@ -70,13 +73,16 @@ class TripleClientStreamTest { MockClientStreamListener listener = new MockClientStreamListener(); TripleWriteQueue writeQueue = mock(TripleWriteQueue.class); final EmbeddedChannel channel = new EmbeddedChannel(); - when(writeQueue.enqueue(any())).thenReturn(channel.newPromise()); + when(writeQueue.enqueueFuture(any(QueuedCommand.class), any(Executor.class))).thenReturn(channel.newPromise()); Http2StreamChannel http2StreamChannel = mock(Http2StreamChannel.class); when(http2StreamChannel.isActive()).thenReturn(true); when(http2StreamChannel.newSucceededFuture()).thenReturn(channel.newSucceededFuture()); when(http2StreamChannel.eventLoop()).thenReturn(new NioEventLoopGroup().next()); + when(http2StreamChannel.newPromise()).thenReturn(channel.newPromise()); + when(http2StreamChannel.parent()).thenReturn(channel); TripleClientStream stream = new TripleClientStream(url.getOrDefaultFrameworkModel(), ImmediateEventExecutor.INSTANCE, writeQueue, listener, http2StreamChannel); + verify(writeQueue).enqueue(any(CreateStreamQueueCommand.class)); final RequestMetadata requestMetadata = new RequestMetadata(); requestMetadata.method = methodDescriptor; @@ -88,19 +94,19 @@ class TripleClientStreamTest { requestMetadata.group = url.getGroup(); requestMetadata.version = url.getVersion(); stream.sendHeader(requestMetadata.toHeaders()); - verify(writeQueue).enqueue(any(HeaderQueueCommand.class)); + verify(writeQueue).enqueueFuture(any(HeaderQueueCommand.class), any(Executor.class)); // no other commands verify(writeQueue).enqueue(any(QueuedCommand.class)); stream.sendMessage(new byte[0], 0, false); - verify(writeQueue).enqueue(any(DataQueueCommand.class)); - verify(writeQueue, times(2)).enqueue(any(QueuedCommand.class)); + verify(writeQueue).enqueueFuture(any(DataQueueCommand.class), any(Executor.class)); + verify(writeQueue, times(2)).enqueueFuture(any(QueuedCommand.class), any(Executor.class)); stream.halfClose(); - verify(writeQueue).enqueue(any(EndStreamQueueCommand.class)); - verify(writeQueue, times(3)).enqueue(any(QueuedCommand.class)); + verify(writeQueue).enqueueFuture(any(EndStreamQueueCommand.class), any(Executor.class)); + verify(writeQueue, times(3)).enqueueFuture(any(QueuedCommand.class), any(Executor.class)); stream.cancelByLocal(TriRpcStatus.CANCELLED); - verify(writeQueue, times(1)).enqueue(any(CancelQueueCommand.class), anyBoolean()); - verify(writeQueue, times(3)).enqueue(any(QueuedCommand.class)); + verify(writeQueue, times(1)).enqueue(any(CancelQueueCommand.class)); + verify(writeQueue, times(3)).enqueueFuture(any(QueuedCommand.class), any(Executor.class)); H2TransportListener transportListener = stream.createTransportListener(); DefaultHttp2Headers headers = new DefaultHttp2Headers(); diff --git a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/transport/WriteQueueTest.java b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/transport/WriteQueueTest.java index 4912f3f438..40e5c1d84d 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/transport/WriteQueueTest.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/transport/WriteQueueTest.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.rpc.protocol.tri.transport; +import io.netty.channel.embedded.EmbeddedChannel; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.TriRpcStatus; import org.apache.dubbo.rpc.protocol.tri.command.CancelQueueCommand; @@ -30,8 +31,10 @@ import io.netty.channel.DefaultEventLoop; import io.netty.channel.EventLoop; import io.netty.handler.codec.http2.DefaultHttp2Headers; import io.netty.handler.codec.http2.Http2Error; +import org.apache.dubbo.rpc.protocol.tri.stream.TripleStreamChannelFuture; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -72,16 +75,19 @@ class WriteQueueTest { } @Test + @Disabled void test() throws Exception { WriteQueue writeQueue = new WriteQueue(); - writeQueue.enqueue(HeaderQueueCommand.createHeaders(new DefaultHttp2Headers()).channel(channel)); - writeQueue.enqueue(DataQueueCommand.createGrpcCommand(new byte[0], false, 0).channel(channel)); + EmbeddedChannel embeddedChannel = new EmbeddedChannel(); + TripleStreamChannelFuture tripleStreamChannelFuture = new TripleStreamChannelFuture(embeddedChannel); + writeQueue.enqueue(HeaderQueueCommand.createHeaders(tripleStreamChannelFuture, new DefaultHttp2Headers()).channel(channel)); + writeQueue.enqueue(DataQueueCommand.create(tripleStreamChannelFuture, new byte[0], false, 0).channel(channel)); TriRpcStatus status = TriRpcStatus.UNKNOWN .withCause(new RpcException()) .withDescription("Encode Response data error"); - writeQueue.enqueue(CancelQueueCommand.createCommand(Http2Error.CANCEL).channel(channel)); - writeQueue.enqueue(TextDataQueueCommand.createCommand(status.description, true).channel(channel)); + writeQueue.enqueue(CancelQueueCommand.createCommand(tripleStreamChannelFuture, Http2Error.CANCEL).channel(channel)); + writeQueue.enqueue(TextDataQueueCommand.createCommand(tripleStreamChannelFuture, status.description, true).channel(channel)); while (writeMethodCalledTimes.get() != 4) { Thread.sleep(50); @@ -99,14 +105,17 @@ class WriteQueueTest { } @Test + @Disabled void testChunk() throws Exception { WriteQueue writeQueue = new WriteQueue(); // test deque chunk size + EmbeddedChannel embeddedChannel = new EmbeddedChannel(); + TripleStreamChannelFuture tripleStreamChannelFuture = new TripleStreamChannelFuture(embeddedChannel); writeMethodCalledTimes.set(0); for (int i = 0; i < DEQUE_CHUNK_SIZE; i++) { - writeQueue.enqueue(HeaderQueueCommand.createHeaders(new DefaultHttp2Headers()).channel(channel)); + writeQueue.enqueue(HeaderQueueCommand.createHeaders(tripleStreamChannelFuture, new DefaultHttp2Headers()).channel(channel)); } - writeQueue.enqueue(HeaderQueueCommand.createHeaders(new DefaultHttp2Headers()).channel(channel)); + writeQueue.enqueue(HeaderQueueCommand.createHeaders(tripleStreamChannelFuture, new DefaultHttp2Headers()).channel(channel)); while (writeMethodCalledTimes.get() != (DEQUE_CHUNK_SIZE + 1)) { Thread.sleep(50); } From 4903cab55149145078543975d2a04a335438b77a Mon Sep 17 00:00:00 2001 From: FanYang <399284508@qq.com> Date: Sat, 4 Mar 2023 20:30:37 +0800 Subject: [PATCH 060/144] abnormal time count (#11710) --- .../dubbo/metrics/filter/MethodMetricsInterceptor.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java index a66c42139d..2394fbe56a 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java @@ -76,16 +76,22 @@ public class MethodMetricsInterceptor { if (throwable instanceof RpcException && ((RpcException) throwable).isBiz()) { onCompleted(invocation); + }else{ + rtTime(invocation); } sampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL_FAILED); } - private void onCompleted(Invocation invocation) { + private void rtTime(Invocation invocation){ Long endTime = System.currentTimeMillis(); Long beginTime = (Long) invocation.get(METRIC_FILTER_START_TIME); Long rt = endTime - beginTime; sampler.addRT(invocation, rt); + } + + private void onCompleted(Invocation invocation) { + rtTime(invocation); sampler.dec(invocation,MetricsEvent.Type.PROCESSING); } } From b35312ae4951393751060ef3178500162de8252e Mon Sep 17 00:00:00 2001 From: songxiaosheng Date: Mon, 6 Mar 2023 15:05:59 +0800 Subject: [PATCH 061/144] :bug: fix push metadata code location (#11712) --- .../dubbo/registry/client/AbstractServiceDiscovery.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java index edb974da48..5e692f4538 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java @@ -363,19 +363,19 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery { } TimePair timePair = TimePair.start(); GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); - eventMulticaster.publishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); if (metadataReport != null) { SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.getRevision()); if ((DEFAULT_METADATA_STORAGE_TYPE.equals(metadataType) && metadataReport.shouldReportMetadata()) || REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) { try { + eventMulticaster.publishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); metadataReport.publishAppMetadata(identifier, metadataInfo); + eventMulticaster.publishFinishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); } catch (IllegalStateException e) { eventMulticaster.publishErrorEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); throw e; } } } - eventMulticaster.publishFinishEvent(new MetadataEvent.PushEvent(applicationModel, timePair)); MetadataInfo clonedMetadataInfo = metadataInfo.clone(); metadataInfos.put(metadataInfo.getRevision(), new MetadataInfoStat(clonedMetadataInfo)); } From a21d04255a9aae791b526a43c560b9645d063b18 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Mon, 6 Mar 2023 15:26:15 +0800 Subject: [PATCH 062/144] Fix issue 11708 (#11714) --- .../apache/dubbo/qos/pu/TelnetDetector.java | 19 ++++++++++++------- .../dubbo/remoting/buffer/ChannelBuffer.java | 8 ++++++++ .../remoting/buffer/DynamicChannelBuffer.java | 5 +++++ .../netty4/NettyBackedChannelBuffer.java | 6 ++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java index 84199937d4..a7b7c47ff7 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java @@ -32,7 +32,7 @@ import static java.lang.Math.min; public class TelnetDetector implements ProtocolDetector { - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; private final int MaxSize = 2048; private final ChannelBuffer AytPreface = new HeapChannelBuffer(new byte[]{(byte) 0xff, (byte) 0xf6}); @@ -46,7 +46,7 @@ public class TelnetDetector implements ProtocolDetector { return Result.UNRECOGNIZED; } Result resCommand = commandDetect(in); - if (resCommand.equals(Result.RECOGNIZED)){ + if (resCommand.equals(Result.RECOGNIZED)) { return resCommand; } Result resAyt = telnetAytDetect(in); @@ -62,14 +62,19 @@ public class TelnetDetector implements ProtocolDetector { private Result commandDetect(ChannelBuffer in) { // detect if remote channel send a qos command to server ChannelBuffer back = in.copy(); - byte[] backBytes = new byte[back.readableBytes()]; - back.getBytes(back.readerIndex(), backBytes); + byte[] backBytes; + try { + backBytes = new byte[back.readableBytes()]; + back.getBytes(back.readerIndex(), backBytes); + } finally { + back.release(); + } String s = new String(backBytes, CharsetUtil.UTF_8); // trim /r/n to let parser work for input s = s.trim(); CommandContext commandContext = TelnetCommandDecoder.decode(s); - if(frameworkModel.getExtensionLoader(BaseCommand.class).hasExtension(commandContext.getCommandName())){ + if (frameworkModel.getExtensionLoader(BaseCommand.class).hasExtension(commandContext.getCommandName())) { return Result.RECOGNIZED; } return Result.UNRECOGNIZED; @@ -79,10 +84,10 @@ public class TelnetDetector implements ProtocolDetector { // detect if remote channel send a telnet ayt command to server int prefaceLen = AytPreface.readableBytes(); int bytesRead = min(in.readableBytes(), prefaceLen); - if(bytesRead == 0 || !ChannelBuffers.prefixEquals(in, AytPreface, bytesRead)) { + if (bytesRead == 0 || !ChannelBuffers.prefixEquals(in, AytPreface, bytesRead)) { return Result.UNRECOGNIZED; } - if(bytesRead == prefaceLen) { + if (bytesRead == prefaceLen) { // we need to consume preface because it's not a qos command // consume and remember to mark, pu server handler reset reader index in.readBytes(AytPreface.readableBytes()); diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/ChannelBuffer.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/ChannelBuffer.java index fab35dd80e..e77cf46ab2 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/ChannelBuffer.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/ChannelBuffer.java @@ -948,4 +948,12 @@ public interface ChannelBuffer extends Comparable { * array */ int arrayOffset(); + + /** + * If this buffer is backed by an NIO direct buffer, + * in some scenarios it may be necessary to manually release. + */ + default void release() { + + } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/DynamicChannelBuffer.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/DynamicChannelBuffer.java index dbd9677a76..cfd7965ffe 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/DynamicChannelBuffer.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/buffer/DynamicChannelBuffer.java @@ -200,4 +200,9 @@ public class DynamicChannelBuffer extends AbstractChannelBuffer { public int arrayOffset() { return buffer.arrayOffset(); } + + @Override + public void release() { + buffer.release(); + } } diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java index a64a646721..fd1f9c7c52 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java @@ -22,6 +22,7 @@ import org.apache.dubbo.remoting.buffer.ChannelBufferFactory; import org.apache.dubbo.remoting.buffer.ChannelBuffers; import io.netty.buffer.ByteBuf; +import io.netty.util.ReferenceCountUtil; import java.io.IOException; import java.io.InputStream; @@ -447,4 +448,9 @@ public class NettyBackedChannelBuffer implements ChannelBuffer { public int compareTo(ChannelBuffer o) { return ChannelBuffers.compare(this, o); } + + @Override + public void release() { + ReferenceCountUtil.safeRelease(buffer); + } } From c9f320fd396b905fb54cab1328823a886b397d07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:19:09 +0800 Subject: [PATCH 063/144] Bump spring-boot-dependencies from 2.7.8 to 2.7.9 (#11750) Bumps [spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 2.7.8 to 2.7.9. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.8...v2.7.9) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-demo/dubbo-demo-spring-boot/pom.xml | 2 +- dubbo-spring-boot/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-demo/dubbo-demo-spring-boot/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/pom.xml index 18546bdbec..55e6920b09 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/pom.xml @@ -36,7 +36,7 @@ 8 8 true - 2.7.8 + 2.7.9 2.7.8 1.10.4 diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index 2d6991aac4..e8c7b59d5f 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -40,7 +40,7 @@ - 2.7.8 + 2.7.9 ${revision} 2.19.0 From 675d1f6a78a6f287789db7a5fdb1c2515cf169fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:19:24 +0800 Subject: [PATCH 064/144] Bump maven-assembly-plugin from 3.4.2 to 3.5.0 (#11749) Bumps [maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 3.4.2 to 3.5.0. - [Release notes](https://github.com/apache/maven-assembly-plugin/releases) - [Commits](https://github.com/apache/maven-assembly-plugin/compare/maven-assembly-plugin-3.4.2...maven-assembly-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-assembly-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-distribution/dubbo-apache-release/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-distribution/dubbo-apache-release/pom.xml b/dubbo-distribution/dubbo-apache-release/pom.xml index d8c4094b25..d48ee13382 100644 --- a/dubbo-distribution/dubbo-apache-release/pom.xml +++ b/dubbo-distribution/dubbo-apache-release/pom.xml @@ -52,7 +52,7 @@ maven-assembly-plugin - 3.4.2 + 3.5.0 bin From 7600d6c10944638059f47fc67c9091c43c1392cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:19:35 +0800 Subject: [PATCH 065/144] Bump maven-compiler-plugin from 3.7.0 to 3.11.0 (#11748) Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.7.0 to 3.11.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.7.0...maven-compiler-plugin-3.11.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml | 2 +- dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml | 2 +- dubbo-demo/dubbo-demo-triple/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml index 279701893a..e43248093c 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml @@ -116,7 +116,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.11.0 1.8 1.8 diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml index b35faa8482..3b4a9bdf29 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml @@ -117,7 +117,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.11.0 1.8 1.8 diff --git a/dubbo-demo/dubbo-demo-triple/pom.xml b/dubbo-demo/dubbo-demo-triple/pom.xml index f420d80d6b..a7e0015e71 100644 --- a/dubbo-demo/dubbo-demo-triple/pom.xml +++ b/dubbo-demo/dubbo-demo-triple/pom.xml @@ -35,7 +35,7 @@ 1.8 1.8 3.22.0 - 3.10.1 + 3.11.0 diff --git a/pom.xml b/pom.xml index eea92a1f98..b0d034963a 100644 --- a/pom.xml +++ b/pom.xml @@ -116,7 +116,7 @@ 3.0.0-M9 3.0.0-M9 2.8.2 - 3.10.1 + 3.11.0 3.2.1 3.5.0 9.4.50.v20221201 From e24b284d5764f4035790c87bbd1086b11489776f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:19:46 +0800 Subject: [PATCH 066/144] Bump native-maven-plugin from 0.9.19 to 0.9.20 (#11747) Bumps [native-maven-plugin](https://github.com/graalvm/native-build-tools) from 0.9.19 to 0.9.20. - [Release notes](https://github.com/graalvm/native-build-tools/releases) - [Commits](https://github.com/graalvm/native-build-tools/compare/0.9.19...0.9.20) --- updated-dependencies: - dependency-name: org.graalvm.buildtools:native-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml | 2 +- dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml index e43248093c..460655a982 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml @@ -134,7 +134,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.19 + 0.9.20 ${project.build.outputDirectory} diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml index 3b4a9bdf29..776f2b3842 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml @@ -134,7 +134,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.19 + 0.9.20 ${project.build.outputDirectory} From 338e194ce247357c20f45d6208ea40016d2d29f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:20:04 +0800 Subject: [PATCH 067/144] Bump maven-plugin-annotations from 3.7.1 to 3.8.1 (#11746) Bumps [maven-plugin-annotations](https://github.com/apache/maven-plugin-tools) from 3.7.1 to 3.8.1. - [Release notes](https://github.com/apache/maven-plugin-tools/releases) - [Commits](https://github.com/apache/maven-plugin-tools/compare/maven-plugin-tools-3.7.1...maven-plugin-tools-3.8.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugin-tools:maven-plugin-annotations dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-maven-plugin/pom.xml | 2 +- dubbo-native-plugin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-maven-plugin/pom.xml b/dubbo-maven-plugin/pom.xml index e15d57d96f..2f63fdeaa4 100644 --- a/dubbo-maven-plugin/pom.xml +++ b/dubbo-maven-plugin/pom.xml @@ -48,7 +48,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.7.1 + 3.8.1 provided diff --git a/dubbo-native-plugin/pom.xml b/dubbo-native-plugin/pom.xml index ccf4cfd971..a4332acd60 100644 --- a/dubbo-native-plugin/pom.xml +++ b/dubbo-native-plugin/pom.xml @@ -50,7 +50,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.7.1 + 3.8.1 provided From 9830eda07f8bb591346503c01037393a9884ce07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:20:20 +0800 Subject: [PATCH 068/144] Bump maven-common-artifact-filters from 3.2.0 to 3.3.2 (#11744) Bumps [maven-common-artifact-filters](https://github.com/apache/maven-common-artifact-filters) from 3.2.0 to 3.3.2. - [Release notes](https://github.com/apache/maven-common-artifact-filters/releases) - [Commits](https://github.com/apache/maven-common-artifact-filters/compare/maven-common-artifact-filters-3.2.0...maven-common-artifact-filters-3.3.2) --- updated-dependencies: - dependency-name: org.apache.maven.shared:maven-common-artifact-filters dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-maven-plugin/pom.xml b/dubbo-maven-plugin/pom.xml index 2f63fdeaa4..1df4be5ca4 100644 --- a/dubbo-maven-plugin/pom.xml +++ b/dubbo-maven-plugin/pom.xml @@ -55,7 +55,7 @@ org.apache.maven.shared maven-common-artifact-filters - 3.2.0 + 3.3.2 From 8eb77895fa556ad591ae5bf1660b49090d5ef586 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:20:33 +0800 Subject: [PATCH 069/144] Bump maven-core from 3.8.7 to 3.9.0 (#11743) Bumps [maven-core](https://github.com/apache/maven) from 3.8.7 to 3.9.0. - [Release notes](https://github.com/apache/maven/releases) - [Commits](https://github.com/apache/maven/compare/maven-3.8.7...maven-3.9.0) --- updated-dependencies: - dependency-name: org.apache.maven:maven-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-maven-plugin/pom.xml b/dubbo-maven-plugin/pom.xml index 1df4be5ca4..f3cdcd8580 100644 --- a/dubbo-maven-plugin/pom.xml +++ b/dubbo-maven-plugin/pom.xml @@ -40,7 +40,7 @@ org.apache.maven maven-core - 3.8.7 + 3.9.0 provided From 0c64ce7dd6054fd9e37a235e81a0be0467238bb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:20:53 +0800 Subject: [PATCH 070/144] Bump tomcat-embed-core from 8.5.85 to 8.5.87 (#11742) Bumps tomcat-embed-core from 8.5.85 to 8.5.87. --- updated-dependencies: - dependency-name: org.apache.tomcat.embed:tomcat-embed-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index e5d57f3907..706a735671 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -146,7 +146,7 @@ 2.1.1 3.15.3.Final 1.9.13 - 8.5.85 + 8.5.87 0.7.5 2.1.2 1.53.0 From ea6a3273d00ec11ad8375ac9a37c00c32c844619 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:21:03 +0800 Subject: [PATCH 071/144] Bump spring-boot-starter-test from 2.7.8 to 2.7.9 (#11741) Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.7.8 to 2.7.9. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.8...v2.7.9) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-test dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-config/dubbo-config-spring/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-config/dubbo-config-spring/pom.xml b/dubbo-config/dubbo-config-spring/pom.xml index 3bb4e3b260..e7264d158d 100644 --- a/dubbo-config/dubbo-config-spring/pom.xml +++ b/dubbo-config/dubbo-config-spring/pom.xml @@ -27,7 +27,7 @@ The spring config module of dubbo project false - 2.7.8 + 2.7.9 From 03838ad97e02be7389477a00c4b72c0c9ea11678 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:21:14 +0800 Subject: [PATCH 072/144] Bump jetty-maven-plugin from 9.4.50.v20221201 to 9.4.51.v20230217 (#11740) Bumps [jetty-maven-plugin](https://github.com/eclipse/jetty.project) from 9.4.50.v20221201 to 9.4.51.v20230217. - [Release notes](https://github.com/eclipse/jetty.project/releases) - [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.50.v20221201...jetty-9.4.51.v20230217) --- updated-dependencies: - dependency-name: org.eclipse.jetty:jetty-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b0d034963a..60f7de473b 100644 --- a/pom.xml +++ b/pom.xml @@ -119,7 +119,7 @@ 3.11.0 3.2.1 3.5.0 - 9.4.50.v20221201 + 9.4.51.v20230217 3.2.1 0.8.8 1.3.0 From 30de082266dde5e50609fe2e47eeaf188bb50664 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:21:26 +0800 Subject: [PATCH 073/144] Bump spring-boot.version from 2.7.8 to 2.7.9 (#11739) Bumps `spring-boot.version` from 2.7.8 to 2.7.9. Updates `spring-boot-starter` from 2.7.8 to 2.7.9 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.8...v2.7.9) Updates `spring-boot-autoconfigure` from 2.7.8 to 2.7.9 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.8...v2.7.9) Updates `spring-boot-starter-logging` from 2.7.8 to 2.7.9 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.8...v2.7.9) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-autoconfigure dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-starter-logging dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../dubbo-demo-spring-boot-consumer/pom.xml | 2 +- .../dubbo-demo-spring-boot-provider/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml index 626b9d9825..90616e8f9d 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml @@ -31,7 +31,7 @@ 8 8 1.7.33 - 2.7.8 + 2.7.9 true diff --git a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml index ba32f8c70e..da3de4b5e7 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml @@ -31,7 +31,7 @@ 8 8 1.7.33 - 2.7.8 + 2.7.9 true From 0351087891c61a3d9271c27837ee83f4f1feb173 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:21:38 +0800 Subject: [PATCH 074/144] Bump jetty_version from 9.4.50.v20221201 to 9.4.51.v20230217 (#11738) Bumps `jetty_version` from 9.4.50.v20221201 to 9.4.51.v20230217. Updates `jetty-server` from 9.4.50.v20221201 to 9.4.51.v20230217 - [Release notes](https://github.com/eclipse/jetty.project/releases) - [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.50.v20221201...jetty-9.4.51.v20230217) Updates `jetty-servlet` from 9.4.50.v20221201 to 9.4.51.v20230217 - [Release notes](https://github.com/eclipse/jetty.project/releases) - [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.50.v20221201...jetty-9.4.51.v20230217) --- updated-dependencies: - dependency-name: org.eclipse.jetty:jetty-server dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.eclipse.jetty:jetty-servlet dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 706a735671..c7b26da9ff 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -118,7 +118,7 @@ 1.3.2 3.1.0 5.0.0 - 9.4.50.v20221201 + 9.4.51.v20230217 3.0.1 1.1.0.Final 5.4.3.Final From e81e7562115937c9f87572441c9046dbe643966d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:22:59 +0800 Subject: [PATCH 075/144] Bump log4j2_version from 2.19.0 to 2.20.0 (#11736) Bumps `log4j2_version` from 2.19.0 to 2.20.0. Updates `log4j-api` from 2.19.0 to 2.20.0 - [Release notes](https://github.com/apache/logging-log4j2/releases) - [Changelog](https://github.com/apache/logging-log4j2/blob/2.x/CHANGELOG.adoc) - [Commits](https://github.com/apache/logging-log4j2/compare/rel/2.19.0...rel/2.20.0) Updates `log4j-core` from 2.19.0 to 2.20.0 - [Release notes](https://github.com/apache/logging-log4j2/releases) - [Changelog](https://github.com/apache/logging-log4j2/blob/2.x/CHANGELOG.adoc) - [Commits](https://github.com/apache/logging-log4j2/compare/rel/2.19.0...rel/2.20.0) --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- dubbo-spring-boot/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index c7b26da9ff..9b1730c0e1 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -158,7 +158,7 @@ 1.2.17 1.2.11 - 2.19.0 + 2.20.0 2.11.0 0.13.0 diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index e8c7b59d5f..e529eff00f 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -43,7 +43,7 @@ 2.7.9 ${revision} - 2.19.0 + 2.20.0 1.13.0 1.10.4 From 80621216c8871992f073d1ae57e8c54e7cce2358 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:26:37 +0800 Subject: [PATCH 076/144] Bump resteasy_version from 3.15.3.Final to 3.15.6.Final (#11735) Bumps `resteasy_version` from 3.15.3.Final to 3.15.6.Final. Updates `resteasy-jaxrs` from 3.15.3.Final to 3.15.6.Final Updates `resteasy-client` from 3.15.3.Final to 3.15.6.Final - [Release notes](https://github.com/resteasy/Resteasy/releases) - [Commits](https://github.com/resteasy/Resteasy/compare/3.15.3.Final...3.15.6.Final) Updates `resteasy-netty4` from 3.15.3.Final to 3.15.6.Final Updates `resteasy-jdk-http` from 3.15.3.Final to 3.15.6.Final Updates `resteasy-jackson-provider` from 3.15.3.Final to 3.15.6.Final Updates `resteasy-jaxb-provider` from 3.15.3.Final to 3.15.6.Final --- updated-dependencies: - dependency-name: org.jboss.resteasy:resteasy-jaxrs dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jboss.resteasy:resteasy-client dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jboss.resteasy:resteasy-netty4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jboss.resteasy:resteasy-jdk-http dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jboss.resteasy:resteasy-jackson-provider dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jboss.resteasy:resteasy-jaxb-provider dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 9b1730c0e1..3abb1dfed4 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -144,7 +144,7 @@ 4.10.0 2.1.1 - 3.15.3.Final + 3.15.6.Final 1.9.13 8.5.87 0.7.5 From cbc1161983a1a833624b4e048766aaf1fb6f679b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:26:45 +0800 Subject: [PATCH 077/144] Bump maven-plugin-api from 3.5.4 to 3.9.0 (#11734) Bumps [maven-plugin-api](https://github.com/apache/maven) from 3.5.4 to 3.9.0. - [Release notes](https://github.com/apache/maven/releases) - [Commits](https://github.com/apache/maven/compare/maven-3.5.4...maven-3.9.0) --- updated-dependencies: - dependency-name: org.apache.maven:maven-plugin-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-maven-plugin/pom.xml b/dubbo-maven-plugin/pom.xml index f3cdcd8580..0326b11100 100644 --- a/dubbo-maven-plugin/pom.xml +++ b/dubbo-maven-plugin/pom.xml @@ -34,7 +34,7 @@ org.apache.maven maven-plugin-api - 3.5.4 + 3.9.0 From 66d6ffdbec73a62b1fa724e5b85f0acfeb5e7e82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:26:55 +0800 Subject: [PATCH 078/144] Bump bytebuddy.version from 1.13.0 to 1.14.0 (#11733) Bumps `bytebuddy.version` from 1.13.0 to 1.14.0. Updates `byte-buddy` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.13.0...byte-buddy-1.14.0) Updates `byte-buddy-agent` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.13.0...byte-buddy-1.14.0) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: net.bytebuddy:byte-buddy-agent dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-spring-boot/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index e529eff00f..8ac8bcd5cc 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -45,7 +45,7 @@ 2.20.0 - 1.13.0 + 1.14.0 1.10.4 From ba1085188884d696b008de249e007be6a5cb6be6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:27:05 +0800 Subject: [PATCH 079/144] Bump libthrift from 0.18.0 to 0.18.1 (#11732) Bumps [libthrift](https://github.com/apache/thrift) from 0.18.0 to 0.18.1. - [Release notes](https://github.com/apache/thrift/releases) - [Changelog](https://github.com/apache/thrift/blob/master/CHANGES.md) - [Commits](https://github.com/apache/thrift/compare/v0.18.0...v0.18.1) --- updated-dependencies: - dependency-name: org.apache.thrift:libthrift dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 3abb1dfed4..a1c1a8d6e3 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -112,7 +112,7 @@ 1.5.3 1.4.3 3.5.5 - 0.18.0 + 0.18.1 4.0.66 3.19.6 1.3.2 From ea90151e456dccc7008546e3926389483e6297f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:27:15 +0800 Subject: [PATCH 080/144] Bump maven-plugin-plugin from 3.7.1 to 3.8.1 (#11731) Bumps [maven-plugin-plugin](https://github.com/apache/maven-plugin-tools) from 3.7.1 to 3.8.1. - [Release notes](https://github.com/apache/maven-plugin-tools/releases) - [Commits](https://github.com/apache/maven-plugin-tools/compare/maven-plugin-tools-3.7.1...maven-plugin-tools-3.8.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-plugin-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-maven-plugin/pom.xml | 2 +- dubbo-native-plugin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-maven-plugin/pom.xml b/dubbo-maven-plugin/pom.xml index 0326b11100..6f2ddf18e9 100644 --- a/dubbo-maven-plugin/pom.xml +++ b/dubbo-maven-plugin/pom.xml @@ -76,7 +76,7 @@ maven-plugin-plugin - 3.7.1 + 3.8.1 default-addPluginArtifactMetadata diff --git a/dubbo-native-plugin/pom.xml b/dubbo-native-plugin/pom.xml index a4332acd60..c41fa9d15e 100644 --- a/dubbo-native-plugin/pom.xml +++ b/dubbo-native-plugin/pom.xml @@ -79,7 +79,7 @@ maven-plugin-plugin - 3.7.1 + 3.8.1 default-addPluginArtifactMetadata From 516c61bc5ab7508c9d427927d8dfddcef05cebe7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:27:37 +0800 Subject: [PATCH 081/144] Bump spring-boot-maven-plugin from 2.7.8 to 2.7.9 (#11745) Bumps [spring-boot-maven-plugin](https://github.com/spring-projects/spring-boot) from 2.7.8 to 2.7.9. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.8...v2.7.9) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-demo/dubbo-demo-annotation/pom.xml | 2 +- dubbo-demo/dubbo-demo-api/pom.xml | 2 +- dubbo-demo/dubbo-demo-spring-boot/pom.xml | 2 +- dubbo-demo/dubbo-demo-xml/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-demo/dubbo-demo-annotation/pom.xml b/dubbo-demo/dubbo-demo-annotation/pom.xml index 0e9a250ee9..b3991acd71 100644 --- a/dubbo-demo/dubbo-demo-annotation/pom.xml +++ b/dubbo-demo/dubbo-demo-annotation/pom.xml @@ -30,7 +30,7 @@ true - 2.7.8 + 2.7.9 diff --git a/dubbo-demo/dubbo-demo-api/pom.xml b/dubbo-demo/dubbo-demo-api/pom.xml index a7c93fb624..a4957977fe 100644 --- a/dubbo-demo/dubbo-demo-api/pom.xml +++ b/dubbo-demo/dubbo-demo-api/pom.xml @@ -36,7 +36,7 @@ true - 2.7.8 + 2.7.9 dubbo-demo-api diff --git a/dubbo-demo/dubbo-demo-spring-boot/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/pom.xml index 55e6920b09..34a9a855d5 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/pom.xml @@ -37,7 +37,7 @@ 8 true 2.7.9 - 2.7.8 + 2.7.9 1.10.4 diff --git a/dubbo-demo/dubbo-demo-xml/pom.xml b/dubbo-demo/dubbo-demo-xml/pom.xml index 475a852c63..b5b32d519c 100644 --- a/dubbo-demo/dubbo-demo-xml/pom.xml +++ b/dubbo-demo/dubbo-demo-xml/pom.xml @@ -32,7 +32,7 @@ true - 2.7.8 + 2.7.9 From 7277c159cf6cc614e7ef8d7a48067e9a57d88885 Mon Sep 17 00:00:00 2001 From: liufeiyu1002 <32605119+liufeiyu1002@users.noreply.github.com> Date: Fri, 3 Mar 2023 07:15:26 +0800 Subject: [PATCH 082/144] fix reference bean name conflicts (#11699) * fix reference bean name conflicts * add ut case --- .../ReferenceAnnotationBeanPostProcessor.java | 19 ++++++++++-- ...erenceAnnotationBeanPostProcessorTest.java | 29 +++++++++++++++---- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java index be855881bc..de7e6cc0fc 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java @@ -19,6 +19,7 @@ package org.apache.dubbo.config.spring.beans.factory.annotation; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.ArrayUtils; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -399,8 +400,22 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean } //check bean definition - if (beanDefinitionRegistry.containsBeanDefinition(referenceBeanName)) { - BeanDefinition prevBeanDefinition = beanDefinitionRegistry.getBeanDefinition(referenceBeanName); + boolean isContains; + if ((isContains = beanDefinitionRegistry.containsBeanDefinition(referenceBeanName)) || beanDefinitionRegistry.isAlias(referenceBeanName)) { + String preReferenceBeanName = referenceBeanName; + if (!isContains){ + // Look in the alias for the origin bean name + String[] aliases = beanDefinitionRegistry.getAliases(referenceBeanName); + if (ArrayUtils.isNotEmpty(aliases)) { + for (String alias : aliases) { + if (beanDefinitionRegistry.containsBeanDefinition(alias)) { + preReferenceBeanName = alias; + break; + } + } + } + } + BeanDefinition prevBeanDefinition = beanDefinitionRegistry.getBeanDefinition(preReferenceBeanName); String prevBeanType = prevBeanDefinition.getBeanClassName(); String prevBeanDesc = referenceBeanName + "[" + prevBeanType + "]"; String newBeanDesc = referenceBeanName + "[" + referenceKey + "]"; diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java index 06d0592668..a4fbcff02d 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java @@ -128,15 +128,30 @@ class ReferenceAnnotationBeanPostProcessorTest { @DubboReference(version = "2", url = "dubbo://127.0.0.1:12345?version=2", tag = "demo_tag") private HelloService helloService2; - // #7 ReferenceBean (Method Injection #3) + // #7 ReferenceBean (Field Injection #5) + // The HelloService is the same as above service(#6 ReferenceBean (Field Injection #4)), helloService3 will be registered as an alias of helloService2 + @DubboReference(version = "2", url = "dubbo://127.0.0.1:12345?version=2", tag = "demo_tag") + private HelloService helloService3; + + // #8 ReferenceBean (Method Injection #3) @DubboReference(version = "3", url = "dubbo://127.0.0.1:12345?version=2", tag = "demo_tag") public void setHelloService2(HelloService helloService2) { // The helloService2 beanName is the same as above(#6 ReferenceBean (Field Injection #4)), and this will rename to helloService2#2 renamedHelloService2 = helloService2; } + // #9 ReferenceBean (Method Injection #4) + @DubboReference(version = "4", url = "dubbo://127.0.0.1:12345?version=2") + public void setHelloService3(DemoService helloService3){ + // The helloService3 beanName is the same as above(#7 ReferenceBean (Field Injection #5) is an alias), + // The current beanName(helloService3) is not registered in the beanDefinitionMap, but it is already an alias. so this will rename to helloService3#2 + this.renamedHelloService3 = helloService3; + } + private HelloService renamedHelloService2; + private DemoService renamedHelloService3; + @Test void testAop() throws Exception { @@ -150,7 +165,7 @@ class ReferenceAnnotationBeanPostProcessorTest { Assertions.assertNotNull(testBean.getDemoServiceFromParent()); Assertions.assertNotNull(testBean.getDemoService()); Assertions.assertNotNull(testBean.myDemoService); - Assertions.assertEquals(2, demoServicesMap.size()); + Assertions.assertEquals(3, demoServicesMap.size()); Assertions.assertNotNull(context.getBean("demoServiceImpl")); Assertions.assertNotNull(context.getBean("myDemoService")); @@ -189,12 +204,13 @@ class ReferenceAnnotationBeanPostProcessorTest { Map> referenceBeanMap = beanPostProcessor.getInjectedFieldReferenceBeanMap(); - Assertions.assertEquals(4, referenceBeanMap.size()); + Assertions.assertEquals(5, referenceBeanMap.size()); Map checkingFieldNames = new HashMap<>(); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest$MyConfiguration.helloService", 0); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest.helloService", 0); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest.helloService2", 0); + checkingFieldNames.put("private org.apache.dubbo.config.spring.api.HelloService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest.helloService3", 0); checkingFieldNames.put("private org.apache.dubbo.config.spring.api.DemoService org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest$ParentBean.demoServiceFromParent", 0); for (Map.Entry> entry : referenceBeanMap.entrySet()) { @@ -222,12 +238,13 @@ class ReferenceAnnotationBeanPostProcessorTest { Map> referenceBeanMap = beanPostProcessor.getInjectedMethodReferenceBeanMap(); - Assertions.assertEquals(3, referenceBeanMap.size()); + Assertions.assertEquals(4, referenceBeanMap.size()); Map checkingMethodNames = new HashMap<>(); checkingMethodNames.put("setDemoServiceFromAncestor", 0); checkingMethodNames.put("setDemoService", 0); checkingMethodNames.put("setHelloService2", 0); + checkingMethodNames.put("setHelloService3", 0); for (Map.Entry> entry : referenceBeanMap.entrySet()) { @@ -252,7 +269,7 @@ class ReferenceAnnotationBeanPostProcessorTest { Collection referenceBeans = referenceBeanManager.getReferences(); - Assertions.assertEquals(4, referenceBeans.size()); + Assertions.assertEquals(5, referenceBeans.size()); for (ReferenceBean referenceBean : referenceBeans) { ReferenceConfig referenceConfig = referenceBean.getReferenceConfig(); @@ -350,4 +367,4 @@ class ReferenceAnnotationBeanPostProcessorTest { } } -} \ No newline at end of file +} From d3d8c54c74e5ff646213e3670c044387144ed1d9 Mon Sep 17 00:00:00 2001 From: conghuhu <56248584+conghuhu@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:12:46 +0800 Subject: [PATCH 083/144] fix: add micrometer bom to observability & optimize the structure of the package (#11724) * chore: optimize the structure of the package * chore: add micrometer bom to observability --------- Co-authored-by: Albumen Kevin --- ...ractDefaultDubboObservationConvention.java | 8 +++---- ...faultDubboClientObservationConvention.java | 6 ++--- ...faultDubboServerObservationConvention.java | 2 +- .../observation/DubboClientContext.java | 2 +- .../DubboClientObservationConvention.java | 2 +- .../observation/DubboObservation.java | 2 +- .../observation/DubboServerContext.java | 2 +- .../DubboServerObservationConvention.java | 2 +- .../ObservationReceiverFilter.java | 4 ---- .../observation/ObservationSenderFilter.java | 4 ---- .../pom.xml | 24 +++++++++++++++++++ .../DubboObservationAutoConfiguration.java | 10 ++++---- dubbo-spring-boot/pom.xml | 6 ----- 13 files changed, 43 insertions(+), 31 deletions(-) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/AbstractDefaultDubboObservationConvention.java (88%) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/DefaultDubboClientObservationConvention.java (92%) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/DefaultDubboServerObservationConvention.java (96%) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/DubboClientContext.java (96%) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/DubboClientObservationConvention.java (95%) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/DubboObservation.java (98%) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/DubboServerContext.java (96%) rename dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/{filter => }/observation/DubboServerObservationConvention.java (95%) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/AbstractDefaultDubboObservationConvention.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/AbstractDefaultDubboObservationConvention.java similarity index 88% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/AbstractDefaultDubboObservationConvention.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/AbstractDefaultDubboObservationConvention.java index d975e74da8..3a542fef86 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/AbstractDefaultDubboObservationConvention.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/AbstractDefaultDubboObservationConvention.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import io.micrometer.common.KeyValues; import io.micrometer.common.docs.KeyName; @@ -25,9 +25,9 @@ import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.support.RpcUtils; -import static org.apache.dubbo.metrics.filter.observation.DubboObservation.LowCardinalityKeyNames.RPC_METHOD; -import static org.apache.dubbo.metrics.filter.observation.DubboObservation.LowCardinalityKeyNames.RPC_SERVICE; -import static org.apache.dubbo.metrics.filter.observation.DubboObservation.LowCardinalityKeyNames.RPC_SYSTEM; +import static org.apache.dubbo.metrics.observation.DubboObservation.LowCardinalityKeyNames.RPC_METHOD; +import static org.apache.dubbo.metrics.observation.DubboObservation.LowCardinalityKeyNames.RPC_SERVICE; +import static org.apache.dubbo.metrics.observation.DubboObservation.LowCardinalityKeyNames.RPC_SYSTEM; class AbstractDefaultDubboObservationConvention { KeyValues getLowCardinalityKeyValues(Invocation invocation) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DefaultDubboClientObservationConvention.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConvention.java similarity index 92% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DefaultDubboClientObservationConvention.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConvention.java index 5849f5e165..ea31a526a5 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DefaultDubboClientObservationConvention.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConvention.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import java.util.List; @@ -24,8 +24,8 @@ import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcContextAttachment; -import static org.apache.dubbo.metrics.filter.observation.DubboObservation.LowCardinalityKeyNames.NET_PEER_NAME; -import static org.apache.dubbo.metrics.filter.observation.DubboObservation.LowCardinalityKeyNames.NET_PEER_PORT; +import static org.apache.dubbo.metrics.observation.DubboObservation.LowCardinalityKeyNames.NET_PEER_NAME; +import static org.apache.dubbo.metrics.observation.DubboObservation.LowCardinalityKeyNames.NET_PEER_PORT; /** * Default implementation of the {@link DubboClientObservationConvention}. diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DefaultDubboServerObservationConvention.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConvention.java similarity index 96% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DefaultDubboServerObservationConvention.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConvention.java index 094d17b50d..efb85f515e 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DefaultDubboServerObservationConvention.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConvention.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import io.micrometer.common.KeyValues; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboClientContext.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientContext.java similarity index 96% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboClientContext.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientContext.java index 4a0baa536f..6cd559fa1e 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboClientContext.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientContext.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import java.util.Objects; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboClientObservationConvention.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientObservationConvention.java similarity index 95% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboClientObservationConvention.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientObservationConvention.java index 044c548434..d33164294d 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboClientObservationConvention.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientObservationConvention.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationConvention; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboObservation.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboObservation.java similarity index 98% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboObservation.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboObservation.java index 446b5579e1..ff4b1575ff 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboObservation.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboObservation.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import io.micrometer.common.docs.KeyName; import io.micrometer.observation.Observation; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboServerContext.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerContext.java similarity index 96% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboServerContext.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerContext.java index 1f1fc4c5a4..d4ad9d97f3 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboServerContext.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerContext.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import io.micrometer.observation.transport.ReceiverContext; import org.apache.dubbo.rpc.Invocation; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboServerObservationConvention.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerObservationConvention.java similarity index 95% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboServerObservationConvention.java rename to dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerObservationConvention.java index bd6c66f11d..678226ee7f 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/filter/observation/DubboServerObservationConvention.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerObservationConvention.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.filter.observation; +package org.apache.dubbo.metrics.observation; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationConvention; diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java index e3b039177e..a25cc92ed8 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java @@ -20,10 +20,6 @@ import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import org.apache.dubbo.common.extension.Activate; -import org.apache.dubbo.metrics.filter.observation.DefaultDubboServerObservationConvention; -import org.apache.dubbo.metrics.filter.observation.DubboObservation; -import org.apache.dubbo.metrics.filter.observation.DubboServerContext; -import org.apache.dubbo.metrics.filter.observation.DubboServerObservationConvention; import org.apache.dubbo.rpc.BaseFilter; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java index 356c824f6e..6e0e099e48 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationSenderFilter.java @@ -20,10 +20,6 @@ import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import org.apache.dubbo.common.extension.Activate; -import org.apache.dubbo.metrics.filter.observation.DefaultDubboClientObservationConvention; -import org.apache.dubbo.metrics.filter.observation.DubboClientContext; -import org.apache.dubbo.metrics.filter.observation.DubboClientObservationConvention; -import org.apache.dubbo.metrics.filter.observation.DubboObservation; import org.apache.dubbo.rpc.BaseFilter; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml index 5922c1450c..7e0106a494 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml @@ -28,6 +28,30 @@ dubbo-spring-boot-observability-starter + + 1.10.4 + 1.0.2 + + + + + + io.micrometer + micrometer-bom + ${micrometer.version} + pom + import + + + io.micrometer + micrometer-tracing-bom + ${micrometer-tracing.version} + pom + import + + + + io.micrometer diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java index d50881e3c4..6b98ba9090 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java @@ -25,8 +25,10 @@ import io.micrometer.observation.ObservationRegistry; import io.micrometer.tracing.Tracer; import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler; import io.micrometer.tracing.handler.TracingObservationHandler; + import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -46,7 +48,7 @@ import java.util.Arrays; * Register observationRegistry to ApplicationModel. * Create observationRegistry when you are using Boot <3.0 or you are not using spring-boot-starter-actuator */ -@AutoConfiguration(after =DubboMicrometerTracingAutoConfiguration.class,afterName = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration") +@AutoConfiguration(after = DubboMicrometerTracingAutoConfiguration.class, afterName = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration") @ConditionalOnDubboTracingEnable public class DubboObservationAutoConfiguration implements BeanFactoryAware, SmartInitializingSingleton { @@ -108,14 +110,14 @@ public class DubboObservationAutoConfiguration implements BeanFactoryAware, Smar } @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ MeterRegistry.class, Tracer.class }) + @ConditionalOnClass({MeterRegistry.class, Tracer.class}) @ConditionalOnMissingBean(type = "org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor") static class MetricsWithTracingConfiguration { @Bean ObservationHandlerGrouping metricsAndTracingObservationHandlerGrouping() { return new ObservationHandlerGrouping( - Arrays.asList(TracingObservationHandler.class, MeterObservationHandler.class)); + Arrays.asList(TracingObservationHandler.class, MeterObservationHandler.class)); } } @@ -142,7 +144,7 @@ public class DubboObservationAutoConfiguration implements BeanFactoryAware, Smar @Bean TracingAwareMeterObservationHandler tracingAwareMeterObservationHandler( - MeterRegistry meterRegistry, Tracer tracer) { + MeterRegistry meterRegistry, Tracer tracer) { DefaultMeterObservationHandler delegate = new DefaultMeterObservationHandler(meterRegistry); return new TracingAwareMeterObservationHandler<>(delegate, tracer); } diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index 8ac8bcd5cc..c67931eace 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -46,7 +46,6 @@ 2.20.0 1.14.0 - 1.10.4 @@ -59,11 +58,6 @@ pom import - - io.micrometer - micrometer-core - ${micrometer-core.version} - From d0b98b309006379e57be06ad8d0cda2d8920f760 Mon Sep 17 00:00:00 2001 From: liuguangliang <240951888@qq.com> Date: Wed, 8 Mar 2023 18:42:27 +0800 Subject: [PATCH 084/144] improve NacosNamingServiceWrapper performance (#11665) Signed-off-by: mantuliu <240951888@qq.com> --- .../nacos/NacosNamingServiceWrapper.java | 44 +++---------------- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java index 3bd6116d15..2b09d8f675 100644 --- a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java +++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java @@ -60,7 +60,6 @@ public class NacosNamingServiceWrapper { private final ConcurrentMap registerStatus = new ConcurrentHashMap<>(); private final ConcurrentMap subscribeStatus = new ConcurrentHashMap<>(); - private final Lock mapLock = new ReentrantLock(); public NacosNamingServiceWrapper(NacosConnectionManager nacosConnectionManager, int retryTimes, int sleepMsBetweenRetries) { this.nacosConnectionManager = nacosConnectionManager; @@ -108,13 +107,7 @@ public class NacosNamingServiceWrapper { public void registerInstance(String serviceName, String group, Instance instance) throws NacosException { String nacosServiceName = handleInnerSymbol(serviceName); - InstancesInfo instancesInfo; - try { - mapLock.lock(); - instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); - } finally { - mapLock.unlock(); - } + InstancesInfo instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); try { instancesInfo.lock(); @@ -176,13 +169,7 @@ public class NacosNamingServiceWrapper { public void updateInstance(String serviceName, String group, Instance oldInstance, Instance newInstance) throws NacosException { String nacosServiceName = handleInnerSymbol(serviceName); - InstancesInfo instancesInfo; - try { - mapLock.lock(); - instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); - } finally { - mapLock.unlock(); - } + InstancesInfo instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); try { instancesInfo.lock(); @@ -222,13 +209,7 @@ public class NacosNamingServiceWrapper { public void deregisterInstance(String serviceName, String group, String ip, int port) throws NacosException { String nacosServiceName = handleInnerSymbol(serviceName); - InstancesInfo instancesInfo; - try { - mapLock.lock(); - instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); - } finally { - mapLock.unlock(); - } + InstancesInfo instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); try { instancesInfo.lock(); @@ -249,13 +230,7 @@ public class NacosNamingServiceWrapper { public void deregisterInstance(String serviceName, String group, Instance instance) throws NacosException { String nacosServiceName = handleInnerSymbol(serviceName); - InstancesInfo instancesInfo; - try { - mapLock.lock(); - instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); - } finally { - mapLock.unlock(); - } + InstancesInfo instancesInfo = ConcurrentHashMapUtils.computeIfAbsent(registerStatus, new InstanceId(nacosServiceName, group), id -> new InstancesInfo()); try { instancesInfo.lock(); @@ -269,14 +244,9 @@ public class NacosNamingServiceWrapper { InstanceInfo instanceInfo = optional.get(); instancesInfo.getInstances().remove(instanceInfo); - try { - mapLock.lock(); - if (instancesInfo.getInstances().isEmpty()) { - registerStatus.remove(new InstanceId(nacosServiceName, group)); - instancesInfo.setValid(false); - } - } finally { - mapLock.unlock(); + if (instancesInfo.getInstances().isEmpty()) { + registerStatus.remove(new InstanceId(nacosServiceName, group)); + instancesInfo.setValid(false); } // only one registered From 92a10515164c7cbeace15203805459f1f334f4f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Mar 2023 19:48:47 +0800 Subject: [PATCH 085/144] Bump protobuf-java.version from 3.19.6 to 3.22.0 (#11737) * Bump protobuf-java.version from 3.19.6 to 3.22.0 Bumps `protobuf-java.version` from 3.19.6 to 3.22.0. Updates `protobuf-java` from 3.19.6 to 3.22.0 - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.19.6...v3.22.0) Updates `protobuf-java-util` from 3.19.6 to 3.22.0 --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.google.protobuf:protobuf-java-util dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update build-and-test-pr.yml * Update .licenserc.yaml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: kezhenxu94 Co-authored-by: Albumen Kevin --- .github/workflows/build-and-test-pr.yml | 4 ++-- .licenserc.yaml | 4 ++++ dubbo-dependencies-bom/pom.xml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test-pr.yml b/.github/workflows/build-and-test-pr.yml index 1d0174dfd5..72c5fef4ca 100644 --- a/.github/workflows/build-and-test-pr.yml +++ b/.github/workflows/build-and-test-pr.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Check License - uses: apache/skywalking-eyes@main + uses: apache/skywalking-eyes@e1a02359b239bd28de3f6d35fdc870250fa513d5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: "Set up JDK 17" @@ -36,7 +36,7 @@ jobs: run: | ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C clean install -DskipTests=true -DskipIntegrationTests=true -Dcheckstyle.skip=true -Dcheckstyle_unix.skip=true -Drat.skip=true -Dmaven.javadoc.skip=true - name: Check Dependencies' License - uses: apache/skywalking-eyes/dependency@main + uses: apache/skywalking-eyes/dependency@e1a02359b239bd28de3f6d35fdc870250fa513d5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.licenserc.yaml b/.licenserc.yaml index 8d0f30f4c5..4978c9a34c 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -192,6 +192,10 @@ dependency: license: Apache-2.0 - name: org.sonatype.plexus:plexus-cipher 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 # multi license - name: org.javassist:javassist license: Apache-2.0 diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index a1c1a8d6e3..5f03e7f142 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -114,7 +114,7 @@ 3.5.5 0.18.1 4.0.66 - 3.19.6 + 3.22.0 1.3.2 3.1.0 5.0.0 From 0a9b19c306c8ef34c1949e1634d03b4d0aa45904 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Wed, 8 Mar 2023 20:11:07 +0800 Subject: [PATCH 086/144] Exact to support dynamic cert (#11578) --- .licenserc.yaml | 1 + codestyle/checkstyle-suppressions.xml | 3 +- .../common/CommonScopeModelInitializer.java | 2 + .../common/constants/LoggerCodeConstants.java | 6 + .../apache/dubbo/common/ssl/AuthPolicy.java | 23 ++ .../org/apache/dubbo/common/ssl/Cert.java | 67 ++++ .../apache/dubbo/common/ssl/CertManager.java | 55 +++ .../apache/dubbo/common/ssl/CertProvider.java | 30 ++ .../apache/dubbo/common/ssl/ProviderCert.java | 35 ++ .../ssl/impl/SSLConfigCertProvider.java | 80 ++++ .../apache/dubbo/common/utils/IOUtils.java | 12 + .../org/apache/dubbo/config/SslConfig.java | 37 ++ .../org.apache.dubbo.common.ssl.CertProvider | 1 + .../dubbo/common/ssl/CertManagerTest.java | 105 +++++ .../dubbo/common/ssl/FirstCertProvider.java | 56 +++ .../common/ssl/SSLConfigCertProviderTest.java | 124 ++++++ .../dubbo/common/ssl/SecondCertProvider.java | 56 +++ .../org.apache.dubbo.common.ssl.CertProvider | 2 + dubbo-common/src/test/resources/certs/ca.pem | 15 + .../src/test/resources/certs/cert.pem | 18 + dubbo-common/src/test/resources/certs/key.pem | 16 + dubbo-distribution/dubbo-all/pom.xml | 14 + dubbo-distribution/dubbo-bom/pom.xml | 5 + .../META-INF/native-image/reflect-config.json | 44 +- .../META-INF/native-image/reflect-config.json | 30 ++ dubbo-plugin/dubbo-security/pom.xml | 131 ++++++ .../dubbo/security/cert/CertConfig.java | 82 ++++ .../security/cert/CertDeployerListener.java | 64 +++ .../apache/dubbo/security/cert/CertPair.java | 70 ++++ .../cert/CertScopeModelInitializer.java | 54 +++ .../apache/dubbo/security/cert/Constants.java | 21 + .../dubbo/security/cert/DubboCertManager.java | 377 ++++++++++++++++++ .../security/cert/DubboCertProvider.java | 64 +++ .../dubbo-security/src/main/proto/ca.proto | 47 +++ ...bo.common.deploy.ApplicationDeployListener | 1 + .../org.apache.dubbo.common.ssl.CertProvider | 1 + ...ache.dubbo.rpc.model.ScopeModelInitializer | 1 + .../cert/CertDeployerListenerTest.java | 242 +++++++++++ .../security/cert/DubboCertManagerTest.java | 284 +++++++++++++ .../security/cert/DubboCertProviderTest.java | 150 +++++++ .../src/test/resources/certs/broken-ca.crt | 7 + .../src/test/resources/certs/ca.crt | 15 + .../src/test/resources/certs/token | 1 + dubbo-plugin/pom.xml | 1 + .../transport/netty4/NettyClient.java | 10 +- .../netty4/NettyConnectionClient.java | 8 +- .../netty4/NettyPortUnificationServer.java | 12 +- .../NettyPortUnificationServerHandler.java | 41 +- .../transport/netty4/NettyServer.java | 6 +- .../netty4/ssl/SslClientTlsHandler.java | 2 +- .../transport/netty4/ssl/SslContexts.java | 40 +- .../netty4/ssl/SslServerTlsHandler.java | 61 +-- dubbo-test/dubbo-dependencies-all/pom.xml | 4 + 53 files changed, 2551 insertions(+), 83 deletions(-) create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/ssl/AuthPolicy.java create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/ssl/Cert.java create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertManager.java create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertProvider.java create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/ssl/ProviderCert.java create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/ssl/impl/SSLConfigCertProvider.java create mode 100644 dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider create mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/ssl/CertManagerTest.java create mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/ssl/FirstCertProvider.java create mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SSLConfigCertProviderTest.java create mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SecondCertProvider.java create mode 100644 dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider create mode 100644 dubbo-common/src/test/resources/certs/ca.pem create mode 100644 dubbo-common/src/test/resources/certs/cert.pem create mode 100644 dubbo-common/src/test/resources/certs/key.pem create mode 100644 dubbo-plugin/dubbo-security/pom.xml create mode 100644 dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertConfig.java create mode 100644 dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java create mode 100644 dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertPair.java create mode 100644 dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java create mode 100644 dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/Constants.java create mode 100644 dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java create mode 100644 dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertProvider.java create mode 100644 dubbo-plugin/dubbo-security/src/main/proto/ca.proto create mode 100644 dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.deploy.ApplicationDeployListener create mode 100644 dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider create mode 100644 dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer create mode 100644 dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java create mode 100644 dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java create mode 100644 dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertProviderTest.java create mode 100644 dubbo-plugin/dubbo-security/src/test/resources/certs/broken-ca.crt create mode 100644 dubbo-plugin/dubbo-security/src/test/resources/certs/ca.crt create mode 100644 dubbo-plugin/dubbo-security/src/test/resources/certs/token diff --git a/.licenserc.yaml b/.licenserc.yaml index 4978c9a34c..70b039fe23 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -67,6 +67,7 @@ header: - 'CNAME' - 'Jenkinsfile' - '**/vendor/**' + - '**/src/test/resources/certs/**' - 'dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java' - 'dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocalMap.java' - 'dubbo-common/src/main/java/org/apache/dubbo/common/timer/HashedWheelTimer.java' diff --git a/codestyle/checkstyle-suppressions.xml b/codestyle/checkstyle-suppressions.xml index 0b2fa10a02..c3415cd97b 100644 --- a/codestyle/checkstyle-suppressions.xml +++ b/codestyle/checkstyle-suppressions.xml @@ -5,5 +5,6 @@ + - \ No newline at end of file + diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java b/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java index b9e5caa8bf..023830cd26 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/CommonScopeModelInitializer.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; import org.apache.dubbo.common.config.ConfigurationCache; import org.apache.dubbo.common.convert.ConverterUtil; import org.apache.dubbo.common.lang.ShutdownHookCallbacks; +import org.apache.dubbo.common.ssl.CertManager; import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.common.utils.DefaultSerializeClassChecker; @@ -38,6 +39,7 @@ public class CommonScopeModelInitializer implements ScopeModelInitializer { beanFactory.registerBean(ConverterUtil.class); beanFactory.registerBean(SerializeSecurityManager.class); beanFactory.registerBean(DefaultSerializeClassChecker.class); + beanFactory.registerBean(CertManager.class); } @Override diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java index e8f142b7eb..0682c5233d 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java @@ -380,6 +380,12 @@ public interface LoggerCodeConstants { String CONFIG_DUBBO_BEAN_NOT_FOUND = "5-40"; + String CONFIG_SSL_PATH_LOAD_FAILED = "5-41"; + + String CONFIG_SSL_CERT_GENERATE_FAILED = "5-42"; + + String CONFIG_SSL_CONNECT_INSECURE = "5-43"; + // Transport module String TRANSPORT_FAILED_CONNECT_PROVIDER = "6-1"; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/AuthPolicy.java b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/AuthPolicy.java new file mode 100644 index 0000000000..a8841e61d5 --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/AuthPolicy.java @@ -0,0 +1,23 @@ +/* + * 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.ssl; + +public enum AuthPolicy { + NONE, + SERVER_AUTH, + CLIENT_AUTH +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/Cert.java b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/Cert.java new file mode 100644 index 0000000000..859fae996c --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/Cert.java @@ -0,0 +1,67 @@ +/* + * 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.ssl; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +public class Cert { + private final byte[] keyCertChain; + private final byte[] privateKey; + private final byte[] trustCert; + + private final String password; + + public Cert(byte[] keyCertChain, byte[] privateKey, byte[] trustCert) { + this(keyCertChain, privateKey, trustCert, null); + } + + public Cert(byte[] keyCertChain, byte[] privateKey, byte[] trustCert, String password) { + this.keyCertChain = keyCertChain; + this.privateKey = privateKey; + this.trustCert = trustCert; + this.password = password; + } + + public byte[] getKeyCertChain() { + return keyCertChain; + } + + public InputStream getKeyCertChainInputStream() { + return keyCertChain != null ? new ByteArrayInputStream(keyCertChain) : null; + } + + public byte[] getPrivateKey() { + return privateKey; + } + + public InputStream getPrivateKeyInputStream() { + return privateKey != null ? new ByteArrayInputStream(privateKey) : null; + } + + public byte[] getTrustCert() { + return trustCert; + } + + public InputStream getTrustCertInputStream() { + return trustCert != null ? new ByteArrayInputStream(trustCert) : null; + } + + public String getPassword() { + return password; + } +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertManager.java b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertManager.java new file mode 100644 index 0000000000..d906457d66 --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertManager.java @@ -0,0 +1,55 @@ +/* + * 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.ssl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import java.net.SocketAddress; +import java.util.List; + +public class CertManager { + private final List certProviders; + + public CertManager(FrameworkModel frameworkModel) { + this.certProviders = frameworkModel.getExtensionLoader(CertProvider.class).getActivateExtensions(); + } + + public ProviderCert getProviderConnectionConfig(URL localAddress, SocketAddress remoteAddress) { + for (CertProvider certProvider : certProviders) { + if (certProvider.isSupport(localAddress)) { + ProviderCert cert = certProvider.getProviderConnectionConfig(localAddress); + if (cert != null) { + return cert; + } + } + } + return null; + } + + public Cert getConsumerConnectionConfig(URL remoteAddress) { + for (CertProvider certProvider : certProviders) { + if (certProvider.isSupport(remoteAddress)) { + Cert cert = certProvider.getConsumerConnectionConfig(remoteAddress); + if (cert != null) { + return cert; + } + } + } + return null; + } +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertProvider.java b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertProvider.java new file mode 100644 index 0000000000..dad514f9b2 --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/CertProvider.java @@ -0,0 +1,30 @@ +/* + * 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.ssl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.ExtensionScope; +import org.apache.dubbo.common.extension.SPI; + +@SPI(scope = ExtensionScope.FRAMEWORK) +public interface CertProvider { + boolean isSupport(URL address); + + ProviderCert getProviderConnectionConfig(URL localAddress); + + Cert getConsumerConnectionConfig(URL remoteAddress); +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/ProviderCert.java b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/ProviderCert.java new file mode 100644 index 0000000000..81b9f9876f --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/ProviderCert.java @@ -0,0 +1,35 @@ +/* + * 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.ssl; + +public class ProviderCert extends Cert { + private final AuthPolicy authPolicy; + + public ProviderCert(byte[] keyCertChain, byte[] privateKey, byte[] trustCert, AuthPolicy authPolicy) { + super(keyCertChain, privateKey, trustCert); + this.authPolicy = authPolicy; + } + + public ProviderCert(byte[] keyCertChain, byte[] privateKey, byte[] trustCert, String password, AuthPolicy authPolicy) { + super(keyCertChain, privateKey, trustCert, password); + this.authPolicy = authPolicy; + } + + public AuthPolicy getAuthPolicy() { + return authPolicy; + } +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/impl/SSLConfigCertProvider.java b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/impl/SSLConfigCertProvider.java new file mode 100644 index 0000000000..b694ee3bef --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/ssl/impl/SSLConfigCertProvider.java @@ -0,0 +1,80 @@ +/* + * 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.ssl.impl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.LoggerCodeConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.ssl.AuthPolicy; +import org.apache.dubbo.common.ssl.Cert; +import org.apache.dubbo.common.ssl.CertProvider; +import org.apache.dubbo.common.ssl.ProviderCert; +import org.apache.dubbo.common.utils.IOUtils; + +import java.io.IOException; +import java.util.Objects; + +@Activate(order = Integer.MAX_VALUE - 10000) +public class SSLConfigCertProvider implements CertProvider { + private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(SSLConfigCertProvider.class); + + @Override + public boolean isSupport(URL address) { + return address.getOrDefaultApplicationModel().getApplicationConfigManager().getSsl() + .isPresent(); + } + + @Override + public ProviderCert getProviderConnectionConfig(URL localAddress) { + return localAddress.getOrDefaultApplicationModel().getApplicationConfigManager().getSsl() + .filter(sslConfig -> Objects.nonNull(sslConfig.getServerKeyCertChainPath())) + .filter(sslConfig -> Objects.nonNull(sslConfig.getServerPrivateKeyPath())) + .map(sslConfig -> { + try { + return new ProviderCert( + IOUtils.toByteArray(sslConfig.getServerKeyCertChainPathStream()), + IOUtils.toByteArray(sslConfig.getServerPrivateKeyPathStream()), + sslConfig.getServerTrustCertCollectionPath() != null ? IOUtils.toByteArray(sslConfig.getServerTrustCertCollectionPathStream()) : null, + sslConfig.getServerKeyPassword(), AuthPolicy.CLIENT_AUTH); + } catch (IOException e) { + logger.warn(LoggerCodeConstants.CONFIG_SSL_PATH_LOAD_FAILED, "", "", "Failed to load ssl config.", e); + return null; + } + }).orElse(null); + } + + @Override + public Cert getConsumerConnectionConfig(URL remoteAddress) { + return remoteAddress.getOrDefaultApplicationModel().getApplicationConfigManager().getSsl() + .filter(sslConfig -> Objects.nonNull(sslConfig.getClientKeyCertChainPath())) + .filter(sslConfig -> Objects.nonNull(sslConfig.getClientPrivateKeyPath())) + .map(sslConfig -> { + try { + return new Cert( + IOUtils.toByteArray(sslConfig.getClientKeyCertChainPathStream()), + IOUtils.toByteArray(sslConfig.getClientPrivateKeyPathStream()), + sslConfig.getClientTrustCertCollectionPath() != null ? IOUtils.toByteArray(sslConfig.getClientTrustCertCollectionPathStream()) : null, + sslConfig.getClientKeyPassword()); + } catch (IOException e) { + logger.warn(LoggerCodeConstants.CONFIG_SSL_PATH_LOAD_FAILED, "", "", "Failed to load ssl config.", e); + return null; + } + }).orElse(null); + } +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java index deab7d2c56..2f79f6c1e0 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java @@ -19,6 +19,7 @@ package org.apache.dubbo.common.utils; import org.apache.dubbo.common.constants.CommonConstants; import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -277,4 +278,15 @@ public class IOUtils { } } } + + public static byte[] toByteArray(final InputStream inputStream) throws IOException { + try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + byte[] buffer = new byte[1024]; + int n; + while (-1 != (n = inputStream.read(buffer))) { + byteArrayOutputStream.write(buffer, 0, n); + } + return byteArrayOutputStream.toByteArray(); + } + } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java index 0dc9557246..5bf5a57b03 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java @@ -64,6 +64,11 @@ public class SslConfig extends AbstractConfig { private InputStream clientPrivateKeyPathStream; private InputStream clientTrustCertCollectionPathStream; + private String caAddress; + private String envType; + private String caCertPath; + private String oidcTokenPath; + public SslConfig() { } @@ -143,6 +148,38 @@ public class SslConfig extends AbstractConfig { this.clientTrustCertCollectionPath = clientTrustCertCollectionPath; } + public String getCaAddress() { + return caAddress; + } + + public void setCaAddress(String caAddress) { + this.caAddress = caAddress; + } + + public String getEnvType() { + return envType; + } + + public void setEnvType(String envType) { + this.envType = envType; + } + + public String getCaCertPath() { + return caCertPath; + } + + public void setCaCertPath(String caCertPath) { + this.caCertPath = caCertPath; + } + + public String getOidcTokenPath() { + return oidcTokenPath; + } + + public void setOidcTokenPath(String oidcTokenPath) { + this.oidcTokenPath = oidcTokenPath; + } + @Transient public InputStream getServerKeyCertChainPathStream() throws IOException { if (serverKeyCertChainPath != null) { diff --git a/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider new file mode 100644 index 0000000000..4f00eed19e --- /dev/null +++ b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider @@ -0,0 +1 @@ +ssl-config=org.apache.dubbo.common.ssl.impl.SSLConfigCertProvider diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/CertManagerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/CertManagerTest.java new file mode 100644 index 0000000000..d586abbfa8 --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/CertManagerTest.java @@ -0,0 +1,105 @@ +/* + * 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.ssl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class CertManagerTest { + private FrameworkModel frameworkModel; + private URL url; + @BeforeEach + void setup() { + FirstCertProvider.setProviderCert(null); + FirstCertProvider.setCert(null); + FirstCertProvider.setSupport(false); + + SecondCertProvider.setProviderCert(null); + SecondCertProvider.setCert(null); + SecondCertProvider.setSupport(false); + + frameworkModel = new FrameworkModel(); + url = URL.valueOf("dubbo://").setScopeModel(frameworkModel.newApplication()); + } + + @AfterEach + void teardown() { + frameworkModel.destroy(); + } + + @Test + void testGetConsumerConnectionConfig() { + CertManager certManager = new CertManager(frameworkModel); + + Assertions.assertNull(certManager.getConsumerConnectionConfig(url)); + + Cert cert1 = Mockito.mock(Cert.class); + FirstCertProvider.setCert(cert1); + Assertions.assertNull(certManager.getConsumerConnectionConfig(url)); + + FirstCertProvider.setSupport(true); + Assertions.assertEquals(cert1, certManager.getConsumerConnectionConfig(url)); + + Cert cert2 = Mockito.mock(Cert.class); + SecondCertProvider.setCert(cert2); + Assertions.assertEquals(cert1, certManager.getConsumerConnectionConfig(url)); + + SecondCertProvider.setSupport(true); + Assertions.assertEquals(cert1, certManager.getConsumerConnectionConfig(url)); + + FirstCertProvider.setSupport(false); + Assertions.assertEquals(cert2, certManager.getConsumerConnectionConfig(url)); + + FirstCertProvider.setSupport(true); + FirstCertProvider.setCert(null); + Assertions.assertEquals(cert2, certManager.getConsumerConnectionConfig(url)); + } + + @Test + void testGetProviderConnectionConfig() { + CertManager certManager = new CertManager(frameworkModel); + + Assertions.assertNull(certManager.getProviderConnectionConfig(url, null)); + + ProviderCert providerCert1 = Mockito.mock(ProviderCert.class); + FirstCertProvider.setProviderCert(providerCert1); + Assertions.assertNull(certManager.getProviderConnectionConfig(url, null)); + + FirstCertProvider.setSupport(true); + Assertions.assertEquals(providerCert1, certManager.getProviderConnectionConfig(url, null)); + + ProviderCert providerCert2 = Mockito.mock(ProviderCert.class); + SecondCertProvider.setProviderCert(providerCert2); + Assertions.assertEquals(providerCert1, certManager.getProviderConnectionConfig(url, null)); + + SecondCertProvider.setSupport(true); + Assertions.assertEquals(providerCert1, certManager.getProviderConnectionConfig(url, null)); + + FirstCertProvider.setSupport(false); + Assertions.assertEquals(providerCert2, certManager.getProviderConnectionConfig(url, null)); + + FirstCertProvider.setSupport(true); + FirstCertProvider.setProviderCert(null); + Assertions.assertEquals(providerCert2, certManager.getProviderConnectionConfig(url, null)); + } +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/FirstCertProvider.java b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/FirstCertProvider.java new file mode 100644 index 0000000000..99153771e0 --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/FirstCertProvider.java @@ -0,0 +1,56 @@ +/* + * 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.ssl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +@Activate(order = -10000) +public class FirstCertProvider implements CertProvider { + private static final AtomicBoolean isSupport = new AtomicBoolean(false); + private static final AtomicReference providerCert = new AtomicReference<>(); + private static final AtomicReference cert = new AtomicReference<>(); + @Override + public boolean isSupport(URL address) { + return isSupport.get(); + } + + @Override + public ProviderCert getProviderConnectionConfig(URL localAddress) { + return providerCert.get(); + } + + @Override + public Cert getConsumerConnectionConfig(URL remoteAddress) { + return cert.get(); + } + + public static void setSupport(boolean support) { + isSupport.set(support); + } + + public static void setProviderCert(ProviderCert providerCert) { + FirstCertProvider.providerCert.set(providerCert); + } + + public static void setCert(Cert cert) { + FirstCertProvider.cert.set(cert); + } +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SSLConfigCertProviderTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SSLConfigCertProviderTest.java new file mode 100644 index 0000000000..f7a1c02ef7 --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SSLConfigCertProviderTest.java @@ -0,0 +1,124 @@ +/* + * 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.ssl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.ssl.impl.SSLConfigCertProvider; +import org.apache.dubbo.common.utils.IOUtils; +import org.apache.dubbo.config.SslConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +class SSLConfigCertProviderTest { + @Test + void testSupported() { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + SSLConfigCertProvider sslConfigCertProvider = new SSLConfigCertProvider(); + + URL url = URL.valueOf("").setScopeModel(applicationModel); + Assertions.assertFalse(sslConfigCertProvider.isSupport(url)); + + SslConfig sslConfig = new SslConfig(); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + Assertions.assertTrue(sslConfigCertProvider.isSupport(url)); + + frameworkModel.destroy(); + } + + @Test + void testGetProviderConnectionConfig() throws IOException { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + SSLConfigCertProvider sslConfigCertProvider = new SSLConfigCertProvider(); + + URL url = URL.valueOf("").setScopeModel(applicationModel); + Assertions.assertNull(sslConfigCertProvider.getProviderConnectionConfig(url)); + + SslConfig sslConfig = new SslConfig(); + sslConfig.setServerKeyCertChainPath("keyCert"); + sslConfig.setServerPrivateKeyPath("private"); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + ProviderCert providerCert = sslConfigCertProvider.getProviderConnectionConfig(url); + Assertions.assertNull(providerCert); + + sslConfig.setServerKeyCertChainPath(this.getClass().getClassLoader().getResource("certs/cert.pem").getFile()); + sslConfig.setServerPrivateKeyPath(this.getClass().getClassLoader().getResource("certs/key.pem").getFile()); + providerCert = sslConfigCertProvider.getProviderConnectionConfig(url); + Assertions.assertNotNull(providerCert); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/cert.pem")), + providerCert.getKeyCertChain()); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/key.pem")), + providerCert.getPrivateKey()); + Assertions.assertNull(providerCert.getTrustCert()); + + sslConfig.setServerTrustCertCollectionPath(this.getClass().getClassLoader().getResource("certs/ca.pem").getFile()); + providerCert = sslConfigCertProvider.getProviderConnectionConfig(url); + Assertions.assertNotNull(providerCert); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/cert.pem")), + providerCert.getKeyCertChain()); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/key.pem")), + providerCert.getPrivateKey()); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/ca.pem")), + providerCert.getTrustCert()); + + frameworkModel.destroy(); + } + + @Test + void testGetConsumerConnectionConfig() throws IOException { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + SSLConfigCertProvider sslConfigCertProvider = new SSLConfigCertProvider(); + + URL url = URL.valueOf("").setScopeModel(applicationModel); + Assertions.assertNull(sslConfigCertProvider.getConsumerConnectionConfig(url)); + + SslConfig sslConfig = new SslConfig(); + sslConfig.setClientKeyCertChainPath("keyCert"); + sslConfig.setClientPrivateKeyPath("private"); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + Cert cert = sslConfigCertProvider.getConsumerConnectionConfig(url); + Assertions.assertNull(cert); + + sslConfig.setClientKeyCertChainPath(this.getClass().getClassLoader().getResource("certs/cert.pem").getFile()); + sslConfig.setClientPrivateKeyPath(this.getClass().getClassLoader().getResource("certs/key.pem").getFile()); + cert = sslConfigCertProvider.getConsumerConnectionConfig(url); + Assertions.assertNotNull(cert); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/cert.pem")), + cert.getKeyCertChain()); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/key.pem")), + cert.getPrivateKey()); + + sslConfig.setClientTrustCertCollectionPath(this.getClass().getClassLoader().getResource("certs/ca.pem").getFile()); + cert = sslConfigCertProvider.getConsumerConnectionConfig(url); + Assertions.assertNotNull(cert); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/cert.pem")), + cert.getKeyCertChain()); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/key.pem")), + cert.getPrivateKey()); + Assertions.assertArrayEquals(IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream("certs/ca.pem")), + cert.getTrustCert()); + + frameworkModel.destroy(); + } +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SecondCertProvider.java b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SecondCertProvider.java new file mode 100644 index 0000000000..950b5cb8ee --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/ssl/SecondCertProvider.java @@ -0,0 +1,56 @@ +/* + * 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.ssl; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +@Activate(order = 10000) +public class SecondCertProvider implements CertProvider { + private static final AtomicBoolean isSupport = new AtomicBoolean(false); + private static final AtomicReference providerCert = new AtomicReference<>(); + private static final AtomicReference cert = new AtomicReference<>(); + @Override + public boolean isSupport(URL address) { + return isSupport.get(); + } + + @Override + public ProviderCert getProviderConnectionConfig(URL localAddress) { + return providerCert.get(); + } + + @Override + public Cert getConsumerConnectionConfig(URL remoteAddress) { + return cert.get(); + } + + public static void setSupport(boolean support) { + isSupport.set(support); + } + + public static void setProviderCert(ProviderCert providerCert) { + SecondCertProvider.providerCert.set(providerCert); + } + + public static void setCert(Cert cert) { + SecondCertProvider.cert.set(cert); + } +} diff --git a/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider new file mode 100644 index 0000000000..d66d1ed761 --- /dev/null +++ b/dubbo-common/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider @@ -0,0 +1,2 @@ +first=org.apache.dubbo.common.ssl.FirstCertProvider +second=org.apache.dubbo.common.ssl.SecondCertProvider diff --git a/dubbo-common/src/test/resources/certs/ca.pem b/dubbo-common/src/test/resources/certs/ca.pem new file mode 100644 index 0000000000..6c8511a73c --- /dev/null +++ b/dubbo-common/src/test/resources/certs/ca.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla +Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT +BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 ++L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu +g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd +Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau +sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m +oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG +Dfcog5wrJytaQ6UA0wE= +-----END CERTIFICATE----- diff --git a/dubbo-common/src/test/resources/certs/cert.pem b/dubbo-common/src/test/resources/certs/cert.pem new file mode 100644 index 0000000000..913649b97f --- /dev/null +++ b/dubbo-common/src/test/resources/certs/cert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAlKgAwIBAgIBCjANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTEwMDEwOTU4WhcNMjUxMTA3 +MDEwOTU4WjBaMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8G +A1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQDDAp0ZXN0Y2xp +ZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDsVEfbob4W3lVCDLOVmx9K +cdJnoZdvurGaTY87xNiopmaR8zCR7pFR9BX5L4bNG/PkuVLfVTVAKndyDCQggBBr +UTaEITNbfWK9swHJEr20WnKfhS/wo/Xg5sqNNCrFRmnnnwOA4eDlvmYZEzSnJXV6 +pEro9bBH9uOCWWLqmaev7QIDAQABo4HCMIG/MAkGA1UdEwQCMAAwCwYDVR0PBAQD +AgXgMB0GA1UdDgQWBBQAdbW5Vml/CnYwqdP3mOHDARU+8zBwBgNVHSMEaTBnoVqk +WDBWMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMY +SW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2GCCQCRxhke +HRoqBzAJBgNVHREEAjAAMAkGA1UdEgQCMAAwDQYJKoZIhvcNAQELBQADgYEAf4MM +k+sdzd720DfrQ0PF2gDauR3M9uBubozDuMuF6ufAuQBJSKGQEGibXbUelrwHmnql +UjTyfolVcxEBVaF4VFHmn7u6vP7S1NexIDdNUHcULqxIb7Tzl8JYq8OOHD2rQy4H +s8BXaVIzw4YcaCGAMS0iDX052Sy7e2JhP8Noxvo= +-----END CERTIFICATE----- diff --git a/dubbo-common/src/test/resources/certs/key.pem b/dubbo-common/src/test/resources/certs/key.pem new file mode 100644 index 0000000000..f48d0735d9 --- /dev/null +++ b/dubbo-common/src/test/resources/certs/key.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOxUR9uhvhbeVUIM +s5WbH0px0mehl2+6sZpNjzvE2KimZpHzMJHukVH0Ffkvhs0b8+S5Ut9VNUAqd3IM +JCCAEGtRNoQhM1t9Yr2zAckSvbRacp+FL/Cj9eDmyo00KsVGaeefA4Dh4OW+ZhkT +NKcldXqkSuj1sEf244JZYuqZp6/tAgMBAAECgYEAi2NSVqpZMafE5YYUTcMGe6QS +k2jtpsqYgggI2RnLJ/2tNZwYI5pwP8QVSbnMaiF4gokD5hGdrNDfTnb2v+yIwYEH +0w8+oG7Z81KodsiZSIDJfTGsAZhVNwOz9y0VD8BBZZ1/274Zh52AUKLjZS/ZwIbS +W2ywya855dPnH/wj+0ECQQD9X8D920kByTNHhBG18biAEZ4pxs9f0OAG8333eVcI +w2lJDLsYDZrCB2ocgA3lUdozlzPC7YDYw8reg0tkiRY5AkEA7sdNzOeQsQRn7++5 +0bP9DtT/iON1gbfxRzCfCfXdoOtfQWIzTePWtURt9X/5D9NofI0Rg5W2oGy/MLe5 +/sXHVQJBAIup5XrJDkQywNZyAUU2ecn2bCWBFjwtqd+LBmuMciI9fOKsZtEKZrz/ +U0lkeMRoSwvXE8wmGLjjrAbdfohrXFkCQQDZEx/LtIl6JINJQiswVe0tWr6k+ASP +1WXoTm+HYpoF/XUvv9LccNF1IazFj34hwRQwhx7w/V52Ieb+p0jUMYGxAkEAjDhd +9pBO1fKXWiXzi9ZKfoyTNcUq3eBSVKwPG2nItg5ycXengjT5sgcWDnciIzW7BIVI +JiqOszq9GWESErAatg== +-----END PRIVATE KEY----- diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index d958e70657..a973e71da2 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -243,6 +243,13 @@ compile true + + org.apache.dubbo + dubbo-security + ${project.version} + compile + true + org.apache.dubbo dubbo-reactive @@ -515,6 +522,7 @@ org.apache.dubbo:dubbo-monitor-api org.apache.dubbo:dubbo-monitor-default org.apache.dubbo:dubbo-qos + org.apache.dubbo:dubbo-security org.apache.dubbo:dubbo-reactive org.apache.dubbo:dubbo-spring-security org.apache.dubbo:dubbo-registry-api @@ -898,6 +906,12 @@ META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.MetadataServiceURLBuilder + + + META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider + + diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml index 9e04c68747..fc34f5f8b2 100644 --- a/dubbo-distribution/dubbo-bom/pom.xml +++ b/dubbo-distribution/dubbo-bom/pom.xml @@ -299,6 +299,11 @@ dubbo-auth ${project.version} + + org.apache.dubbo + dubbo-security + ${project.version} + org.apache.dubbo dubbo-qos diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json index b70a14a2f0..59853eab5b 100644 --- a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json +++ b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json @@ -2312,13 +2312,13 @@ "name": "org.apache.dubbo.rpc.filter.GenericImplFilter", "allPublicMethods": true, "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ModuleModel" - ] - } - ] + { + "name": "", + "parameterTypes": [ + "org.apache.dubbo.rpc.model.ModuleModel" + ] + } + ] }, { "name": "org.apache.dubbo.rpc.filter.TimeoutFilter", @@ -2599,6 +2599,36 @@ } ] }, + { + "name": "org.apache.dubbo.common.ssl.impl.SSLConfigCertProvider", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.security.cert.DubboCertManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] + } + ] + }, + { + "name": "org.apache.dubbo.common.ssl.CertManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] + } + ] + }, { "name": "org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory" }, diff --git a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json index 112737d01c..59853eab5b 100644 --- a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json +++ b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json @@ -2599,6 +2599,36 @@ } ] }, + { + "name": "org.apache.dubbo.common.ssl.impl.SSLConfigCertProvider", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.security.cert.DubboCertManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] + } + ] + }, + { + "name": "org.apache.dubbo.common.ssl.CertManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] + } + ] + }, { "name": "org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory" }, diff --git a/dubbo-plugin/dubbo-security/pom.xml b/dubbo-plugin/dubbo-security/pom.xml new file mode 100644 index 0000000000..f0a5a7bdaa --- /dev/null +++ b/dubbo-plugin/dubbo-security/pom.xml @@ -0,0 +1,131 @@ + + + + org.apache.dubbo + dubbo-plugin + ${revision} + ../pom.xml + + 4.0.0 + + + false + 3.21.12 + 1.41.0 + + + dubbo-security + jar + + + + + org.apache.dubbo + dubbo-rpc-api + ${project.version} + + + org.apache.dubbo + dubbo-rpc-triple + ${project.version} + + + + org.apache.dubbo + dubbo-common + ${project.version} + + + + + + io.grpc + grpc-protobuf + + + io.grpc + grpc-stub + + + io.grpc + grpc-netty-shaded + + + + com.google.protobuf + protobuf-java + + + com.google.protobuf + protobuf-java-util + + + + org.bouncycastle + bcprov-jdk15on + + + org.bouncycastle + bcpkix-jdk15on + + + org.bouncycastle + bcprov-ext-jdk15on + + + + + org.apache.dubbo + dubbo-config-api + ${project.version} + test + + + + + + + kr.motd.maven + os-maven-plugin + 1.6.2 + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.6.1 + + com.google.protobuf:protoc:${protobuf-java.version}:exe:${os.detected.classifier} + grpc-java + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + + + + compile + compile-custom + + + + + + + + diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertConfig.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertConfig.java new file mode 100644 index 0000000000..8759823e6c --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertConfig.java @@ -0,0 +1,82 @@ +/* + * 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.security.cert; + +import java.util.Objects; + +import static org.apache.dubbo.security.cert.Constants.DEFAULT_REFRESH_INTERVAL; + +public class CertConfig { + private final String remoteAddress; + private final String envType; + private final String caCertPath; + /** + * Path to OpenID Connect Token file + */ + private final String oidcTokenPath; + + private final int refreshInterval; + + public CertConfig(String remoteAddress, String envType, String caCertPath, String oidcTokenPath) { + this(remoteAddress, envType, caCertPath, oidcTokenPath, DEFAULT_REFRESH_INTERVAL); + } + + public CertConfig(String remoteAddress, String envType, String caCertPath, String oidcTokenPath, int refreshInterval) { + this.remoteAddress = remoteAddress; + this.envType = envType; + this.caCertPath = caCertPath; + this.oidcTokenPath = oidcTokenPath; + this.refreshInterval = refreshInterval; + } + + public String getRemoteAddress() { + return remoteAddress; + } + + public String getEnvType() { + return envType; + } + + public String getCaCertPath() { + return caCertPath; + } + + public String getOidcTokenPath() { + return oidcTokenPath; + } + + public int getRefreshInterval() { + return refreshInterval; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CertConfig that = (CertConfig) o; + return Objects.equals(remoteAddress, that.remoteAddress) && Objects.equals(envType, that.envType) && Objects.equals(caCertPath, that.caCertPath) && Objects.equals(oidcTokenPath, that.oidcTokenPath); + } + + @Override + public int hashCode() { + return Objects.hash(remoteAddress, envType, caCertPath, oidcTokenPath); + } +} diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java new file mode 100644 index 0000000000..8dcf3e7318 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java @@ -0,0 +1,64 @@ +/* + * 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.security.cert; + +import org.apache.dubbo.common.deploy.ApplicationDeployListener; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import java.util.Objects; + +public class CertDeployerListener implements ApplicationDeployListener { + private final DubboCertManager dubboCertManager; + + + public CertDeployerListener(FrameworkModel frameworkModel) { + dubboCertManager = frameworkModel.getBeanFactory().getBean(DubboCertManager.class); + } + + @Override + public void onStarting(ApplicationModel scopeModel) { + scopeModel.getApplicationConfigManager().getSsl().ifPresent(sslConfig -> { + if (Objects.nonNull(sslConfig.getCaAddress()) && dubboCertManager != null) { + CertConfig certConfig = new CertConfig(sslConfig.getCaAddress(), + sslConfig.getEnvType(), + sslConfig.getCaCertPath(), + sslConfig.getOidcTokenPath()); + dubboCertManager.connect(certConfig); + } + }); + } + + @Override + public void onStarted(ApplicationModel scopeModel) { + } + + @Override + public void onStopping(ApplicationModel scopeModel) { + dubboCertManager.disConnect(); + } + + @Override + public void onStopped(ApplicationModel scopeModel) { + + } + + @Override + public void onFailure(ApplicationModel scopeModel, Throwable cause) { + dubboCertManager.disConnect(); + } +} diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertPair.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertPair.java new file mode 100644 index 0000000000..719f2ef84d --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertPair.java @@ -0,0 +1,70 @@ +/* + * 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.security.cert; + +import java.util.Objects; + +public class CertPair { + private final String privateKey; + private final String certificate; + private final String trustCerts; + private final long expireTime; + + public CertPair(String privateKey, String certificate, String trustCerts, long expireTime) { + this.privateKey = privateKey; + this.certificate = certificate; + this.trustCerts = trustCerts; + this.expireTime = expireTime; + } + + public String getPrivateKey() { + return privateKey; + } + + public String getCertificate() { + return certificate; + } + + public String getTrustCerts() { + return trustCerts; + } + + public long getExpireTime() { + return expireTime; + } + + public boolean isExpire() { + return System.currentTimeMillis() > expireTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CertPair certPair = (CertPair) o; + return expireTime == certPair.expireTime && Objects.equals(privateKey, certPair.privateKey) && Objects.equals(certificate, certPair.certificate) && Objects.equals(trustCerts, certPair.trustCerts); + } + + @Override + public int hashCode() { + return Objects.hash(privateKey, certificate, trustCerts, expireTime); + } +} diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java new file mode 100644 index 0000000000..42ffa1d703 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertScopeModelInitializer.java @@ -0,0 +1,54 @@ +/* + * 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.security.cert; + +import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; +import org.apache.dubbo.common.utils.ClassUtils; +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 CertScopeModelInitializer implements ScopeModelInitializer { + public static boolean isSupported() { + try { + ClassUtils.forName("io.grpc.Channel"); + ClassUtils.forName("org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder"); + return true; + } catch (Throwable t) { + return false; + } + } + + @Override + public void initializeFrameworkModel(FrameworkModel frameworkModel) { + ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); + if (isSupported()) { + beanFactory.registerBean(DubboCertManager.class); + } + } + + @Override + public void initializeApplicationModel(ApplicationModel applicationModel) { + + } + + @Override + public void initializeModuleModel(ModuleModel moduleModel) { + + } +} diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/Constants.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/Constants.java new file mode 100644 index 0000000000..1f3c3c7ff4 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/Constants.java @@ -0,0 +1,21 @@ +/* + * 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.security.cert; + +public interface Constants { + int DEFAULT_REFRESH_INTERVAL = 30_000; +} diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java new file mode 100644 index 0000000000..3fcb7fb80a --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertManager.java @@ -0,0 +1,377 @@ +/* + * 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.security.cert; + +import org.apache.dubbo.auth.v1alpha1.DubboCertificateRequest; +import org.apache.dubbo.auth.v1alpha1.DubboCertificateResponse; +import org.apache.dubbo.auth.v1alpha1.DubboCertificateServiceGrpc; +import org.apache.dubbo.common.constants.LoggerCodeConstants; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; +import org.apache.dubbo.common.utils.IOUtils; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import io.grpc.Channel; +import io.grpc.Metadata; +import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts; +import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder; +import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.openssl.jcajce.JcaPEMWriter; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; +import org.bouncycastle.util.io.pem.PemObject; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.ECGenParameterSpec; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import static io.grpc.stub.MetadataUtils.newAttachHeadersInterceptor; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_SSL_CERT_GENERATE_FAILED; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_SSL_CONNECT_INSECURE; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_GENERATE_CERT_ISTIO; + +public class DubboCertManager { + + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(DubboCertManager.class); + + private final FrameworkModel frameworkModel; + /** + * gRPC channel to Dubbo Cert Authority server + */ + protected volatile Channel channel; + /** + * Cert pair for current Dubbo instance + */ + protected volatile CertPair certPair; + /** + * Path to OpenID Connect Token file + */ + protected volatile CertConfig certConfig; + /** + * Refresh cert pair for current Dubbo instance + */ + protected volatile ScheduledFuture refreshFuture; + + public DubboCertManager(FrameworkModel frameworkModel) { + this.frameworkModel = frameworkModel; + } + + public synchronized void connect(CertConfig certConfig) { + if (channel != null) { + logger.error(INTERNAL_ERROR, "", "", "Dubbo Cert Authority server is already connected."); + return; + } + if (certConfig == null) { + // No cert config, return + return; + } + if (StringUtils.isEmpty(certConfig.getRemoteAddress())) { + // No remote address configured, return + return; + } + if (StringUtils.isNotEmpty(certConfig.getEnvType()) && !"Kubernetes".equalsIgnoreCase(certConfig.getEnvType())) { + throw new IllegalArgumentException("Only support Kubernetes env now."); + } + // Create gRPC connection + connect0(certConfig); + + this.certConfig = certConfig; + + // Try to generate cert from remote + generateCert(); + // Schedule refresh task + scheduleRefresh(); + } + + /** + * Create task to refresh cert pair for current Dubbo instance + */ + protected void scheduleRefresh() { + FrameworkExecutorRepository repository = frameworkModel.getBeanFactory().getBean(FrameworkExecutorRepository.class); + refreshFuture = repository.getSharedScheduledExecutor().scheduleAtFixedRate(this::generateCert, + certConfig.getRefreshInterval(), certConfig.getRefreshInterval(), TimeUnit.MILLISECONDS); + } + + /** + * Try to connect to remote certificate authorization + * + * @param certConfig certificate authorization address + */ + protected void connect0(CertConfig certConfig) { + String caCertPath = certConfig.getCaCertPath(); + String remoteAddress = certConfig.getRemoteAddress(); + logger.info("Try to connect to Dubbo Cert Authority server: " + remoteAddress + ", caCertPath: " + remoteAddress); + try { + if (StringUtils.isNotEmpty(caCertPath)) { + channel = NettyChannelBuilder.forTarget(remoteAddress) + .sslContext( + GrpcSslContexts.forClient() + .trustManager(new File(caCertPath)) + .build()) + .build(); + } else { + logger.warn(CONFIG_SSL_CONNECT_INSECURE, "", "", + "No caCertPath is provided, will use insecure connection."); + channel = NettyChannelBuilder.forTarget(remoteAddress) + .sslContext(GrpcSslContexts.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE) + .build()) + .build(); + } + } catch (Exception e) { + logger.error(LoggerCodeConstants.CONFIG_SSL_PATH_LOAD_FAILED, "", "", "Failed to load SSL cert file.", e); + throw new RuntimeException(e); + } + } + + public synchronized void disConnect() { + if (refreshFuture != null) { + refreshFuture.cancel(true); + refreshFuture = null; + } + if (channel != null) { + channel = null; + } + } + + public boolean isConnected() { + return certConfig != null && channel != null && certPair != null; + } + + protected CertPair generateCert() { + if (certPair != null && !certPair.isExpire()) { + return certPair; + } + synchronized (this) { + if (certPair == null || certPair.isExpire()) { + try { + logger.info("Try to generate cert from Dubbo Certificate Authority."); + CertPair certFromRemote = refreshCert(); + if (certFromRemote != null) { + certPair = certFromRemote; + } else { + logger.error(CONFIG_SSL_CERT_GENERATE_FAILED, "", "", "Generate Cert from Dubbo Certificate Authority failed."); + } + } catch (Exception e) { + logger.error(REGISTRY_FAILED_GENERATE_CERT_ISTIO, "", "", "Generate Cert from Istio failed.", e); + } + } + } + return certPair; + } + + /** + * Request remote certificate authorization to generate cert pair for current Dubbo instance + * + * @return cert pair + * @throws IOException ioException + */ + protected CertPair refreshCert() throws IOException { + KeyPair keyPair = signWithEcdsa(); + + if (keyPair == null) { + keyPair = signWithRsa(); + } + + if (keyPair == null) { + logger.error(CONFIG_SSL_CERT_GENERATE_FAILED, "", "", "Generate Key failed. Please check if your system support."); + return null; + } + + String csr = generateCsr(keyPair); + DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub stub = DubboCertificateServiceGrpc.newBlockingStub(channel); + stub = setHeaderIfNeed(stub); + + String privateKeyPem = generatePrivatePemKey(keyPair); + DubboCertificateResponse certificateResponse = stub.createCertificate(generateRequest(csr)); + + if (certificateResponse == null || !certificateResponse.getSuccess()) { + logger.error(CONFIG_SSL_CERT_GENERATE_FAILED, "", "", "Failed to generate cert from Dubbo Certificate Authority. " + + "Message: " + (certificateResponse == null ? "null" : certificateResponse.getMessage())); + return null; + } + logger.info("Successfully generate cert from Dubbo Certificate Authority. Cert expire time: " + certificateResponse.getExpireTime()); + + return new CertPair(privateKeyPem, + certificateResponse.getCertPem(), + String.join("\n", certificateResponse.getTrustCertsList()), + certificateResponse.getExpireTime()); + } + + private DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub setHeaderIfNeed(DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub stub) throws IOException { + String oidcTokenPath = certConfig.getOidcTokenPath(); + if (StringUtils.isNotEmpty(oidcTokenPath)) { + Metadata header = new Metadata(); + Metadata.Key key = Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER); + header.put(key, "Bearer " + + IOUtils.read(new FileReader(oidcTokenPath)) + .replace("\n", "") + .replace("\t", "") + .replace("\r", "") + .trim()); + + stub = stub.withInterceptors(newAttachHeadersInterceptor(header)); + logger.info("Use oidc token from " + oidcTokenPath + " to connect to Dubbo Certificate Authority."); + } else { + logger.warn(CONFIG_SSL_CONNECT_INSECURE, "", "", + "Use insecure connection to connect to Dubbo Certificate Authority. Reason: No oidc token is provided."); + } + return stub; + } + + /** + * Generate key pair with RSA + * + * @return key pair + */ + protected static KeyPair signWithRsa() { + KeyPair keyPair = null; + try { + KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA"); + kpGenerator.initialize(4096); + java.security.KeyPair keypair = kpGenerator.generateKeyPair(); + PublicKey publicKey = keypair.getPublic(); + PrivateKey privateKey = keypair.getPrivate(); + ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(keypair.getPrivate()); + keyPair = new KeyPair(publicKey, privateKey, signer); + } catch (NoSuchAlgorithmException | OperatorCreationException e) { + logger.error(CONFIG_SSL_CERT_GENERATE_FAILED, "", "", "Generate Key with SHA256WithRSA algorithm failed. Please check if your system support.", e); + } + return keyPair; + } + + /** + * Generate key pair with ECDSA + * + * @return key pair + */ + protected static KeyPair signWithEcdsa() { + KeyPair keyPair = null; + try { + ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1"); + KeyPairGenerator g = KeyPairGenerator.getInstance("EC"); + g.initialize(ecSpec, new SecureRandom()); + java.security.KeyPair keypair = g.generateKeyPair(); + PublicKey publicKey = keypair.getPublic(); + PrivateKey privateKey = keypair.getPrivate(); + ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA").build(privateKey); + keyPair = new KeyPair(publicKey, privateKey, signer); + } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | OperatorCreationException e) { + logger.error(CONFIG_SSL_CERT_GENERATE_FAILED, "", "", "Generate Key with secp256r1 algorithm failed. Please check if your system support. " + + "Will attempt to generate with RSA2048.", e); + } + return keyPair; + } + + private DubboCertificateRequest generateRequest(String csr) { + return DubboCertificateRequest.newBuilder().setCsr(csr).setType("CONNECTION").build(); + } + + /** + * Generate private key in pem encoded + * + * @param keyPair key pair + * @return private key + * @throws IOException ioException + */ + private String generatePrivatePemKey(KeyPair keyPair) throws IOException { + String key = generatePemKey("RSA PRIVATE KEY", keyPair.getPrivateKey().getEncoded()); + if (logger.isDebugEnabled()) { + logger.debug("Generated Private Key. \n" + key); + } + return key; + } + + /** + * Generate content in pem encoded + * + * @param type content type + * @param content content + * @return encoded data + * @throws IOException ioException + */ + private String generatePemKey(String type, byte[] content) throws IOException { + PemObject pemObject = new PemObject(type, content); + StringWriter str = new StringWriter(); + JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(str); + jcaPEMWriter.writeObject(pemObject); + jcaPEMWriter.close(); + str.close(); + return str.toString(); + } + + /** + * Generate CSR (Certificate Sign Request) + * + * @param keyPair key pair to request + * @return csr + * @throws IOException ioException + */ + private String generateCsr(KeyPair keyPair) throws IOException { + PKCS10CertificationRequest request = new JcaPKCS10CertificationRequestBuilder( + new X500Name("O=" + "cluster.domain"), keyPair.getPublicKey()) + .build(keyPair.getSigner()); + + String csr = generatePemKey("CERTIFICATE REQUEST", request.getEncoded()); + + if (logger.isDebugEnabled()) { + logger.debug("CSR Request to Dubbo Certificate Authorization. \n" + csr); + } + return csr; + } + + protected static class KeyPair { + private final PublicKey publicKey; + private final PrivateKey privateKey; + private final ContentSigner signer; + + public KeyPair(PublicKey publicKey, PrivateKey privateKey, ContentSigner signer) { + this.publicKey = publicKey; + this.privateKey = privateKey; + this.signer = signer; + } + + public PublicKey getPublicKey() { + return publicKey; + } + + public PrivateKey getPrivateKey() { + return privateKey; + } + + public ContentSigner getSigner() { + return signer; + } + } +} diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertProvider.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertProvider.java new file mode 100644 index 0000000000..df2dfded25 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/DubboCertProvider.java @@ -0,0 +1,64 @@ +/* + * 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.security.cert; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.ssl.AuthPolicy; +import org.apache.dubbo.common.ssl.Cert; +import org.apache.dubbo.common.ssl.CertProvider; +import org.apache.dubbo.common.ssl.ProviderCert; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import java.nio.charset.StandardCharsets; + +@Activate +public class DubboCertProvider implements CertProvider { + private final DubboCertManager dubboCertManager; + + + public DubboCertProvider(FrameworkModel frameworkModel) { + dubboCertManager = frameworkModel.getBeanFactory().getBean(DubboCertManager.class); + } + + @Override + public boolean isSupport(URL address) { + return dubboCertManager != null && dubboCertManager.isConnected(); + } + + @Override + public ProviderCert getProviderConnectionConfig(URL localAddress) { + CertPair certPair = dubboCertManager.generateCert(); + if (certPair == null) { + return null; + } + return new ProviderCert(certPair.getCertificate().getBytes(StandardCharsets.UTF_8), + certPair.getPrivateKey().getBytes(StandardCharsets.UTF_8), + certPair.getTrustCerts().getBytes(StandardCharsets.UTF_8), AuthPolicy.NONE); + } + + @Override + public Cert getConsumerConnectionConfig(URL remoteAddress) { + CertPair certPair = dubboCertManager.generateCert(); + if (certPair == null) { + return null; + } + return new Cert(certPair.getCertificate().getBytes(StandardCharsets.UTF_8), + certPair.getPrivateKey().getBytes(StandardCharsets.UTF_8), + certPair.getTrustCerts().getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/dubbo-plugin/dubbo-security/src/main/proto/ca.proto b/dubbo-plugin/dubbo-security/src/main/proto/ca.proto new file mode 100644 index 0000000000..60c5f58e16 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/proto/ca.proto @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; + +import "google/protobuf/struct.proto"; + +package org.apache.dubbo.auth.v1alpha1; + +option go_package = "github.com/apache/dubbo-admin/ca/v1alpha1"; +option java_multiple_files = true; + + +message DubboCertificateRequest { + string csr = 1; + string type = 2; + + google.protobuf.Struct metadata = 3; +} + +message DubboCertificateResponse { + bool success = 1; + string cert_pem = 2; + repeated string trust_certs = 3; + int64 expire_time = 4; + string message = 5; +} + +service DubboCertificateService { + rpc CreateCertificate(DubboCertificateRequest) + returns (DubboCertificateResponse) { + } +} diff --git a/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.deploy.ApplicationDeployListener b/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.deploy.ApplicationDeployListener new file mode 100644 index 0000000000..724bc19065 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.deploy.ApplicationDeployListener @@ -0,0 +1 @@ +cert=org.apache.dubbo.security.cert.CertDeployerListener diff --git a/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider b/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider new file mode 100644 index 0000000000..b95444be8a --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.ssl.CertProvider @@ -0,0 +1 @@ +dubbo=org.apache.dubbo.security.cert.DubboCertProvider diff --git a/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer b/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer new file mode 100644 index 0000000000..302ec9e343 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer @@ -0,0 +1 @@ +cert=org.apache.dubbo.security.cert.CertScopeModelInitializer diff --git a/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java new file mode 100644 index 0000000000..ce6a5fa665 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/CertDeployerListenerTest.java @@ -0,0 +1,242 @@ +/* + * 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.security.cert; + +import org.apache.dubbo.common.deploy.ApplicationDeployer; +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.MetadataReportConfig; +import org.apache.dubbo.config.SslConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mockito.MockedConstruction; +import org.mockito.Mockito; + +import java.util.concurrent.atomic.AtomicReference; + +class CertDeployerListenerTest { + @Test + void testEmpty1() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + applicationModel.getDeployer().start(); + Mockito.verify(reference.get(), Mockito.times(0)) + .connect(Mockito.any()); + applicationModel.getDeployer().stop(); + Mockito.verify(reference.get(), Mockito.atLeast(1)).disConnect(); + frameworkModel.destroy(); + } + } + + @Test + void testEmpty2() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + applicationModel.getApplicationConfigManager().setSsl(new SslConfig()); + applicationModel.getDeployer().start(); + Mockito.verify(reference.get(), Mockito.times(0)) + .connect(Mockito.any()); + applicationModel.getDeployer().stop(); + Mockito.verify(reference.get(), Mockito.atLeast(1)).disConnect(); + frameworkModel.destroy(); + } + } + + @Test + void testCreate() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + SslConfig sslConfig = new SslConfig(); + sslConfig.setCaAddress("127.0.0.1:30060"); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + + applicationModel.getDeployer().start(); + Mockito.verify(reference.get(), Mockito.times(1)) + .connect(Mockito.any()); + applicationModel.getDeployer().stop(); + Mockito.verify(reference.get(), Mockito.atLeast(1)) + .disConnect(); + frameworkModel.destroy(); + } + } + + @Test + void testFailure() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + SslConfig sslConfig = new SslConfig(); + sslConfig.setCaAddress("127.0.0.1:30060"); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + applicationModel.getApplicationConfigManager().addMetadataReport(new MetadataReportConfig("absent")); + + ApplicationDeployer deployer = applicationModel.getDeployer(); + Assertions.assertThrows(IllegalArgumentException.class, deployer::start); + Mockito.verify(reference.get(), Mockito.times(1)) + .connect(Mockito.any()); + Mockito.verify(reference.get(), Mockito.atLeast(1)) + .disConnect(); + frameworkModel.destroy(); + } + } + + @Test + void testNotFound1() { + ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader newClassLoader = new ClassLoader(originClassLoader) { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (name.startsWith("io.grpc.Channel")) { + throw new ClassNotFoundException("Test"); + } + return super.loadClass(name); + } + }; + Thread.currentThread().setContextClassLoader(newClassLoader); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + // ignore + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + SslConfig sslConfig = new SslConfig(); + sslConfig.setCaAddress("127.0.0.1:30060"); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + + applicationModel.getDeployer().start(); + applicationModel.getDeployer().stop(); + Assertions.assertEquals(0, construction.constructed().size()); + frameworkModel.destroy(); + } + Thread.currentThread().setContextClassLoader(originClassLoader); + } + + @Test + void testNotFound2() { + ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader newClassLoader = new ClassLoader(originClassLoader) { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (name.startsWith("org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder")) { + throw new ClassNotFoundException("Test"); + } + return super.loadClass(name); + } + }; + Thread.currentThread().setContextClassLoader(newClassLoader); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + // ignore + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + SslConfig sslConfig = new SslConfig(); + sslConfig.setCaAddress("127.0.0.1:30060"); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + + applicationModel.getDeployer().start(); + applicationModel.getDeployer().stop(); + Assertions.assertEquals(0, construction.constructed().size()); + frameworkModel.destroy(); + } + Thread.currentThread().setContextClassLoader(originClassLoader); + } + + @Test + void testParams1() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + SslConfig sslConfig = new SslConfig(); + sslConfig.setCaAddress("127.0.0.1:30060"); + sslConfig.setCaCertPath("certs/ca.crt"); + sslConfig.setOidcTokenPath("token"); + sslConfig.setEnvType("test"); + applicationModel.getApplicationConfigManager().setSsl(sslConfig); + + applicationModel.getDeployer().start(); + Mockito.verify(reference.get(), Mockito.times(1)) + .connect(new CertConfig("127.0.0.1:30060", "test", "certs/ca.crt", "token")); + applicationModel.getDeployer().stop(); + Mockito.verify(reference.get(), Mockito.atLeast(1)) + .disConnect(); + frameworkModel.destroy(); + } + } + + @Disabled("Enable me until properties from envs work.") + @Test + void testParams2() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + System.setProperty("dubbo.ssl.ca-address", "127.0.0.1:30060"); + System.setProperty("dubbo.ssl.ca-cert-path", "certs/ca.crt"); + System.setProperty("dubbo.ssl.oidc-token-path", "token"); + System.setProperty("dubbo.ssl.env-type", "test"); + FrameworkModel frameworkModel = new FrameworkModel(); + ApplicationModel applicationModel = frameworkModel.newApplication(); + applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("test")); + + applicationModel.getDeployer().start(); + Mockito.verify(reference.get(), Mockito.times(1)) + .connect(new CertConfig("127.0.0.1:30060", "test", "certs/ca.crt", "token")); + applicationModel.getDeployer().stop(); + Mockito.verify(reference.get(), Mockito.atLeast(1)).disConnect(); + frameworkModel.destroy(); + System.clearProperty("dubbo.ssl.ca-address"); + System.clearProperty("dubbo.ssl.ca-cert-path"); + System.clearProperty("dubbo.ssl.oidc-token-path"); + System.clearProperty("dubbo.ssl.env-type"); + } + } +} diff --git a/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java new file mode 100644 index 0000000000..a25c9d330c --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertManagerTest.java @@ -0,0 +1,284 @@ +/* + * 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.security.cert; + +import org.apache.dubbo.auth.v1alpha1.DubboCertificateResponse; +import org.apache.dubbo.auth.v1alpha1.DubboCertificateServiceGrpc; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import io.grpc.Channel; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import static org.awaitility.Awaitility.await; +import static org.mockito.Answers.CALLS_REAL_METHODS; + +class DubboCertManagerTest { + @Test + void test1() { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertManager certManager = new DubboCertManager(frameworkModel) { + @Override + protected void connect0(CertConfig certConfig) { + Assertions.assertEquals("127.0.0.1:30060", certConfig.getRemoteAddress()); + Assertions.assertEquals("caCertPath", certConfig.getCaCertPath()); + } + + @Override + protected CertPair generateCert() { + return null; + } + + @Override + protected void scheduleRefresh() { + + } + }; + certManager.connect(new CertConfig("127.0.0.1:30060", null, "caCertPath", "oidc")); + Assertions.assertEquals(new CertConfig("127.0.0.1:30060", null, "caCertPath", "oidc"), certManager.certConfig); + + certManager.connect(new CertConfig("127.0.0.1:30060", "Kubernetes", "caCertPath", "oidc123")); + Assertions.assertEquals(new CertConfig("127.0.0.1:30060", "Kubernetes", "caCertPath", "oidc123"), certManager.certConfig); + + certManager.connect(new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345")); + Assertions.assertEquals(new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345"), certManager.certConfig); + + CertConfig certConfig = new CertConfig("127.0.0.1:30060", "vm", "caCertPath", "oidc"); + Assertions.assertThrows(IllegalArgumentException.class, () -> certManager.connect(certConfig)); + Assertions.assertEquals(new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345"), certManager.certConfig); + + certManager.connect(null); + Assertions.assertEquals(new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345"), certManager.certConfig); + + certManager.connect(new CertConfig(null, null, null, null)); + Assertions.assertEquals(new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345"), certManager.certConfig); + + certManager.channel = Mockito.mock(Channel.class); + certManager.connect(new CertConfig("error", null, "error", "error")); + Assertions.assertEquals(new CertConfig("127.0.0.1:30060", "kubernetes", "caCertPath", "oidc345"), certManager.certConfig); + + frameworkModel.destroy(); + } + + @Test + void testRefresh() { + FrameworkModel frameworkModel = new FrameworkModel(); + AtomicInteger count = new AtomicInteger(0); + DubboCertManager certManager = new DubboCertManager(frameworkModel) { + @Override + protected CertPair generateCert() { + count.incrementAndGet(); + return null; + } + }; + + certManager.certConfig = new CertConfig(null, null, null, null, 10); + certManager.scheduleRefresh(); + + Assertions.assertNotNull(certManager.refreshFuture); + await().until(() -> count.get() > 1); + certManager.refreshFuture.cancel(false); + frameworkModel.destroy(); + } + + @Test + void testConnect1() { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertManager certManager = new DubboCertManager(frameworkModel); + CertConfig certConfig = new CertConfig("127.0.0.1:30062", null, null, null); + certManager.connect0(certConfig); + Assertions.assertNotNull(certManager.channel); + Assertions.assertEquals("127.0.0.1:30062", certManager.channel.authority()); + + frameworkModel.destroy(); + } + + @Test + void testConnect2() { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertManager certManager = new DubboCertManager(frameworkModel); + String file = this.getClass().getClassLoader().getResource("certs/ca.crt").getFile(); + CertConfig certConfig = new CertConfig("127.0.0.1:30062", null, file, null); + certManager.connect0(certConfig); + Assertions.assertNotNull(certManager.channel); + Assertions.assertEquals("127.0.0.1:30062", certManager.channel.authority()); + + frameworkModel.destroy(); + } + + @Test + void testConnect3() { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertManager certManager = new DubboCertManager(frameworkModel); + String file = this.getClass().getClassLoader().getResource("certs/broken-ca.crt").getFile(); + CertConfig certConfig = new CertConfig("127.0.0.1:30062", null, file, null); + Assertions.assertThrows(RuntimeException.class, () -> certManager.connect0(certConfig)); + + frameworkModel.destroy(); + } + + @Test + void testDisconnect() { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertManager certManager = new DubboCertManager(frameworkModel); + ScheduledFuture scheduledFuture = Mockito.mock(ScheduledFuture.class); + certManager.refreshFuture = scheduledFuture; + certManager.disConnect(); + Assertions.assertNull(certManager.refreshFuture); + Mockito.verify(scheduledFuture, Mockito.times(1)).cancel(true); + + + certManager.channel = Mockito.mock(Channel.class); + certManager.disConnect(); + Assertions.assertNull(certManager.channel); + + frameworkModel.destroy(); + } + + @Test + void testConnected() { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertManager certManager = new DubboCertManager(frameworkModel); + + Assertions.assertFalse(certManager.isConnected()); + + certManager.certConfig = Mockito.mock(CertConfig.class); + Assertions.assertFalse(certManager.isConnected()); + + certManager.channel = Mockito.mock(Channel.class); + Assertions.assertFalse(certManager.isConnected()); + + certManager.certPair = Mockito.mock(CertPair.class); + Assertions.assertTrue(certManager.isConnected()); + + frameworkModel.destroy(); + } + + @Test + void testGenerateCert() { + FrameworkModel frameworkModel = new FrameworkModel(); + + AtomicBoolean exception = new AtomicBoolean(false); + AtomicReference certPairReference = new AtomicReference<>(); + DubboCertManager certManager = new DubboCertManager(frameworkModel) { + @Override + protected CertPair refreshCert() throws IOException { + if (exception.get()) { + throw new IOException("test"); + } + return certPairReference.get(); + } + }; + + CertPair certPair = new CertPair("", "", "", Long.MAX_VALUE); + certPairReference.set(certPair); + + Assertions.assertEquals(certPair, certManager.generateCert()); + + certManager.certPair = new CertPair("", "", "", Long.MAX_VALUE - 10000); + Assertions.assertEquals(new CertPair("", "", "", Long.MAX_VALUE - 10000), certManager.generateCert()); + + certManager.certPair = new CertPair("", "", "", 0); + Assertions.assertEquals(certPair, certManager.generateCert()); + + certManager.certPair = new CertPair("", "", "", 0); + certPairReference.set(null); + Assertions.assertEquals(new CertPair("", "", "", 0), certManager.generateCert()); + + exception.set(true); + Assertions.assertEquals(new CertPair("", "", "", 0), certManager.generateCert()); + + frameworkModel.destroy(); + } + + @Test + void testSignWithRsa() { + DubboCertManager.KeyPair keyPair = DubboCertManager.signWithRsa(); + Assertions.assertNotNull(keyPair); + Assertions.assertNotNull(keyPair.getPrivateKey()); + Assertions.assertNotNull(keyPair.getPublicKey()); + Assertions.assertNotNull(keyPair.getSigner()); + } + + @Test + void testSignWithEcdsa() { + DubboCertManager.KeyPair keyPair = DubboCertManager.signWithEcdsa(); + Assertions.assertNotNull(keyPair); + Assertions.assertNotNull(keyPair.getPrivateKey()); + Assertions.assertNotNull(keyPair.getPublicKey()); + Assertions.assertNotNull(keyPair.getSigner()); + } + + + @Test + void testRefreshCert() throws IOException { + try (MockedStatic managerMock = Mockito.mockStatic(DubboCertManager.class, CALLS_REAL_METHODS)) { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertManager certManager = new DubboCertManager(frameworkModel); + managerMock.when(DubboCertManager::signWithEcdsa).thenReturn(null); + managerMock.when(DubboCertManager::signWithRsa).thenReturn(null); + + Assertions.assertNull(certManager.refreshCert()); + + managerMock.when(DubboCertManager::signWithEcdsa).thenCallRealMethod(); + + certManager.channel = Mockito.mock(Channel.class); + try (MockedStatic mockGrpc = Mockito.mockStatic(DubboCertificateServiceGrpc.class, CALLS_REAL_METHODS)) { + DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub stub = Mockito.mock(DubboCertificateServiceGrpc.DubboCertificateServiceBlockingStub.class); + mockGrpc.when(() -> DubboCertificateServiceGrpc.newBlockingStub(Mockito.any(Channel.class))).thenReturn(stub); + Mockito.when(stub.createCertificate(Mockito.any())).thenReturn( + DubboCertificateResponse.newBuilder() + .setSuccess(false).build()); + + certManager.certConfig = new CertConfig(null, null, null, null); + Assertions.assertNull(certManager.refreshCert()); + + String file = this.getClass().getClassLoader().getResource("certs/token").getFile(); + Mockito.when(stub.withInterceptors(Mockito.any())).thenReturn(stub); + certManager.certConfig = new CertConfig(null, null, null, file); + + Assertions.assertNull(certManager.refreshCert()); + Mockito.verify(stub, Mockito.times(1)).withInterceptors(Mockito.any()); + + Mockito.when(stub.createCertificate(Mockito.any())).thenReturn( + DubboCertificateResponse.newBuilder() + .setSuccess(true) + .setCertPem("certPem") + .addTrustCerts("trustCerts") + .setExpireTime(123456).build()); + CertPair certPair = certManager.refreshCert(); + Assertions.assertNotNull(certPair); + Assertions.assertEquals("certPem", certPair.getCertificate()); + Assertions.assertEquals("trustCerts", certPair.getTrustCerts()); + Assertions.assertEquals(123456, certPair.getExpireTime()); + + Mockito.when(stub.createCertificate(Mockito.any())).thenReturn(null); + Assertions.assertNull(certManager.refreshCert()); + } + + frameworkModel.destroy(); + } + } +} diff --git a/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertProviderTest.java b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertProviderTest.java new file mode 100644 index 0000000000..e022473ee4 --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/test/java/org/apache/dubbo/security/cert/DubboCertProviderTest.java @@ -0,0 +1,150 @@ +/* + * 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.security.cert; + +import org.apache.dubbo.common.ssl.AuthPolicy; +import org.apache.dubbo.common.ssl.Cert; +import org.apache.dubbo.common.ssl.ProviderCert; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.MockedConstruction; +import org.mockito.Mockito; + +import java.util.concurrent.atomic.AtomicReference; + +class DubboCertProviderTest { + @Test + void testEnable() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertProvider provider = new DubboCertProvider(frameworkModel); + + Mockito.when(reference.get().isConnected()).thenReturn(true); + Assertions.assertTrue(provider.isSupport(null)); + + Mockito.when(reference.get().isConnected()).thenReturn(false); + Assertions.assertFalse(provider.isSupport(null)); + + frameworkModel.destroy(); + } + } + + @Test + void testEnable1() { + ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader newClassLoader = new ClassLoader(originClassLoader) { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (name.startsWith("io.grpc.Channel")) { + throw new ClassNotFoundException("Test"); + } + return super.loadClass(name); + } + }; + Thread.currentThread().setContextClassLoader(newClassLoader); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + // ignore + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertProvider provider = new DubboCertProvider(frameworkModel); + + Assertions.assertFalse(provider.isSupport(null)); + + frameworkModel.destroy(); + } + Thread.currentThread().setContextClassLoader(originClassLoader); + } + + @Test + void testEnable2() { + ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader newClassLoader = new ClassLoader(originClassLoader) { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (name.startsWith("org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder")) { + throw new ClassNotFoundException("Test"); + } + return super.loadClass(name); + } + }; + Thread.currentThread().setContextClassLoader(newClassLoader); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + // ignore + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertProvider provider = new DubboCertProvider(frameworkModel); + + Assertions.assertFalse(provider.isSupport(null)); + + frameworkModel.destroy(); + } + Thread.currentThread().setContextClassLoader(originClassLoader); + } + + @Test + void getProviderConnectionConfigTest() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertProvider provider = new DubboCertProvider(frameworkModel); + Assertions.assertNull(provider.getProviderConnectionConfig(null)); + + CertPair certPair = new CertPair("privateKey", "publicKey", "trustCerts", 12345); + Mockito.when(reference.get().generateCert()).thenReturn(certPair); + ProviderCert providerConnectionConfig = provider.getProviderConnectionConfig(null); + Assertions.assertArrayEquals("privateKey".getBytes(), providerConnectionConfig.getPrivateKey()); + Assertions.assertArrayEquals("publicKey".getBytes(), providerConnectionConfig.getKeyCertChain()); + Assertions.assertArrayEquals("trustCerts".getBytes(), providerConnectionConfig.getTrustCert()); + Assertions.assertEquals(AuthPolicy.NONE, providerConnectionConfig.getAuthPolicy()); + + frameworkModel.destroy(); + } + } + + @Test + void getConsumerConnectionConfigTest() { + AtomicReference reference = new AtomicReference<>(); + try (MockedConstruction construction = + Mockito.mockConstruction(DubboCertManager.class, (mock, context) -> { + reference.set(mock); + })) { + FrameworkModel frameworkModel = new FrameworkModel(); + DubboCertProvider provider = new DubboCertProvider(frameworkModel); + Assertions.assertNull(provider.getConsumerConnectionConfig(null)); + + CertPair certPair = new CertPair("privateKey", "publicKey", "trustCerts", 12345); + Mockito.when(reference.get().generateCert()).thenReturn(certPair); + Cert connectionConfig = provider.getConsumerConnectionConfig(null); + Assertions.assertArrayEquals("privateKey".getBytes(), connectionConfig.getPrivateKey()); + Assertions.assertArrayEquals("publicKey".getBytes(), connectionConfig.getKeyCertChain()); + Assertions.assertArrayEquals("trustCerts".getBytes(), connectionConfig.getTrustCert()); + + frameworkModel.destroy(); + } + } +} diff --git a/dubbo-plugin/dubbo-security/src/test/resources/certs/broken-ca.crt b/dubbo-plugin/dubbo-security/src/test/resources/certs/broken-ca.crt new file mode 100644 index 0000000000..176d0f815a --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/test/resources/certs/broken-ca.crt @@ -0,0 +1,7 @@ +-----BEGIN CERTIFICATE----- +MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau +sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m +oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG +Dfcog5wrJytaQ6UA0wE= +-----END CERTIFICATE----- diff --git a/dubbo-plugin/dubbo-security/src/test/resources/certs/ca.crt b/dubbo-plugin/dubbo-security/src/test/resources/certs/ca.crt new file mode 100644 index 0000000000..6c8511a73c --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/test/resources/certs/ca.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla +Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT +BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 ++L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu +g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd +Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau +sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m +oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG +Dfcog5wrJytaQ6UA0wE= +-----END CERTIFICATE----- diff --git a/dubbo-plugin/dubbo-security/src/test/resources/certs/token b/dubbo-plugin/dubbo-security/src/test/resources/certs/token new file mode 100644 index 0000000000..c7e6f0a16d --- /dev/null +++ b/dubbo-plugin/dubbo-security/src/test/resources/certs/token @@ -0,0 +1 @@ +tokentokentoken diff --git a/dubbo-plugin/pom.xml b/dubbo-plugin/pom.xml index ec7500d944..1266f7e313 100644 --- a/dubbo-plugin/pom.xml +++ b/dubbo-plugin/pom.xml @@ -32,6 +32,7 @@ dubbo-qos dubbo-auth dubbo-reactive + dubbo-security dubbo-spring-security diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java index 05aca85c64..d175a84c0a 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClient.java @@ -28,8 +28,9 @@ import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.remoting.RemotingException; -import org.apache.dubbo.remoting.transport.netty4.ssl.SslClientTlsHandler; import org.apache.dubbo.remoting.transport.AbstractClient; +import org.apache.dubbo.remoting.transport.netty4.ssl.SslClientTlsHandler; +import org.apache.dubbo.remoting.transport.netty4.ssl.SslContexts; import org.apache.dubbo.remoting.utils.UrlUtils; import io.netty.bootstrap.Bootstrap; @@ -41,13 +42,13 @@ import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.handler.proxy.Socks5ProxyHandler; +import io.netty.handler.ssl.SslContext; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.EventExecutorGroup; import java.net.InetSocketAddress; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_CLIENT_CONNECT_TIMEOUT; import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_FAILED_CONNECT_PROVIDER; import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_FAILED_DISCONNECT_PROVIDER; @@ -119,14 +120,15 @@ public class NettyClient extends AbstractClient { .channel(socketChannelClass()); bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.max(DEFAULT_CONNECT_TIMEOUT, getConnectTimeout())); + SslContext sslContext = SslContexts.buildClientSslContext(getUrl()); bootstrap.handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { int heartbeatInterval = UrlUtils.getHeartbeat(getUrl()); - if (getUrl().getParameter(SSL_ENABLED_KEY, false)) { - ch.pipeline().addLast("negotiation", new SslClientTlsHandler(getUrl())); + if (sslContext != null) { + ch.pipeline().addLast("negotiation", new SslClientTlsHandler(sslContext)); } NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this); diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java index 28cbe1f1b7..ebc0a2b793 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyConnectionClient.java @@ -28,6 +28,7 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.api.WireProtocol; import org.apache.dubbo.remoting.api.connection.AbstractConnectionClient; import org.apache.dubbo.remoting.transport.netty4.ssl.SslClientTlsHandler; +import org.apache.dubbo.remoting.transport.netty4.ssl.SslContexts; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.PooledByteBufAllocator; @@ -38,6 +39,7 @@ import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoop; import io.netty.channel.socket.SocketChannel; +import io.netty.handler.ssl.SslContext; import io.netty.util.AttributeKey; import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.GlobalEventExecutor; @@ -48,7 +50,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_CLIENT_THREADPOOL; -import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY; import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_CLIENT_CONNECT_TIMEOUT; import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_FAILED_CONNECT_PROVIDER; @@ -107,6 +108,7 @@ public class NettyConnectionClient extends AbstractConnectionClient { final NettyConnectionHandler connectionHandler = new NettyConnectionHandler(this); nettyBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getConnectTimeout()); + SslContext sslContext = SslContexts.buildClientSslContext(getUrl()); nettyBootstrap.handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) { @@ -114,8 +116,8 @@ public class NettyConnectionClient extends AbstractConnectionClient { final ChannelPipeline pipeline = ch.pipeline(); NettySslContextOperator nettySslContextOperator = new NettySslContextOperator(); - if (getUrl().getParameter(SSL_ENABLED_KEY, false)) { - pipeline.addLast("negotiation", new SslClientTlsHandler(getUrl())); + if (sslContext != null) { + pipeline.addLast("negotiation", new SslClientTlsHandler(sslContext)); } // pipeline.addLast("logging", new LoggingHandler(LogLevel.INFO)); //for debug diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServer.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServer.java index d0f0e7364b..239367320a 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServer.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServer.java @@ -26,7 +26,6 @@ import org.apache.dubbo.remoting.Channel; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.remoting.RemotingException; -import org.apache.dubbo.remoting.transport.netty4.ssl.SslContexts; import org.apache.dubbo.remoting.api.WireProtocol; import org.apache.dubbo.remoting.api.pu.AbstractPortUnificationServer; import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers; @@ -39,7 +38,6 @@ import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.socket.SocketChannel; -import io.netty.handler.ssl.SslContext; import io.netty.util.concurrent.Future; import java.net.InetSocketAddress; @@ -52,7 +50,6 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE; import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_FAILED_CLOSE; import static org.apache.dubbo.remoting.Constants.EVENT_LOOP_BOSS_POOL_NAME; import static org.apache.dubbo.remoting.Constants.EVENT_LOOP_WORKER_POOL_NAME; @@ -115,13 +112,6 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer { getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS), EVENT_LOOP_WORKER_POOL_NAME); - final boolean enableSsl = getUrl().getParameter(SSL_ENABLED_KEY, false); - final SslContext sslContext; - if (enableSsl) { - sslContext = SslContexts.buildServerSslContext(getUrl()); - } else { - sslContext = null; - } bootstrap.group(bossGroup, workerGroup) .channel(NettyEventLoopFactory.serverSocketChannelClass()) .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE) @@ -133,7 +123,7 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer { // Do not add idle state handler here, because it should be added in the protocol handler. final ChannelPipeline p = ch.pipeline(); final NettyPortUnificationServerHandler puHandler; - puHandler = new NettyPortUnificationServerHandler(getUrl(), sslContext, true, getProtocols(), + puHandler = new NettyPortUnificationServerHandler(getUrl(), true, getProtocols(), NettyPortUnificationServer.this, NettyPortUnificationServer.this.dubboChannels, getSupportedUrls(), getSupportedHandlers()); p.addLast("negotiation-protocol", puHandler); diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java index c48372865e..5d02ea4e16 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java @@ -20,12 +20,15 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.io.Bytes; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.ssl.CertManager; +import org.apache.dubbo.common.ssl.ProviderCert; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.remoting.Channel; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.api.ProtocolDetector; import org.apache.dubbo.remoting.api.WireProtocol; import org.apache.dubbo.remoting.buffer.ChannelBuffer; +import org.apache.dubbo.remoting.transport.netty4.ssl.SslContexts; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; @@ -33,7 +36,9 @@ import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslHandler; +import io.netty.handler.ssl.SslHandshakeCompletionEvent; +import javax.net.ssl.SSLSession; import java.net.InetSocketAddress; import java.util.List; import java.util.Map; @@ -45,8 +50,6 @@ public class NettyPortUnificationServerHandler extends ByteToMessageDecoder { private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger( NettyPortUnificationServerHandler.class); - - private final SslContext sslCtx; private final URL url; private final ChannelHandler handler; private final boolean detectSsl; @@ -56,11 +59,10 @@ public class NettyPortUnificationServerHandler extends ByteToMessageDecoder { private final Map handlerMapper; - public NettyPortUnificationServerHandler(URL url, SslContext sslCtx, boolean detectSsl, + public NettyPortUnificationServerHandler(URL url, boolean detectSsl, List protocols, ChannelHandler handler, Map dubboChannels, Map urlMapper, Map handlerMapper) { this.url = url; - this.sslCtx = sslCtx; this.protocols = protocols; this.detectSsl = detectSsl; this.handler = handler; @@ -84,6 +86,21 @@ public class NettyPortUnificationServerHandler extends ByteToMessageDecoder { } } + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof SslHandshakeCompletionEvent) { + SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt; + if (handshakeEvent.isSuccess()) { + SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession(); + LOGGER.info("TLS negotiation succeed with session: " + session); + } else { + LOGGER.error(INTERNAL_ERROR, "", "", "TLS negotiation failed when trying to accept new connection.", handshakeEvent.cause()); + ctx.close(); + } + } + super.userEventTriggered(ctx, evt); + } + @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { @@ -94,8 +111,11 @@ public class NettyPortUnificationServerHandler extends ByteToMessageDecoder { return; } - if (isSsl(in)) { - enableSsl(ctx); + CertManager certManager = url.getOrDefaultFrameworkModel().getBeanFactory().getBean(CertManager.class); + ProviderCert providerConnectionConfig = certManager.getProviderConnectionConfig(url, ctx.channel().remoteAddress()); + + if (providerConnectionConfig != null && isSsl(in)) { + enableSsl(ctx, providerConnectionConfig); } else { for (final WireProtocol protocol : protocols) { in.markReaderIndex(); @@ -136,13 +156,12 @@ public class NettyPortUnificationServerHandler extends ByteToMessageDecoder { } } - private void enableSsl(ChannelHandlerContext ctx) { + private void enableSsl(ChannelHandlerContext ctx, ProviderCert providerConnectionConfig) { ChannelPipeline p = ctx.pipeline(); - if (sslCtx != null) { - p.addLast("ssl", sslCtx.newHandler(ctx.alloc())); - } + SslContext sslContext = SslContexts.buildServerSslContext(providerConnectionConfig); + p.addLast("ssl", sslContext.newHandler(ctx.alloc())); p.addLast("unificationA", - new NettyPortUnificationServerHandler(url, sslCtx, false, protocols, + new NettyPortUnificationServerHandler(url, false, protocols, handler, dubboChannels, urlMapper, handlerMapper)); p.remove(this); } diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java index 0d585966bf..cbb547a526 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java @@ -49,7 +49,6 @@ import java.util.Map; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY; import static org.apache.dubbo.common.constants.CommonConstants.KEEP_ALIVE_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.TRANSPORT_FAILED_CLOSE; import static org.apache.dubbo.remoting.Constants.EVENT_LOOP_BOSS_POOL_NAME; import static org.apache.dubbo.remoting.Constants.EVENT_LOOP_WORKER_POOL_NAME; @@ -128,7 +127,6 @@ public class NettyServer extends AbstractServer { protected void initServerBootstrap(NettyServerHandler nettyServerHandler) { boolean keepalive = getUrl().getParameter(KEEP_ALIVE_KEY, Boolean.FALSE); - bootstrap.group(bossGroup, workerGroup) .channel(NettyEventLoopFactory.serverSocketChannelClass()) .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE) @@ -141,9 +139,7 @@ public class NettyServer extends AbstractServer { // FIXME: should we use getTimeout()? int idleTimeout = UrlUtils.getIdleTimeout(getUrl()); NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this); - if (getUrl().getParameter(SSL_ENABLED_KEY, false)) { - ch.pipeline().addLast("negotiation", new SslServerTlsHandler(getUrl())); - } + ch.pipeline().addLast("negotiation", new SslServerTlsHandler(getUrl())); ch.pipeline() .addLast("decoder", adapter.getDecoder()) .addLast("encoder", adapter.getEncoder()) diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslClientTlsHandler.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslClientTlsHandler.java index 09f687dd81..4c0ea5dd63 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslClientTlsHandler.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslClientTlsHandler.java @@ -58,7 +58,7 @@ public class SslClientTlsHandler extends ChannelInboundHandlerAdapter { SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt; if (handshakeEvent.isSuccess()) { SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession(); - logger.info("TLS negotiation succeed with session: " + session); + logger.info("TLS negotiation succeed with: " + session.getPeerHost()); ctx.pipeline().remove(this); } else { logger.error(INTERNAL_ERROR, "unknown error in remoting module", "", "TLS negotiation failed when trying to accept new connection.", handshakeEvent.cause()); diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslContexts.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslContexts.java index f595bdb316..ec07ad4e03 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslContexts.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslContexts.java @@ -19,8 +19,10 @@ package org.apache.dubbo.remoting.transport.netty4.ssl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.config.SslConfig; -import org.apache.dubbo.config.context.ConfigManager; +import org.apache.dubbo.common.ssl.AuthPolicy; +import org.apache.dubbo.common.ssl.Cert; +import org.apache.dubbo.common.ssl.CertManager; +import org.apache.dubbo.common.ssl.ProviderCert; import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.OpenSsl; @@ -40,19 +42,16 @@ public class SslContexts { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(SslContexts.class); - public static SslContext buildServerSslContext(URL url) { - ConfigManager globalConfigManager = url.getOrDefaultApplicationModel().getApplicationConfigManager(); - SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!")); - + public static SslContext buildServerSslContext(ProviderCert providerConnectionConfig) { SslContextBuilder sslClientContextBuilder; InputStream serverKeyCertChainPathStream = null; InputStream serverPrivateKeyPathStream = null; InputStream serverTrustCertStream = null; try { - serverKeyCertChainPathStream = sslConfig.getServerKeyCertChainPathStream(); - serverPrivateKeyPathStream = sslConfig.getServerPrivateKeyPathStream(); - serverTrustCertStream = sslConfig.getServerTrustCertCollectionPathStream(); - String password = sslConfig.getServerKeyPassword(); + serverKeyCertChainPathStream = providerConnectionConfig.getKeyCertChainInputStream(); + serverPrivateKeyPathStream = providerConnectionConfig.getPrivateKeyInputStream(); + serverTrustCertStream = providerConnectionConfig.getTrustCertInputStream(); + String password = providerConnectionConfig.getPassword(); if (password != null) { sslClientContextBuilder = SslContextBuilder.forServer(serverKeyCertChainPathStream, serverPrivateKeyPathStream, password); @@ -63,7 +62,11 @@ public class SslContexts { if (serverTrustCertStream != null) { sslClientContextBuilder.trustManager(serverTrustCertStream); - sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE); + if (providerConnectionConfig.getAuthPolicy() == AuthPolicy.CLIENT_AUTH) { + sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE); + } else { + sslClientContextBuilder.clientAuth(ClientAuth.OPTIONAL); + } } } catch (Exception e) { throw new IllegalArgumentException("Could not find certificate file or the certificate is invalid.", e); @@ -80,23 +83,26 @@ public class SslContexts { } public static SslContext buildClientSslContext(URL url) { - ConfigManager globalConfigManager = url.getOrDefaultApplicationModel().getApplicationConfigManager(); - SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!")); + CertManager certManager = url.getOrDefaultFrameworkModel().getBeanFactory().getBean(CertManager.class); + Cert consumerConnectionConfig = certManager.getConsumerConnectionConfig(url); + if (consumerConnectionConfig == null) { + return null; + } SslContextBuilder builder = SslContextBuilder.forClient(); InputStream clientTrustCertCollectionPath = null; InputStream clientCertChainFilePath = null; InputStream clientPrivateKeyFilePath = null; try { - clientTrustCertCollectionPath = sslConfig.getClientTrustCertCollectionPathStream(); + clientTrustCertCollectionPath = consumerConnectionConfig.getTrustCertInputStream(); if (clientTrustCertCollectionPath != null) { builder.trustManager(clientTrustCertCollectionPath); } - clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream(); - clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream(); + clientCertChainFilePath = consumerConnectionConfig.getKeyCertChainInputStream(); + clientPrivateKeyFilePath = consumerConnectionConfig.getPrivateKeyInputStream(); if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) { - String password = sslConfig.getClientKeyPassword(); + String password = consumerConnectionConfig.getPassword(); if (password != null) { builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath, password); } else { diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslServerTlsHandler.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslServerTlsHandler.java index a8c008b06c..5aaca5e00a 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslServerTlsHandler.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/ssl/SslServerTlsHandler.java @@ -19,6 +19,9 @@ package org.apache.dubbo.remoting.transport.netty4.ssl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.ssl.AuthPolicy; +import org.apache.dubbo.common.ssl.CertManager; +import org.apache.dubbo.common.ssl.ProviderCert; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; @@ -36,25 +39,18 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERR public class SslServerTlsHandler extends ByteToMessageDecoder { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(SslServerTlsHandler.class); - private final SslContext sslContext; - private final boolean detectSsl; + private final URL url; - - public SslServerTlsHandler() { - this(null, false); - } + private final boolean sslDetected; public SslServerTlsHandler(URL url) { - this(SslContexts.buildServerSslContext(url)); + this.url = url; + this.sslDetected = false; } - public SslServerTlsHandler(SslContext sslContext) { - this(sslContext, true); - } - - public SslServerTlsHandler(SslContext sslContext, boolean detectSsl) { - this.sslContext = sslContext; - this.detectSsl = detectSsl; + public SslServerTlsHandler(URL url, boolean sslDetected) { + this.url = url; + this.sslDetected = sslDetected; } @Override @@ -68,7 +64,7 @@ public class SslServerTlsHandler extends ByteToMessageDecoder { SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt; if (handshakeEvent.isSuccess()) { SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession(); - logger.info("TLS negotiation succeed with session: " + session); + logger.info("TLS negotiation succeed with: " + session.getPeerHost()); // Remove after handshake success. ctx.pipeline().remove(this); } else { @@ -86,23 +82,42 @@ public class SslServerTlsHandler extends ByteToMessageDecoder { return; } - if (isSsl(byteBuf)) { - enableSsl(channelHandlerContext); + if (sslDetected) { + return; } + CertManager certManager = url.getOrDefaultFrameworkModel().getBeanFactory().getBean(CertManager.class); + ProviderCert providerConnectionConfig = certManager.getProviderConnectionConfig(url, channelHandlerContext.channel().remoteAddress()); + + if (providerConnectionConfig == null) { + ChannelPipeline p = channelHandlerContext.pipeline(); + p.remove(this); + return; + } + + if (isSsl(byteBuf)) { + SslContext sslContext = SslContexts.buildServerSslContext(providerConnectionConfig); + enableSsl(channelHandlerContext, sslContext); + return; + } + + if (providerConnectionConfig.getAuthPolicy() == AuthPolicy.NONE) { + ChannelPipeline p = channelHandlerContext.pipeline(); + p.remove(this); + } + + logger.error(INTERNAL_ERROR, "", "", "TLS negotiation failed when trying to accept new connection."); + channelHandlerContext.close(); } private boolean isSsl(ByteBuf buf) { - if (detectSsl) { - return SslHandler.isEncrypted(buf); - } - return false; + return SslHandler.isEncrypted(buf); } - private void enableSsl(ChannelHandlerContext ctx) { + private void enableSsl(ChannelHandlerContext ctx, SslContext sslContext) { ChannelPipeline p = ctx.pipeline(); ctx.pipeline().addAfter(ctx.name(), null, sslContext.newHandler(ctx.alloc())); - p.addLast("unificationA", new SslServerTlsHandler(sslContext, false)); + p.addLast("unificationA", new SslServerTlsHandler(url, true)); p.remove(this); } diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index 90e91d7e4d..4494617120 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -194,6 +194,10 @@ org.apache.dubbo dubbo-auth + + org.apache.dubbo + dubbo-security + org.apache.dubbo dubbo-qos From 11f45d872603ecb78dbafa6a2099329a08ad0458 Mon Sep 17 00:00:00 2001 From: suncairong163 <105478245+suncairong163@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:40:14 +0800 Subject: [PATCH 087/144] Feature/resolve samples dependency conflict (#11705) --- dubbo-dependencies-bom/pom.xml | 2 +- .../metrics/sampler/CountSamplerTest.java | 2 - .../protocol/rest/ReferenceCountedClient.java | 38 +++++++++++++++++-- .../dubbo/rpc/protocol/rest/RestProtocol.java | 16 +++++--- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 5f03e7f142..7007a23b0e 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -141,7 +141,7 @@ 0.16.0 1.0.4 3.5.3 - 4.10.0 + 3.14.2 2.1.1 3.15.6.Final diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java index d592176515..ff3b6c0714 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java @@ -25,7 +25,6 @@ import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; import org.apache.dubbo.metrics.model.sample.MetricSample; -import org.jetbrains.annotations.NotNull; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -113,7 +112,6 @@ public class CountSamplerTest { MetricsKey.METRIC_RT_SUM.getName()).applyAsLong() == 4); } - @NotNull @SuppressWarnings("rawtypes") private Map getCollect(RTType rtType) { List> metricSamples = sampler.collectRT( diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java index 22de2147c2..ada7d5c1c3 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/ReferenceCountedClient.java @@ -16,24 +16,56 @@ */ package org.apache.dubbo.rpc.protocol.rest; +import org.apache.dubbo.common.URL; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.reference.ReferenceCountedResource; import org.apache.dubbo.remoting.http.RestClient; +import org.apache.dubbo.remoting.http.factory.RestClientFactory; + +import java.util.concurrent.ConcurrentMap; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_CLOSE_CLIENT; public class ReferenceCountedClient extends ReferenceCountedResource { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ReferenceCountedClient.class); - private final T client; + private ConcurrentMap> clients; + private URL url; + private RestClientFactory clientFactory; - public ReferenceCountedClient(T client) { + private T client; + + public ReferenceCountedClient(T client, ConcurrentMap> clients, RestClientFactory clientFactory, URL url) { this.client = client; + this.clients = clients; + this.clientFactory = clientFactory; + this.url = url; } public T getClient() { - return client; + + // for client destroy and create right now, only lock current client + synchronized (this) { + ReferenceCountedClient referenceCountedClient = clients.get(url.getAddress()); + + // for double check + if (referenceCountedClient.isDestroyed()) { + synchronized (this) { + referenceCountedClient = clients.get(url.getAddress()); + if (referenceCountedClient.isDestroyed()) { + RestClient restClient = clientFactory.createRestClient(url); + clients.put(url.getAddress(), new ReferenceCountedClient(restClient, clients, clientFactory, url)); + return (T) restClient; + } else { + return (T) referenceCountedClient.client; + } + } + + } else { + return client; + } + } } public boolean isDestroyed() { diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java index 4cd8376263..6884aacc14 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java @@ -70,6 +70,7 @@ import static org.apache.dubbo.rpc.protocol.rest.constans.RestConstant.PATH_SEPA public class RestProtocol extends AbstractProxyProtocol { private static final int DEFAULT_PORT = 80; + private static final String DEFAULT_CLIENT = org.apache.dubbo.remoting.Constants.OK_HTTP; private static final String DEFAULT_SERVER = Constants.JETTY; private final RestServerFactory serverFactory = new RestServerFactory(); @@ -136,6 +137,7 @@ public class RestProtocol extends AbstractProxyProtocol { }; } + @Override protected Invoker protocolBindingRefer(final Class type, final URL url) throws RpcException { @@ -144,17 +146,16 @@ public class RestProtocol extends AbstractProxyProtocol { synchronized (clients) { refClient = clients.get(url.getAddress()); if (refClient == null || refClient.isDestroyed()) { - refClient = ConcurrentHashMapUtils.computeIfAbsent(clients, url.getAddress(), _key -> createReferenceCountedClient(url)); + refClient = ConcurrentHashMapUtils.computeIfAbsent(clients, url.getAddress(), _key -> createReferenceCountedClient(url,clients)); } } } refClient.retain(); - final ReferenceCountedClient glueRefClient = refClient; - // resolve metadata Map> metadataMap = MetadataResolver.resolveConsumerServiceMetadata(type, url); + ReferenceCountedClient finalRefClient = refClient; Invoker invoker = new AbstractInvoker(type, url, new String[]{INTERFACE_KEY, GROUP_KEY, TOKEN_KEY}) { @Override protected Result doInvoke(Invocation invocation) { @@ -175,7 +176,8 @@ public class RestProtocol extends AbstractProxyProtocol { intercept.intercept(httpConnectionCreateContext); } - CompletableFuture future = glueRefClient.getClient().send(requestTemplate); + + CompletableFuture future = finalRefClient.getClient().send(requestTemplate); CompletableFuture responseFuture = new CompletableFuture<>(); AsyncRpcResult asyncRpcResult = new AsyncRpcResult(responseFuture, invocation); future.whenComplete((r, t) -> { @@ -231,12 +233,14 @@ public class RestProtocol extends AbstractProxyProtocol { } - private ReferenceCountedClient createReferenceCountedClient(URL url) throws RpcException { + private ReferenceCountedClient createReferenceCountedClient(URL url, ConcurrentMap> clients) throws RpcException { // url -> RestClient RestClient restClient = clientFactory.createRestClient(url); - return new ReferenceCountedClient<>(restClient); + ReferenceCountedClient refClient = new ReferenceCountedClient(restClient, clients, clientFactory, url); + + return refClient; } @Override From 16c61c53c6caf8ac5710f85ce7ddb2592da52dc3 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 10 Mar 2023 11:08:59 +0800 Subject: [PATCH 088/144] Fix metadata proxy load filter (#11769) --- .../apache/dubbo/registry/client/metadata/MetadataUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java index 91bbdfbec6..6434b24ae4 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java @@ -137,7 +137,7 @@ public class MetadataUtils { ModuleModel internalModel = applicationModel.getInternalModule(); ConsumerModel consumerModel = applicationModel.getInternalModule().registerInternalConsumer(MetadataService.class, url); - Protocol protocol = applicationModel.getExtensionLoader(Protocol.class).getAdaptiveExtension(); + Protocol protocol = applicationModel.getExtensionLoader(Protocol.class).getExtension(url.getProtocol(), false); url = url.setServiceModel(consumerModel); From 27420cf68acf9917ff982836ca3453b2616bd887 Mon Sep 17 00:00:00 2001 From: SeasonPan <244014926@qq.com> Date: Fri, 10 Mar 2023 15:18:41 +0800 Subject: [PATCH 089/144] [fix]Override the method of Object.clone(), but not implements Cloneable (#11761) --- .../java/org/apache/dubbo/rpc/cluster/router/state/BitList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java index 9694bf9f51..b3fda63948 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java @@ -52,7 +52,7 @@ import java.util.concurrent.ThreadLocalRandom; * @param * @since 3.0 */ -public class BitList extends AbstractList { +public class BitList extends AbstractList implements Cloneable { private final BitSet rootSet; private volatile List originList; private final static BitList emptyList = new BitList(Collections.emptyList()); From 8d1152d86df52b1c36a069d5375b661b44a5f98d Mon Sep 17 00:00:00 2001 From: songxiaosheng Date: Fri, 10 Mar 2023 15:19:58 +0800 Subject: [PATCH 090/144] :bug:Fix/consumer provider metrics name cover (#11753) --- .../dubbo/metrics/event/MethodEvent.java | 37 ++++++++ .../dubbo/metrics/event/MetricsEvent.java | 38 ++++++--- .../dubbo/metrics/model/MetricsKey.java | 6 -- .../collector/AggregateMetricsCollector.java | 85 +++++++++++-------- .../sample/MethodMetricsSampler.java | 42 +++++---- .../filter/MethodMetricsInterceptor.java | 29 +++++-- .../metrics/filter/MetricsClusterFilter.java | 14 ++- .../AggregateMetricsCollectorTest.java | 17 ++-- .../metrics/filter/MetricsFilterTest.java | 29 ++++--- .../DefaultMetricsCollectorTest.java | 22 ++--- .../metrics/sampler/CountSamplerTest.java | 69 +++++++-------- 11 files changed, 241 insertions(+), 147 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MethodEvent.java diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MethodEvent.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MethodEvent.java new file mode 100644 index 0000000000..c876070e17 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MethodEvent.java @@ -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.metrics.event; + +public class MethodEvent extends MetricsEvent { + private String type; + + public MethodEvent(Object source, String type) { + super(source); + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java index 5c49988f2e..0a67ac9029 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/MetricsEvent.java @@ -46,18 +46,32 @@ public abstract class MetricsEvent { } public enum Type { - TOTAL, - SUCCEED, - BUSINESS_FAILED, - REQUEST_TIMEOUT, - REQUEST_LIMIT, - PROCESSING, - UNKNOWN_FAILED, - TOTAL_FAILED, - APPLICATION_INFO, - NETWORK_EXCEPTION, - SERVICE_UNAVAILABLE, - CODEC_EXCEPTION; + TOTAL("TOTAL_%s"), + SUCCEED("SUCCEED_%s"), + BUSINESS_FAILED("BUSINESS_FAILED_%s"), + REQUEST_TIMEOUT("REQUEST_TIMEOUT_%s"), + REQUEST_LIMIT("REQUEST_LIMIT_%s"), + PROCESSING("PROCESSING_%s"), + UNKNOWN_FAILED("UNKNOWN_FAILED_%s"), + TOTAL_FAILED("TOTAL_FAILED_%s"), + APPLICATION_INFO("APPLICATION_INFO_%s"), + NETWORK_EXCEPTION("NETWORK_EXCEPTION_%s"), + SERVICE_UNAVAILABLE("SERVICE_UNAVAILABLE_%s"), + CODEC_EXCEPTION("CODEC_EXCEPTION_%s"),; + private String name; + + public final String getName() { + return this.name; + } + + public final String getNameByType(String type) { + return String.format(name, type); + } + + + Type(String name) { + this.name = name; + } } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java index 8d55c707b1..86b2c873c9 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java @@ -106,12 +106,6 @@ public enum MetricsKey { return String.format(name, type); } - - public final MetricsKey formatName(String type) { - this.name = String.format(name, type); - return this; - } - public final String getDescription() { return this.description; } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java index c5e0191d7b..664fa371de 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollector.java @@ -23,9 +23,9 @@ import org.apache.dubbo.config.context.ConfigManager; import org.apache.dubbo.config.nested.AggregationConfig; import org.apache.dubbo.metrics.aggregate.TimeWindowCounter; import org.apache.dubbo.metrics.aggregate.TimeWindowQuantile; +import org.apache.dubbo.metrics.event.MethodEvent; import org.apache.dubbo.metrics.event.MetricsEvent; import org.apache.dubbo.metrics.event.RTEvent; -import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.metrics.listener.MetricsListener; import org.apache.dubbo.metrics.model.MethodMetric; import org.apache.dubbo.metrics.model.MetricsKey; @@ -39,6 +39,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; import static org.apache.dubbo.metrics.model.MetricsCategory.QPS; import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; @@ -50,7 +52,7 @@ import static org.apache.dubbo.metrics.model.MetricsCategory.RT; public class AggregateMetricsCollector implements MetricsCollector, MetricsListener { private int bucketNum; private int timeWindowSeconds; - private final Map> methodTypeCounter = new ConcurrentHashMap<>(); + private final Map> methodTypeCounter = new ConcurrentHashMap<>(); private final ConcurrentMap rt = new ConcurrentHashMap<>(); private final ConcurrentHashMap qps = new ConcurrentHashMap<>(); private final ApplicationModel applicationModel; @@ -59,7 +61,7 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe private static final Integer DEFAULT_TIME_WINDOW_SECONDS = 120; public AggregateMetricsCollector(ApplicationModel applicationModel) { - this.registryerEventTypeHandler(); + this.registryEventTypeHandler(); this.applicationModel = applicationModel; ConfigManager configManager = applicationModel.getApplicationConfigManager(); @@ -78,8 +80,8 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe public void onEvent(MetricsEvent event) { if (event instanceof RTEvent) { onRTEvent((RTEvent) event); - } else if (event instanceof RequestEvent) { - onRequestEvent((RequestEvent) event); + } else if (event instanceof MethodEvent) { + onRequestEvent((MethodEvent) event); } } @@ -91,10 +93,10 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe } - private void onRequestEvent(RequestEvent event) { + private void onRequestEvent(MethodEvent event) { MethodMetric metric = (MethodMetric) event.getSource(); - MetricsEvent.Type type = event.getType(); + String type = event.getType(); ConcurrentMap counter = methodTypeCounter.get(type); @@ -103,7 +105,8 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe } TimeWindowCounter windowCounter = ConcurrentHashMapUtils.computeIfAbsent(counter, metric, methodMetric -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); - if (type == MetricsEvent.Type.TOTAL) { + if (MetricsEvent.Type.TOTAL.getNameByType(PROVIDER_SIDE).equals(type) + || MetricsEvent.Type.TOTAL.getNameByType(CONSUMER_SIDE).equals(type)) { TimeWindowCounter qpsCounter = ConcurrentHashMapUtils.computeIfAbsent(qps, metric, methodMetric -> new TimeWindowCounter(bucketNum, timeWindowSeconds)); qpsCounter.increment(); } @@ -121,47 +124,61 @@ public class AggregateMetricsCollector implements MetricsCollector, MetricsListe } private void collectRequests(List list) { - collectMethod(list, MetricsEvent.Type.TOTAL, MetricsKey.METRIC_REQUESTS_TOTAL_AGG); - collectMethod(list, MetricsEvent.Type.SUCCEED, MetricsKey.METRIC_REQUESTS_SUCCEED_AGG); - collectMethod(list, MetricsEvent.Type.UNKNOWN_FAILED, MetricsKey.METRIC_REQUESTS_FAILED_AGG); - collectMethod(list, MetricsEvent.Type.BUSINESS_FAILED, MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG); - collectMethod(list, MetricsEvent.Type.REQUEST_TIMEOUT, MetricsKey.METRIC_REQUESTS_TIMEOUT_AGG); - collectMethod(list, MetricsEvent.Type.REQUEST_LIMIT, MetricsKey.METRIC_REQUESTS_LIMIT_AGG); - collectMethod(list, MetricsEvent.Type.TOTAL_FAILED, MetricsKey.METRIC_REQUESTS_TOTAL_FAILED_AGG); - collectMethod(list, MetricsEvent.Type.NETWORK_EXCEPTION, MetricsKey.METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG); - collectMethod(list, MetricsEvent.Type.CODEC_EXCEPTION, MetricsKey.METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG); - collectMethod(list, MetricsEvent.Type.SERVICE_UNAVAILABLE, MetricsKey.METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG); + collectBySide(list, PROVIDER_SIDE); + collectBySide(list, CONSUMER_SIDE); } - private void collectMethod(List list, MetricsEvent.Type eventType, MetricsKey metricsKey) { + private void collectBySide(List list, String side) { + collectMethod(list, MetricsEvent.Type.TOTAL.getNameByType(side), MetricsKey.METRIC_REQUESTS_TOTAL_AGG); + collectMethod(list, MetricsEvent.Type.SUCCEED.getNameByType(side), MetricsKey.METRIC_REQUESTS_SUCCEED_AGG); + collectMethod(list, MetricsEvent.Type.UNKNOWN_FAILED.getNameByType(side), MetricsKey.METRIC_REQUESTS_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.BUSINESS_FAILED.getNameByType(side), MetricsKey.METRIC_REQUESTS_BUSINESS_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.REQUEST_TIMEOUT.getNameByType(side), MetricsKey.METRIC_REQUESTS_TIMEOUT_AGG); + collectMethod(list, MetricsEvent.Type.REQUEST_LIMIT.getNameByType(side), MetricsKey.METRIC_REQUESTS_LIMIT_AGG); + collectMethod(list, MetricsEvent.Type.TOTAL_FAILED.getNameByType(side), MetricsKey.METRIC_REQUESTS_TOTAL_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.NETWORK_EXCEPTION.getNameByType(side), MetricsKey.METRIC_REQUESTS_TOTAL_NETWORK_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.CODEC_EXCEPTION.getNameByType(side), MetricsKey.METRIC_REQUESTS_TOTAL_CODEC_FAILED_AGG); + collectMethod(list, MetricsEvent.Type.SERVICE_UNAVAILABLE.getNameByType(side), MetricsKey.METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG); + } + + private void collectMethod(List list, String eventType, MetricsKey metricsKey) { ConcurrentHashMap windowCounter = methodTypeCounter.get(eventType); if (windowCounter != null) { - windowCounter.forEach((k, v) -> list.add(new GaugeMetricSample<>(metricsKey.formatName(k.getSide()), k.getTags(), REQUESTS, v, TimeWindowCounter::get))); + windowCounter.forEach((k, v) -> list.add(new GaugeMetricSample<>(metricsKey.getNameByType(k.getSide()), + metricsKey.getDescription(), k.getTags(), REQUESTS, v, TimeWindowCounter::get))); } } private void collectQPS(List list) { - qps.forEach((k, v) -> list.add(new GaugeMetricSample<>(MetricsKey.METRIC_QPS.formatName(k.getSide()), k.getTags(), QPS, v, value -> value.get() / value.bucketLivedSeconds()))); + qps.forEach((k, v) -> list.add(new GaugeMetricSample<>(MetricsKey.METRIC_QPS.getNameByType(k.getSide()), + MetricsKey.METRIC_QPS.getDescription(), k.getTags(), QPS, v, value -> value.get() / value.bucketLivedSeconds()))); } private void collectRT(List list) { rt.forEach((k, v) -> { - list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P99.formatName(k.getSide()), k.getTags(), RT, v, value -> value.quantile(0.99))); - list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P95.formatName(k.getSide()), k.getTags(), RT, v, value -> value.quantile(0.95))); + list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P99.getNameByType(k.getSide()), + MetricsKey.METRIC_RT_P99.getDescription(), k.getTags(), RT, v, value -> value.quantile(0.99))); + list.add(new GaugeMetricSample<>(MetricsKey.METRIC_RT_P95.getNameByType(k.getSide()), + MetricsKey.METRIC_RT_P99.getDescription(), k.getTags(), RT, v, value -> value.quantile(0.95))); }); } - private void registryerEventTypeHandler() { - methodTypeCounter.put(MetricsEvent.Type.TOTAL, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.SUCCEED, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.UNKNOWN_FAILED, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.BUSINESS_FAILED, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.REQUEST_TIMEOUT, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.REQUEST_LIMIT, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.TOTAL_FAILED, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.SERVICE_UNAVAILABLE, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.NETWORK_EXCEPTION, new ConcurrentHashMap<>()); - methodTypeCounter.put(MetricsEvent.Type.CODEC_EXCEPTION, new ConcurrentHashMap<>()); + private void registryEventTypeHandler() { + registryBySide(PROVIDER_SIDE); + registryBySide(CONSUMER_SIDE); + } + + private void registryBySide(String side) { + methodTypeCounter.put(MetricsEvent.Type.TOTAL.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.SUCCEED.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.UNKNOWN_FAILED.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.BUSINESS_FAILED.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.REQUEST_TIMEOUT.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.REQUEST_LIMIT.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.TOTAL_FAILED.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.SERVICE_UNAVAILABLE.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.NETWORK_EXCEPTION.getNameByType(side), new ConcurrentHashMap<>()); + methodTypeCounter.put(MetricsEvent.Type.CODEC_EXCEPTION.getNameByType(side), new ConcurrentHashMap<>()); } private void registerListener() { diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java index b5a9af0157..a42f6c5b38 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/MethodMetricsSampler.java @@ -18,9 +18,9 @@ package org.apache.dubbo.metrics.collector.sample; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; +import org.apache.dubbo.metrics.event.MethodEvent; import org.apache.dubbo.metrics.event.MetricsEvent; import org.apache.dubbo.metrics.event.RTEvent; -import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.metrics.model.MethodMetric; import org.apache.dubbo.metrics.model.Metric; import org.apache.dubbo.metrics.model.MetricsCategory; @@ -34,10 +34,12 @@ import java.util.List; import java.util.concurrent.atomic.AtomicLong; import java.util.function.ToDoubleFunction; +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; import static org.apache.dubbo.metrics.model.MetricsCategory.REQUESTS; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; -public class MethodMetricsSampler extends SimpleMetricsCountSampler { +public class MethodMetricsSampler extends SimpleMetricsCountSampler { private final DefaultMetricsCollector collector; @@ -47,14 +49,15 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler sampleConfigure) { + MetricsCountSampleConfigurer sampleConfigure) { sampleConfigure.configureMetrics(configure -> new MethodMetric(collector.getApplicationName(), configure.getSource())); - sampleConfigure.configureEventHandler(configure -> collector.getEventMulticaster().publishEvent(new RequestEvent(configure.getMetric(), configure.getMetricName()))); + sampleConfigure.configureEventHandler(configure -> collector.getEventMulticaster().publishEvent(new MethodEvent(configure.getMetric(), + configure.getMetricName()))); } @Override public void rtConfigure( - MetricsCountSampleConfigurer sampleConfigure) { + MetricsCountSampleConfigurer sampleConfigure) { sampleConfigure.configureMetrics(configure -> new MethodMetric(collector.getApplicationName(), configure.getSource())); sampleConfigure.configureEventHandler(configure -> collector.getEventMulticaster().publishEvent(new RTEvent(configure.getMetric(), configure.getRt()))); } @@ -76,17 +79,22 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler list) { - count(list, MetricsEvent.Type.TOTAL, MetricsKey.METRIC_REQUESTS); - count(list, MetricsEvent.Type.SUCCEED, MetricsKey.METRIC_REQUESTS_SUCCEED); - count(list, MetricsEvent.Type.UNKNOWN_FAILED, MetricsKey.METRIC_REQUESTS_FAILED); - count(list, MetricsEvent.Type.PROCESSING, MetricsKey.METRIC_REQUESTS_PROCESSING); - count(list, MetricsEvent.Type.BUSINESS_FAILED, MetricsKey.METRIC_REQUEST_BUSINESS_FAILED); - count(list, MetricsEvent.Type.REQUEST_TIMEOUT, MetricsKey.METRIC_REQUESTS_TIMEOUT); - count(list, MetricsEvent.Type.REQUEST_LIMIT, MetricsKey.METRIC_REQUESTS_LIMIT); - count(list, MetricsEvent.Type.TOTAL_FAILED, MetricsKey.METRIC_REQUESTS_TOTAL_FAILED); - count(list, MetricsEvent.Type.NETWORK_EXCEPTION, MetricsKey.METRIC_REQUESTS_NETWORK_FAILED); - count(list, MetricsEvent.Type.SERVICE_UNAVAILABLE, MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED); - count(list, MetricsEvent.Type.CODEC_EXCEPTION, MetricsKey.METRIC_REQUESTS_CODEC_FAILED); + collectBySide(list, PROVIDER_SIDE); + collectBySide(list, CONSUMER_SIDE); + } + + private void collectBySide(List list, String side) { + count(list, MetricsEvent.Type.TOTAL.getNameByType(side), MetricsKey.METRIC_REQUESTS); + count(list, MetricsEvent.Type.SUCCEED.getNameByType(side), MetricsKey.METRIC_REQUESTS_SUCCEED); + count(list, MetricsEvent.Type.UNKNOWN_FAILED.getNameByType(side), MetricsKey.METRIC_REQUESTS_FAILED); + count(list, MetricsEvent.Type.PROCESSING.getNameByType(side), MetricsKey.METRIC_REQUESTS_PROCESSING); + count(list, MetricsEvent.Type.BUSINESS_FAILED.getNameByType(side), MetricsKey.METRIC_REQUEST_BUSINESS_FAILED); + count(list, MetricsEvent.Type.REQUEST_TIMEOUT.getNameByType(side), MetricsKey.METRIC_REQUESTS_TIMEOUT); + count(list, MetricsEvent.Type.REQUEST_LIMIT.getNameByType(side), MetricsKey.METRIC_REQUESTS_LIMIT); + count(list, MetricsEvent.Type.TOTAL_FAILED.getNameByType(side), MetricsKey.METRIC_REQUESTS_TOTAL_FAILED); + count(list, MetricsEvent.Type.NETWORK_EXCEPTION.getNameByType(side), MetricsKey.METRIC_REQUESTS_NETWORK_FAILED); + count(list, MetricsEvent.Type.SERVICE_UNAVAILABLE.getNameByType(side), MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED); + count(list, MetricsEvent.Type.CODEC_EXCEPTION.getNameByType(side), MetricsKey.METRIC_REQUESTS_CODEC_FAILED); } @@ -104,7 +112,7 @@ public class MethodMetricsSampler extends SimpleMetricsCountSampler void count(List list, MetricsEvent.Type eventType, MetricsKey metricsKey) { + private void count(List list, String eventType, MetricsKey metricsKey) { getCount(eventType).filter(e -> !e.isEmpty()) .ifPresent(map -> map.forEach((k, v) -> list.add(getGaugeMetricSample(metricsKey, k, REQUESTS, v, AtomicLong::get)))); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java index 2394fbe56a..74fd349f7b 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MethodMetricsInterceptor.java @@ -16,11 +16,17 @@ */ package org.apache.dubbo.metrics.filter; + import org.apache.dubbo.metrics.collector.sample.MethodMetricsSampler; import org.apache.dubbo.metrics.event.MetricsEvent; import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; + +import java.util.Optional; + +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; import static org.apache.dubbo.common.constants.MetricsConstants.METRIC_FILTER_START_TIME; public class MethodMetricsInterceptor { @@ -32,16 +38,23 @@ public class MethodMetricsInterceptor { } public void beforeMethod(Invocation invocation) { - sampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); - sampler.incOnEvent(invocation,MetricsEvent.Type.PROCESSING); + String side = getSide(invocation); + sampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL.getNameByType(side)); + sampler.incOnEvent(invocation, MetricsEvent.Type.PROCESSING.getNameByType(side)); invocation.put(METRIC_FILTER_START_TIME, System.currentTimeMillis()); } + private String getSide(Invocation invocation) { + Optional> invoker = Optional.ofNullable(invocation.getInvoker()); + String side = invoker.isPresent() ? invoker.get().getUrl().getSide() : PROVIDER_SIDE; + return side; + } + public void afterMethod(Invocation invocation, Result result) { if (result.hasException()) { handleMethodException(invocation, result.getException()); - }else{ - sampler.incOnEvent(invocation,MetricsEvent.Type.SUCCEED); + } else { + sampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED.getNameByType(getSide(invocation))); onCompleted(invocation); } } @@ -50,7 +63,7 @@ public class MethodMetricsInterceptor { if (throwable == null) { return; } - + String side = getSide(invocation); if (throwable instanceof RpcException) { RpcException e = (RpcException) throwable; @@ -71,7 +84,7 @@ public class MethodMetricsInterceptor { if (e.isNetwork()) { eventType = MetricsEvent.Type.NETWORK_EXCEPTION; } - sampler.incOnEvent(invocation,eventType); + sampler.incOnEvent(invocation, eventType.getNameByType(side)); } if (throwable instanceof RpcException && ((RpcException) throwable).isBiz()) { @@ -80,7 +93,7 @@ public class MethodMetricsInterceptor { rtTime(invocation); } - sampler.incOnEvent(invocation,MetricsEvent.Type.TOTAL_FAILED); + sampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL_FAILED.getNameByType(side)); } private void rtTime(Invocation invocation){ @@ -92,6 +105,6 @@ public class MethodMetricsInterceptor { private void onCompleted(Invocation invocation) { rtTime(invocation); - sampler.dec(invocation,MetricsEvent.Type.PROCESSING); + sampler.dec(invocation, MetricsEvent.Type.PROCESSING.getNameByType(getSide(invocation))); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java index 114b191fa0..4fa30ee0b2 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsClusterFilter.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.metrics.filter; + import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.event.MetricsEvent; @@ -27,7 +28,11 @@ import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.cluster.filter.ClusterFilter; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ScopeModelAware; + +import java.util.Optional; + import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; @Activate(group = CONSUMER) public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware { @@ -61,8 +66,15 @@ public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener, if (t != null && t instanceof RpcException) { RpcException e = (RpcException) t; if (e.isForbidden()) { - collector.getMethodSampler().incOnEvent(invocation, MetricsEvent.Type.SERVICE_UNAVAILABLE); + collector.getMethodSampler().incOnEvent(invocation, + MetricsEvent.Type.SERVICE_UNAVAILABLE.getNameByType(getSide(invocation))); } } } + + private String getSide(Invocation invocation) { + Optional> invoker = Optional.ofNullable(invocation.getInvoker()); + String side = invoker.isPresent() ? invoker.get().getUrl().getSide() : PROVIDER_SIDE; + return side; + } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java index c4232f0039..6514aa0d9c 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/collector/AggregateMetricsCollectorTest.java @@ -41,8 +41,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.*; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY; @@ -106,13 +105,13 @@ class AggregateMetricsCollectorTest { defaultCollector.setApplicationName(applicationName); MethodMetricsSampler methodMetricsCountSampler = defaultCollector.getMethodSampler(); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.UNKNOWN_FAILED); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.BUSINESS_FAILED); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.NETWORK_EXCEPTION); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SERVICE_UNAVAILABLE); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.CODEC_EXCEPTION); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.UNKNOWN_FAILED.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.BUSINESS_FAILED.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.NETWORK_EXCEPTION.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SERVICE_UNAVAILABLE.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.CODEC_EXCEPTION.getNameByType(side)); List samples = collector.collect(); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java index 0dcf43c04b..a50fd29dc6 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java @@ -50,6 +50,7 @@ import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; + import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE; import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_PARAMETER_DESC; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; @@ -90,7 +91,7 @@ class MetricsFilterTest { filter = new MetricsFilter(); collector = applicationModel.getBeanFactory().getOrRegisterBean(DefaultMetricsCollector.class); - if(!initApplication.get()) { + if (!initApplication.get()) { collector.collectApplication(applicationModel); initApplication.set(true); } @@ -273,18 +274,20 @@ class MetricsFilterTest { } @Test - public void testErrors(){ - testFilterError(RpcException.SERIALIZATION_EXCEPTION, MetricsKey.METRIC_REQUESTS_CODEC_FAILED.formatName(side)); - testFilterError(RpcException.NETWORK_EXCEPTION, MetricsKey.METRIC_REQUESTS_NETWORK_FAILED.formatName(side)); + public void testErrors() { + testFilterError(RpcException.SERIALIZATION_EXCEPTION, + MetricsKey.METRIC_REQUESTS_CODEC_FAILED.getNameByType(side)); + testFilterError(RpcException.NETWORK_EXCEPTION, + MetricsKey.METRIC_REQUESTS_NETWORK_FAILED.getNameByType(side)); } @Test - public void testNoProvider(){ + public void testNoProvider() { testClusterFilterError(RpcException.FORBIDDEN_EXCEPTION, - MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED.formatName(CommonConstants.CONSUMER)); + MetricsKey.METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED.getNameByType(CommonConstants.CONSUMER)); } - private void testClusterFilterError(int errorCode,MetricsKey metricsKey){ + private void testClusterFilterError(int errorCode, String name) { // setup(); collector.setCollectEnabled(true); given(invoker.invoke(invocation)).willThrow(new RpcException(errorCode)); @@ -301,15 +304,15 @@ class MetricsFilterTest { } } Map metricsMap = getMetricsMap(); - Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName())); + Assertions.assertTrue(metricsMap.containsKey(name)); - MetricSample sample = metricsMap.get(metricsKey.getName()); + MetricSample sample = metricsMap.get(name); Assertions.assertSame(((GaugeMetricSample) sample).applyAsLong(), count); teardown(); } - private void testFilterError(int errorCode,MetricsKey metricsKey){ + private void testFilterError(int errorCode, String name) { setup(); collector.setCollectEnabled(true); given(invoker.invoke(invocation)).willThrow(new RpcException(errorCode)); @@ -326,14 +329,14 @@ class MetricsFilterTest { } } Map metricsMap = getMetricsMap(); - Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName())); + Assertions.assertTrue(metricsMap.containsKey(name)); - MetricSample sample = metricsMap.get(metricsKey.getName()); + MetricSample sample = metricsMap.get(name); Assertions.assertSame(((GaugeMetricSample) sample).applyAsLong(), count); - Assertions.assertTrue(metricsMap.containsKey(metricsKey.getName())); + Assertions.assertTrue(metricsMap.containsKey(name)); Map tags = sample.getTags(); Assertions.assertEquals(tags.get(TAG_INTERFACE_KEY), INTERFACE_NAME); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java index 7a1d238b3f..7affb9ae8b 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/metrics/collector/DefaultMetricsCollectorTest.java @@ -23,9 +23,9 @@ import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.metrics.TestMetricsInvoker; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.collector.sample.MethodMetricsSampler; +import org.apache.dubbo.metrics.event.MethodEvent; import org.apache.dubbo.metrics.event.MetricsEvent; import org.apache.dubbo.metrics.event.RTEvent; -import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.metrics.listener.MetricsListener; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.sample.GaugeMetricSample; @@ -44,8 +44,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.*; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY; @@ -101,10 +100,10 @@ class DefaultMetricsCollectorTest { MethodMetricsSampler methodMetricsCountSampler = collector.getMethodSampler(); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.PROCESSING); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.UNKNOWN_FAILED); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.PROCESSING.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.SUCCEED.getNameByType(side)); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.UNKNOWN_FAILED.getNameByType(side)); List samples = collector.collect(); for (MetricSample sample : samples) { @@ -119,7 +118,7 @@ class DefaultMetricsCollectorTest { Assertions.assertEquals(gaugeSample.applyAsLong(), 1); } - methodMetricsCountSampler.dec(invocation, MetricsEvent.Type.PROCESSING); + methodMetricsCountSampler.dec(invocation, MetricsEvent.Type.PROCESSING.getNameByType(side)); samples = collector.collect(); Map sampleMap = samples.stream().collect(Collectors.toMap(MetricSample::getName, k -> ((GaugeMetricSample) k).applyAsLong())); @@ -169,10 +168,11 @@ class DefaultMetricsCollectorTest { collector.addListener(mockListener); collector.setApplicationName(applicationModel.getApplicationName()); - methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL); + methodMetricsCountSampler.incOnEvent(invocation, MetricsEvent.Type.TOTAL.getNameByType(side)); Assertions.assertNotNull(mockListener.getCurEvent()); - Assertions.assertTrue(mockListener.getCurEvent() instanceof RequestEvent); - Assertions.assertEquals(((RequestEvent) mockListener.getCurEvent()).getType(), MetricsEvent.Type.TOTAL); + Assertions.assertTrue(mockListener.getCurEvent() instanceof MethodEvent); + Assertions.assertEquals(((MethodEvent) mockListener.getCurEvent()).getType(), + MetricsEvent.Type.TOTAL.getNameByType(side)); methodMetricsCountSampler.addRT(invocation, 5L); Assertions.assertTrue(mockListener.getCurEvent() instanceof RTEvent); diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java index ff3b6c0714..ed9cbca73b 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/sampler/CountSamplerTest.java @@ -39,6 +39,7 @@ import java.util.stream.Collectors; import static org.apache.dubbo.metrics.model.MetricsCategory.RT; public class CountSamplerTest { + String side = "consumer"; public RequestMetricsCountSampler sampler = new RequestMetricsCountSampler(); @@ -57,59 +58,54 @@ public class CountSamplerTest { Assertions.assertNotNull(collect); - Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( - MetricsKey.METRIC_RT_LAST.getName()).applyAsLong() == 2); - Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( - MetricsKey.METRIC_RT_MIN.getName()).applyAsLong() == 2); - Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( - MetricsKey.METRIC_RT_MAX.getName()).applyAsLong() == 2); - Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( - MetricsKey.METRIC_RT_AVG.getName()).applyAsLong() == 2); - Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( - MetricsKey.METRIC_RT_SUM.getName()).applyAsLong() == 2); + Assertions.assertTrue(null != collect.get(MetricsKey.METRIC_RT_LAST.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_LAST.getNameByType(side)).applyAsLong() == 2); + Assertions.assertTrue(null != collect.get(MetricsKey.METRIC_RT_MIN.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_MIN.getNameByType(side)).applyAsLong() == 2); + Assertions.assertTrue(null != collect.get(MetricsKey.METRIC_RT_MAX.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_MAX.getNameByType(side)).applyAsLong() == 2); + Assertions.assertTrue(null != collect.get(MetricsKey.METRIC_RT_AVG.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_AVG.getNameByType(side)).applyAsLong() == 2); + Assertions.assertTrue(null != collect.get(MetricsKey.METRIC_RT_SUM.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_SUM.getNameByType(side)).applyAsLong() == 2); sampler.addRT(applicationName, RTType.METHOD_REQUEST, 1L); collect = getCollect(RTType.METHOD_REQUEST); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( - MetricsKey.METRIC_RT_LAST.getName()).applyAsLong() == 1); + null != collect.get(MetricsKey.METRIC_RT_LAST.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_LAST.getNameByType(side)).applyAsLong() == 1); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( - MetricsKey.METRIC_RT_MIN.getName()).applyAsLong() == 1); + null != collect.get(MetricsKey.METRIC_RT_MIN.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_MIN.getNameByType(side)).applyAsLong() == 1); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( - MetricsKey.METRIC_RT_MAX.getName()).applyAsLong() == 2); + null != collect.get(MetricsKey.METRIC_RT_MAX.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_MAX.getNameByType(side)).applyAsLong() == 2); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( - MetricsKey.METRIC_RT_AVG.getName()).applyAsLong() == 1); + null != collect.get(MetricsKey.METRIC_RT_AVG.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_AVG.getNameByType(side)).applyAsLong() == 1); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( - MetricsKey.METRIC_RT_SUM.getName()).applyAsLong() == 3); + null != collect.get(MetricsKey.METRIC_RT_SUM.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_SUM.getNameByType(side)).applyAsLong() == 3); sampler.addRT(applicationName, RTType.APPLICATION, 4L); collect = getCollect(RTType.APPLICATION); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_LAST.getName()) && collect.get( - MetricsKey.METRIC_RT_LAST.getName()).applyAsLong() == 4); + null != collect.get(MetricsKey.METRIC_RT_LAST.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_LAST.getNameByType(side)).applyAsLong() == 4); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_MIN.getName()) && collect.get( - MetricsKey.METRIC_RT_MIN.getName()).applyAsLong() == 4); + null != collect.get(MetricsKey.METRIC_RT_MIN.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_MIN.getNameByType(side)).applyAsLong() == 4); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_MAX.getName()) && collect.get( - MetricsKey.METRIC_RT_MAX.getName()).applyAsLong() == 4); + null != collect.get(MetricsKey.METRIC_RT_MAX.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_MAX.getNameByType(side)).applyAsLong() == 4); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_AVG.getName()) && collect.get( - MetricsKey.METRIC_RT_AVG.getName()).applyAsLong() == 4); + null != collect.get(MetricsKey.METRIC_RT_AVG.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_AVG.getNameByType(side)).applyAsLong() == 4); Assertions.assertTrue( - null != collect.get(MetricsKey.METRIC_RT_SUM.getName()) && collect.get( - MetricsKey.METRIC_RT_SUM.getName()).applyAsLong() == 4); + null != collect.get(MetricsKey.METRIC_RT_SUM.getNameByType(side)) && collect.get( + MetricsKey.METRIC_RT_SUM.getNameByType(side)).applyAsLong() == 4); } @SuppressWarnings("rawtypes") @@ -118,7 +114,8 @@ public class CountSamplerTest { new MetricsCountSampler.MetricSampleFactory>() { @Override public GaugeMetricSample newInstance(MetricsKey key, RequestMethodMetrics metric, T value, ToDoubleFunction apply) { - return new GaugeMetricSample<>(key.formatName("consumer"), metric.getTags(), RT, value, apply); + return new GaugeMetricSample<>(key.getNameByType(side), key.getDescription(), + metric.getTags(), RT, value, apply); } }, rtType); From 14f2d79693bd9ee229fe9806ec4675bf9b76b2c0 Mon Sep 17 00:00:00 2001 From: robin977 Date: Fri, 10 Mar 2023 15:21:25 +0800 Subject: [PATCH 091/144] Fixed the issue where core thread metrics were in effect(#11704) (#11752) * Fixed the issue where core thread metrics were in effect * Fixed the issue where core thread metrics were in effect(#11704) * fix: add core thread metrics name (#11704) * fix: remove useless dependencies (#11704) --------- Co-authored-by: robin --- .../manager/DefaultExecutorRepository.java | 1 - .../org/apache/dubbo/config/Constants.java | 2 +- .../deploy/DefaultApplicationDeployer.java | 6 ++++++ .../collector/DefaultMetricsCollector.java | 4 ++++ .../sample/ThreadPoolMetricsSampler.java | 20 +++++++++++++------ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java index fd2c9aacb2..e35617e44c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/manager/DefaultExecutorRepository.java @@ -108,7 +108,6 @@ public class DefaultExecutorRepository implements ExecutorRepository, ExtensionA executor = createExecutor(url); executors.put(executorCacheKey, executor); } - dataStore.put(executorKey, executorCacheKey, executor); return executor; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java b/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java index 4615444bea..cd65fc4119 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java @@ -149,5 +149,5 @@ public interface Constants { String SERVER_THREAD_POOL_NAME = "DubboServerHandler"; - + String CLIENT_THREAD_POOL_NAME = "DubboClientHandler"; } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index f605c6d09e..919265bd5a 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -1088,6 +1088,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer collect() { List list = new ArrayList<>(); diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java index b83e111706..87e3c7d4d2 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java @@ -37,9 +37,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY; import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION; +import static org.apache.dubbo.config.Constants.CLIENT_THREAD_POOL_NAME; +import static org.apache.dubbo.config.Constants.SERVER_THREAD_POOL_NAME; import static org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL; public class ThreadPoolMetricsSampler implements MetricsSampler { @@ -53,7 +56,6 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) { this.collector = collector; - this.registryDefaultSampleThreadPoolExecutor(); } public void addExecutors(String name, ExecutorService executorService) { @@ -87,7 +89,7 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { return list; } - private void registryDefaultSampleThreadPoolExecutor() { + public void registryDefaultSampleThreadPoolExecutor() { ApplicationModel applicationModel = collector.getApplicationModel(); if (applicationModel == null) { return; @@ -103,20 +105,26 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { if (this.dataStore == null) { this.dataStore = collector.getApplicationModel().getExtensionLoader(DataStore.class).getDefaultExtension(); } + if (dataStore != null) { Map executors = dataStore.get(EXECUTOR_SERVICE_COMPONENT_KEY); for (Map.Entry entry : executors.entrySet()) { ExecutorService executor = (ExecutorService) entry.getValue(); if (executor instanceof ThreadPoolExecutor) { - this.addExecutors(entry.getKey(), executor); + this.addExecutors( SERVER_THREAD_POOL_NAME + "-" + entry.getKey(), executor); + } + } + executors = dataStore.get(CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY); + for (Map.Entry entry : executors.entrySet()) { + ExecutorService executor = (ExecutorService) entry.getValue(); + if (executor instanceof ThreadPoolExecutor) { + this.addExecutors(CLIENT_THREAD_POOL_NAME + "-" + entry.getKey(), executor); } } } if (this.frameworkExecutorRepository != null) { this.addExecutors("sharedExecutor", frameworkExecutorRepository.getSharedExecutor()); - this.addExecutors("mappingRefreshingExecutor", frameworkExecutorRepository.getMappingRefreshingExecutor()); - this.addExecutors("poolRouterExecutor", frameworkExecutorRepository.getPoolRouterExecutor()); - } + } } } From d0a1bd014331483c19208b831c4f6b488654a508 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 10 Mar 2023 16:25:56 +0800 Subject: [PATCH 092/144] Fix recreate client after destroy (#11780) * Fix recreate client after destroy * Fix uts --- .../dubbo/config/ReferenceConfigTest.java | 10 ++- .../rpc/protocol/InvokerCountWrapper.java | 57 ++++++++++++ .../ReferenceCountInvokerWrapper.java | 87 +++++++++++++++++++ .../internal/org.apache.dubbo.rpc.Protocol | 1 + 4 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/InvokerCountWrapper.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ReferenceCountInvokerWrapper.java diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java index e2c781ec22..815b6800e0 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java @@ -42,6 +42,7 @@ 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.ServiceMetadata; +import org.apache.dubbo.rpc.protocol.ReferenceCountInvokerWrapper; import org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker; import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol; import org.apache.dubbo.rpc.service.GenericService; @@ -479,10 +480,11 @@ class ReferenceConfigTest { referenceConfig.init(); Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker); - Invoker withFilter = ((MockClusterInvoker) referenceConfig.getInvoker()).getDirectory().getAllInvokers().get(0); - Assertions.assertTrue(withFilter instanceof ListenerInvokerWrapper); - Assertions.assertTrue(((ListenerInvokerWrapper) withFilter).getInvoker() instanceof InjvmInvoker); - URL url = withFilter.getUrl(); + Invoker withCount = ((MockClusterInvoker) referenceConfig.getInvoker()).getDirectory().getAllInvokers().get(0); + Assertions.assertTrue(withCount instanceof ReferenceCountInvokerWrapper); + Assertions.assertTrue(((ReferenceCountInvokerWrapper) withCount).getInvoker() instanceof ListenerInvokerWrapper); + Assertions.assertTrue(((ListenerInvokerWrapper)(((ReferenceCountInvokerWrapper) withCount).getInvoker())).getInvoker() instanceof InjvmInvoker); + URL url = withCount.getUrl(); Assertions.assertEquals("application1", url.getParameter("application")); Assertions.assertEquals("value1", url.getParameter("key1")); Assertions.assertEquals("value2", url.getParameter("key2")); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/InvokerCountWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/InvokerCountWrapper.java new file mode 100644 index 0000000000..985ece8f51 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/InvokerCountWrapper.java @@ -0,0 +1,57 @@ +/* + * 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.protocol; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.utils.UrlUtils; +import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Protocol; +import org.apache.dubbo.rpc.RpcException; + +@Activate(order = Integer.MIN_VALUE + 1000) +public class InvokerCountWrapper implements Protocol { + private final Protocol protocol; + + public InvokerCountWrapper(Protocol protocol) { + this.protocol = protocol; + } + + @Override + public int getDefaultPort() { + return protocol.getDefaultPort(); + } + + @Override + public Exporter export(Invoker invoker) throws RpcException { + return protocol.export(invoker); + } + + @Override + public Invoker refer(Class type, URL url) throws RpcException { + if (UrlUtils.isRegistry(url)) { + return protocol.refer(type, url); + } + return new ReferenceCountInvokerWrapper<>(protocol.refer(type, url)); + } + + @Override + public void destroy() { + protocol.destroy(); + } +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ReferenceCountInvokerWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ReferenceCountInvokerWrapper.java new file mode 100644 index 0000000000..1326cf16a4 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ReferenceCountInvokerWrapper.java @@ -0,0 +1,87 @@ +/* + * 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.protocol; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.LoggerCodeConstants; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcException; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class ReferenceCountInvokerWrapper implements Invoker { + private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ReferenceCountInvokerWrapper.class); + private final Invoker invoker; + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private final AtomicBoolean destroyed = new AtomicBoolean(false); + + public ReferenceCountInvokerWrapper(Invoker invoker) { + this.invoker = invoker; + } + + @Override + public URL getUrl() { + return invoker.getUrl(); + } + + @Override + public boolean isAvailable() { + return !destroyed.get() && invoker.isAvailable(); + } + + @Override + public void destroy() { + try { + lock.writeLock().lock(); + destroyed.set(true); + } finally { + lock.writeLock().unlock(); + } + invoker.destroy(); + } + + @Override + public Class getInterface() { + return invoker.getInterface(); + } + + @Override + public Result invoke(Invocation invocation) throws RpcException { + try { + lock.readLock().lock(); + if (destroyed.get()) { + logger.warn(LoggerCodeConstants.PROTOCOL_CLOSED_SERVER, "", "", + "Remote invoker has been destroyed, and unable to invoke anymore."); + throw new RpcException("This invoker has been destroyed!"); + } + return invoker.invoke(invocation); + } finally { + lock.readLock().unlock(); + } + } + + public Invoker getInvoker() { + return invoker; + } +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol b/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol index eff2b090d6..ce1e6d393a 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol +++ b/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol @@ -2,3 +2,4 @@ listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper mock=org.apache.dubbo.rpc.support.MockProtocol serializationwrapper=org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper securitywrapper=org.apache.dubbo.rpc.protocol.ProtocolSecurityWrapper +invokercount=org.apache.dubbo.rpc.protocol.InvokerCountWrapper From ba14a201e71dbf0267d411943db30f69840d51b5 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 10 Mar 2023 17:11:17 +0800 Subject: [PATCH 093/144] Sync when destroy (#11783) --- .../apache/dubbo/rpc/model/ScopeModel.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java index b83f96f46f..e066952528 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java @@ -110,21 +110,23 @@ public abstract class ScopeModel implements ExtensionAccessor { } public void destroy() { - if (destroyed.compareAndSet(false, true)) { - try { - onDestroy(); - HashSet copyOfClassLoaders = new HashSet<>(classLoaders); - for (ClassLoader classLoader : copyOfClassLoaders) { - removeClassLoader(classLoader); + synchronized (instLock) { + if (destroyed.compareAndSet(false, true)) { + try { + onDestroy(); + HashSet copyOfClassLoaders = new HashSet<>(classLoaders); + for (ClassLoader classLoader : copyOfClassLoaders) { + removeClassLoader(classLoader); + } + if (beanFactory != null) { + beanFactory.destroy(); + } + if (extensionDirector != null) { + extensionDirector.destroy(); + } + } catch (Throwable t) { + LOGGER.error(CONFIG_UNABLE_DESTROY_MODEL, "", "", "Error happened when destroying ScopeModel.", t); } - if (beanFactory != null) { - beanFactory.destroy(); - } - if (extensionDirector != null) { - extensionDirector.destroy(); - } - } catch (Throwable t) { - LOGGER.error(CONFIG_UNABLE_DESTROY_MODEL, "", "", "Error happened when destroying ScopeModel.", t); } } } From a8a8eda38f3a279a2661cb15b3285735ce5339d9 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 10 Mar 2023 17:13:51 +0800 Subject: [PATCH 094/144] Fix uts --- .../java/org/apache/dubbo/config/ReferenceConfigTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java index 5e9f49c822..04e759e534 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java @@ -483,7 +483,9 @@ class ReferenceConfigTest { Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker); Invoker withCount = ((MockClusterInvoker) referenceConfig.getInvoker()).getDirectory().getAllInvokers().get(0); Assertions.assertTrue(withCount instanceof ReferenceCountInvokerWrapper); - Assertions.assertTrue(((ReferenceCountInvokerWrapper) withCount).getInvoker() instanceof ListenerInvokerWrapper + Assertions.assertTrue(((ReferenceCountInvokerWrapper) withCount).getInvoker() instanceof ListenerInvokerWrapper); + Invoker withFilter = ((ReferenceCountInvokerWrapper) withCount).getInvoker(); + Assertions.assertTrue(withFilter instanceof ListenerInvokerWrapper || withFilter instanceof FilterChainBuilder.CallbackRegistrationInvoker); if (withFilter instanceof ListenerInvokerWrapper) { Assertions.assertTrue(((ListenerInvokerWrapper)(((ReferenceCountInvokerWrapper) withCount).getInvoker())).getInvoker() instanceof InjvmInvoker); From ae28d17897259c7acc87c4c1ca79293d3d06e983 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 10 Mar 2023 17:15:41 +0800 Subject: [PATCH 095/144] Prepare 3.1.8 release --- dubbo-dependencies-bom/pom.xml | 2 +- .../dubbo-dependencies-zookeeper-curator5/pom.xml | 2 +- dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index a20edf2fed..e8b55603cf 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -182,7 +182,7 @@ 2.0 1.1.0 1.21 - 3.1.8-SNAPSHOT + 3.1.8 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml index b31835d2d0..c83716cd7d 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.8-SNAPSHOT + 3.1.8 1.1.0 5.1.0 3.7.0 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml index 964b000b5c..b617d591f6 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.8-SNAPSHOT + 3.1.8 1.1.0 4.2.0 3.4.14 diff --git a/pom.xml b/pom.xml index aafb747c2d..3b6dae0cc0 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ true true true - 3.1.8-SNAPSHOT + 3.1.8 From 34cc45fb7a2f81f1ecd6756d2a358c4c6d58d4b2 Mon Sep 17 00:00:00 2001 From: ChaoChao <34986990+chaoyoung@users.noreply.github.com> Date: Sat, 11 Mar 2023 09:12:42 +0800 Subject: [PATCH 096/144] Fix bug #11767 (#11781) --- .../java/org/apache/dubbo/common/URLStrParser.java | 4 ++-- .../java/org/apache/dubbo/common/URLStrParserTest.java | 3 ++- .../src/test/java/org/apache/dubbo/common/URLTest.java | 10 +++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URLStrParser.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URLStrParser.java index 61b37db84b..d4b5143f7c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/URLStrParser.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URLStrParser.java @@ -278,7 +278,7 @@ public final class URLStrParser { String name = decodeComponent(str, nameStart, valueStart - 3, false, tempBuf); String value; if (valueStart >= valueEnd) { - value = name; + value = ""; } else { value = decodeComponent(str, valueStart, valueEnd, false, tempBuf); } @@ -291,7 +291,7 @@ public final class URLStrParser { String name = str.substring(nameStart, valueStart - 1); String value; if (valueStart >= valueEnd) { - value = name; + value = ""; } else { value = str.substring(valueStart, valueEnd); } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/URLStrParserTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/URLStrParserTest.java index aea2001306..6fccf104b0 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/URLStrParserTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/URLStrParserTest.java @@ -44,6 +44,7 @@ class URLStrParserTest { testCases.add("file:/path/to/file.txt"); testCases.add("dubbo://fe80:0:0:0:894:aeec:f37d:23e1%en0/path?abc=abc"); testCases.add("dubbo://[fe80:0:0:0:894:aeec:f37d:23e1]:20880/path?abc=abc"); + testCases.add("nacos://192.168.1.1:8848?username=&password="); errorDecodedCases.add("dubbo:192.168.1.1"); errorDecodedCases.add("://192.168.1.1"); @@ -80,4 +81,4 @@ class URLStrParserTest { }); } -} \ No newline at end of file +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java index a4400eebef..334ec39684 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java @@ -308,7 +308,7 @@ class URLTest { assertEquals(3, url.getParameters().size()); assertEquals("1.0.0", url.getVersion()); assertEquals("morgan", url.getParameter("application")); - assertEquals("noValue", url.getParameter("noValue")); + assertEquals("", url.getParameter("noValue")); } // TODO Do not want to use spaces? See: DUBBO-502, URL class handles special conventions for special characters. @@ -325,10 +325,10 @@ class URLTest { URL url = URL.valueOf("http://1.2.3.4:8080/path?k0=&k1=v1"); assertURLStrDecoder(url); - assertTrue(url.hasParameter("k0")); + assertFalse(url.hasParameter("k0")); - // If a Key has no corresponding Value, then the Key also used as the Value. - assertEquals("k0", url.getParameter("k0")); + // If a Key has no corresponding Value, then empty string used as the Value. + assertEquals("", url.getParameter("k0")); } @Test @@ -1047,7 +1047,7 @@ class URLTest { @Test void test_valueOfHasNameWithoutValue() throws Exception { URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&noValue"); - Assertions.assertEquals("noValue", url.getParameter("noValue")); + Assertions.assertEquals("", url.getParameter("noValue")); } @Test From 3fafcc47b1121554f92120577564794ec0ab4ae4 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sat, 11 Mar 2023 09:24:08 +0800 Subject: [PATCH 097/144] Prepare 3.2.0-beta.6 release --- dubbo-dependencies-bom/pom.xml | 4 ++-- .../dubbo-dependencies-zookeeper-curator5/pom.xml | 2 +- dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 7007a23b0e..a6c4cd79cc 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -135,7 +135,7 @@ 1.8.0 0.1.35 1.10.4 - + 1.0.2 3.3 0.16.0 @@ -190,7 +190,7 @@ 2.0 1.1.0 1.22 - 3.2.0-beta.6-SNAPSHOT + 3.2.0-beta.6 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml index 79b2b9a936..34d35c4595 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml @@ -32,7 +32,7 @@ pom - 3.2.0-beta.6-SNAPSHOT + 3.2.0-beta.6 1.1.0 5.1.0 3.7.0 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml index 203b2f9618..49a77fd063 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml @@ -32,7 +32,7 @@ pom - 3.2.0-beta.6-SNAPSHOT + 3.2.0-beta.6 1.1.0 4.3.0 3.4.14 diff --git a/pom.xml b/pom.xml index 60f7de473b..24d51eec63 100644 --- a/pom.xml +++ b/pom.xml @@ -130,7 +130,7 @@ true true true - 3.2.0-beta.6-SNAPSHOT + 3.2.0-beta.6 From ea7af7a29410e3eb2e0f49282fea1a68d7fb2ce8 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sat, 11 Mar 2023 11:16:19 +0800 Subject: [PATCH 098/144] Fix ut --- .../test/java/org/apache/dubbo/config/ReferenceConfigTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java index 04e759e534..745110dcdc 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java @@ -483,7 +483,6 @@ class ReferenceConfigTest { Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker); Invoker withCount = ((MockClusterInvoker) referenceConfig.getInvoker()).getDirectory().getAllInvokers().get(0); Assertions.assertTrue(withCount instanceof ReferenceCountInvokerWrapper); - Assertions.assertTrue(((ReferenceCountInvokerWrapper) withCount).getInvoker() instanceof ListenerInvokerWrapper); Invoker withFilter = ((ReferenceCountInvokerWrapper) withCount).getInvoker(); Assertions.assertTrue(withFilter instanceof ListenerInvokerWrapper || withFilter instanceof FilterChainBuilder.CallbackRegistrationInvoker); From 87eb3fdda812c6551ea0c77e89b0ef6809cde0b7 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sat, 11 Mar 2023 16:05:41 +0800 Subject: [PATCH 099/144] Fix metrics publisher NPE --- .../cluster/directory/AbstractDirectory.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java index 6af8bdb98d..9d3dc1e827 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java @@ -28,6 +28,7 @@ import org.apache.dubbo.common.utils.ConcurrentHashSet; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.event.MetricsEvent; import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -387,9 +388,15 @@ public abstract class AbstractDirectory implements Directory { invokersToRemove.removeAll(needToRemove); } + private void publishMetricsEvent(MetricsEvent event) { + if (eventMulticaster != null) { + eventMulticaster.publishEvent(event); + } + } + @Override public void addDisabledInvoker(Invoker invoker) { - eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_DISABLE)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_DISABLE)); if (invokers.contains(invoker)) { disabledInvokers.add(invoker); removeValidInvoker(invoker); @@ -399,7 +406,7 @@ public abstract class AbstractDirectory implements Directory { @Override public void recoverDisabledInvoker(Invoker invoker) { - eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_RECOVER_DISABLE)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_RECOVER_DISABLE)); if (disabledInvokers.remove(invoker)) { try { addValidInvoker(invoker); @@ -463,7 +470,7 @@ public abstract class AbstractDirectory implements Directory { this.invokers = invokers; refreshInvokerInternal(); this.invokersInitialized = true; - eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_CURRENT, invokers.size())); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_CURRENT, invokers.size())); } protected void destroyInvokers() { @@ -474,14 +481,14 @@ public abstract class AbstractDirectory implements Directory { } private boolean addValidInvoker(Invoker invoker) { - eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_VALID)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_VALID)); synchronized (this.validInvokers) { return this.validInvokers.add(invoker); } } private boolean removeValidInvoker(Invoker invoker) { - eventMulticaster.publishEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_UN_VALID)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_UN_VALID)); synchronized (this.validInvokers) { return this.validInvokers.remove(invoker); } From 100a442a1f09c5a6095ca2990296b742724b10a5 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sat, 11 Mar 2023 19:19:14 +0800 Subject: [PATCH 100/144] Fix hessian list --- dubbo-common/src/main/resources/security/serialize.allowlist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-common/src/main/resources/security/serialize.allowlist b/dubbo-common/src/main/resources/security/serialize.allowlist index aa56eab53f..f2eef79665 100644 --- a/dubbo-common/src/main/resources/security/serialize.allowlist +++ b/dubbo-common/src/main/resources/security/serialize.allowlist @@ -124,4 +124,4 @@ java.util.UUID java.util.WeakHashMap org.apache.dubbo com.alibaba.dubbo -com.alibaba.com.caucho.hessian.io.java8 +com.alibaba.com.caucho.hessian.io From 234f1c64abb34cfc49bf233cbf37a4f6e2953857 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sun, 12 Mar 2023 10:26:18 +0800 Subject: [PATCH 101/144] Fix lock acquire blocked --- .../org/apache/dubbo/rpc/model/ApplicationModel.java | 6 ++++++ .../org/apache/dubbo/rpc/model/FrameworkModel.java | 12 +++++++++++- .../java/org/apache/dubbo/rpc/model/ModuleModel.java | 6 ++++++ .../java/org/apache/dubbo/rpc/model/ScopeModel.java | 9 ++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java index 31c11f6aca..50b94b956e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java @@ -36,6 +36,7 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Lock; /** * {@link ExtensionLoader}, {@code DubboBootstrap} and this class are at present designed to be @@ -345,6 +346,11 @@ public class ApplicationModel extends ScopeModel { this.deployer = deployer; } + @Override + protected Lock acquireDestroyLock() { + return frameworkModel.acquireDestroyLock(); + } + // =============================== Deprecated Methods Start ======================================= /** diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java index 8c2787eadc..2bdfa9f577 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java @@ -33,6 +33,8 @@ import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; /** @@ -48,7 +50,7 @@ public class FrameworkModel extends ScopeModel { private static final AtomicLong index = new AtomicLong(1); private static final Object globalLock = new Object(); - + private volatile static FrameworkModel defaultInstance; private static final List allInstances = new CopyOnWriteArrayList<>(); @@ -68,6 +70,8 @@ public class FrameworkModel extends ScopeModel { private final ApplicationModel internalApplicationModel; + private final ReentrantLock destroyLock = new ReentrantLock(); + /** * Use {@link FrameworkModel#newModel()} to create a new model */ @@ -356,6 +360,12 @@ public class FrameworkModel extends ScopeModel { return serviceRepository; } + + @Override + protected Lock acquireDestroyLock() { + return destroyLock; + } + @Override public Environment getModelEnvironment() { throw new UnsupportedOperationException("Environment is inaccessible for FrameworkModel"); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java index c06e3d075d..2178d0b3a9 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java @@ -32,6 +32,7 @@ import org.apache.dubbo.config.context.ModuleConfigManager; import java.util.HashMap; import java.util.Set; +import java.util.concurrent.locks.Lock; /** * Model of a service module @@ -172,6 +173,11 @@ public class ModuleModel extends ScopeModel { this.deployer = deployer; } + @Override + protected Lock acquireDestroyLock() { + return getApplicationModel().getFrameworkModel().acquireDestroyLock(); + } + /** * for ut only */ diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java index e066952528..bbf1bcc987 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java @@ -34,6 +34,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_UNABLE_DESTROY_MODEL; @@ -109,8 +110,12 @@ public abstract class ScopeModel implements ExtensionAccessor { } } + protected abstract Lock acquireDestroyLock(); + public void destroy() { - synchronized (instLock) { + Lock lock = acquireDestroyLock(); + try { + lock.lock(); if (destroyed.compareAndSet(false, true)) { try { onDestroy(); @@ -128,6 +133,8 @@ public abstract class ScopeModel implements ExtensionAccessor { LOGGER.error(CONFIG_UNABLE_DESTROY_MODEL, "", "", "Error happened when destroying ScopeModel.", t); } } + } finally { + lock.unlock(); } } From ffb2bbbffc832997ee9a23f787bfb2b18acabca6 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Sun, 12 Mar 2023 11:11:15 +0800 Subject: [PATCH 102/144] Fix uts --- .../org/apache/dubbo/rpc/model/ScopeModelUtilTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelUtilTest.java b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelUtilTest.java index 147fad70d0..dcf0cfba79 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelUtilTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelUtilTest.java @@ -25,6 +25,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.concurrent.locks.Lock; + /** * {@link ScopeModelUtil} */ @@ -109,6 +111,11 @@ class ScopeModelUtilTest { public Environment getModelEnvironment() { return null; } + + @Override + protected Lock acquireDestroyLock() { + return null; + } } } From 5d50209404cc15f5b4a37258c80327eecd713310 Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:44:13 +0800 Subject: [PATCH 103/144] Cert npe bug fix (#11800) * fix npe * fix npe --------- Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../apache/dubbo/security/cert/CertDeployerListener.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java index 8dcf3e7318..8edd581d11 100644 --- a/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java +++ b/dubbo-plugin/dubbo-security/src/main/java/org/apache/dubbo/security/cert/CertDeployerListener.java @@ -49,7 +49,9 @@ public class CertDeployerListener implements ApplicationDeployListener { @Override public void onStopping(ApplicationModel scopeModel) { - dubboCertManager.disConnect(); + if (dubboCertManager != null) { + dubboCertManager.disConnect(); + } } @Override @@ -59,6 +61,8 @@ public class CertDeployerListener implements ApplicationDeployListener { @Override public void onFailure(ApplicationModel scopeModel, Throwable cause) { - dubboCertManager.disConnect(); + if (dubboCertManager != null) { + dubboCertManager.disConnect(); + } } } From 338c32804e83052634045637cf51ff95fa54a89e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:02:52 +0800 Subject: [PATCH 104/144] Bump byte-buddy from 1.14.0 to 1.14.1 (#11804) Bumps [byte-buddy](https://github.com/raphw/byte-buddy) from 1.14.0 to 1.14.1. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.0...byte-buddy-1.14.1) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 7007a23b0e..02c5ee51eb 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -94,7 +94,7 @@ 5.3.25 5.8.1 3.29.2-GA - 1.14.0 + 1.14.1 3.2.10.Final 4.1.87.Final 2.2.1 From d2d4f1e6cbfef76ee9472a0acbaae89c3fe79132 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:03:42 +0800 Subject: [PATCH 105/144] Bump spring-security-bom from 5.8.1 to 5.8.2 (#11801) Bumps [spring-security-bom](https://github.com/spring-projects/spring-security) from 5.8.1 to 5.8.2. - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/5.8.1...5.8.2) --- updated-dependencies: - dependency-name: org.springframework.security:spring-security-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 02c5ee51eb..7def2661c5 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -92,7 +92,7 @@ 5.3.25 - 5.8.1 + 5.8.2 3.29.2-GA 1.14.1 3.2.10.Final From b4f8c18a1d0d383453e34629a0d7683dfd4ec5fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:03:57 +0800 Subject: [PATCH 106/144] Bump protobuf-java from 3.22.0 to 3.22.2 (#11802) Bumps [protobuf-java](https://github.com/protocolbuffers/protobuf) from 3.22.0 to 3.22.2. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.22.0...v3.22.2) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-demo/dubbo-demo-triple/pom.xml | 2 +- dubbo-rpc/dubbo-rpc-triple/pom.xml | 2 +- dubbo-xds/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dubbo-demo/dubbo-demo-triple/pom.xml b/dubbo-demo/dubbo-demo-triple/pom.xml index a7e0015e71..3f19af44ae 100644 --- a/dubbo-demo/dubbo-demo-triple/pom.xml +++ b/dubbo-demo/dubbo-demo-triple/pom.xml @@ -34,7 +34,7 @@ true 1.8 1.8 - 3.22.0 + 3.22.2 3.11.0 diff --git a/dubbo-rpc/dubbo-rpc-triple/pom.xml b/dubbo-rpc/dubbo-rpc-triple/pom.xml index 4862700ff3..42916180ec 100644 --- a/dubbo-rpc/dubbo-rpc-triple/pom.xml +++ b/dubbo-rpc/dubbo-rpc-triple/pom.xml @@ -32,7 +32,7 @@ 0.0.4.1-SNAPSHOT 1.0.4 3.5.3 - 3.22.0 + 3.22.2 diff --git a/dubbo-xds/pom.xml b/dubbo-xds/pom.xml index 679e555b87..d56a6c0897 100644 --- a/dubbo-xds/pom.xml +++ b/dubbo-xds/pom.xml @@ -31,7 +31,7 @@ The xDS Integration false - 3.22.0 + 3.22.2 1.53.0 From 9c644f180988016ec30db74ed3f869f221f46689 Mon Sep 17 00:00:00 2001 From: songxiaosheng Date: Mon, 13 Mar 2023 17:04:39 +0800 Subject: [PATCH 107/144] =?UTF-8?q?=F0=9F=90=9B=20fix=20thread=20pool=20me?= =?UTF-8?q?trics=20be=20gc=20recycle=20problem=20(#11793)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :bug: fix push metadata code location * :bug: fix thread pool metrics be gc recycle problem --- .../sample/ThreadPoolMetricsSampler.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java index 87e3c7d4d2..adc4118d4f 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadPoolMetricsSampler.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.store.DataStore; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; +import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.metrics.model.MetricsKey; import org.apache.dubbo.metrics.model.ThreadPoolMetric; @@ -53,7 +54,7 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { private FrameworkExecutorRepository frameworkExecutorRepository; private DataStore dataStore; private final Map sampleThreadPoolExecutor = new ConcurrentHashMap<>(); - + private final ConcurrentHashMap threadPoolMetricMap = new ConcurrentHashMap<>(); public ThreadPoolMetricsSampler(DefaultMetricsCollector collector) { this.collector = collector; } @@ -77,14 +78,14 @@ public class ThreadPoolMetricsSampler implements MetricsSampler { private List createMetricsSample(String name, ThreadPoolExecutor executor) { List list = new ArrayList<>(); - ThreadPoolMetric poolMetrics = new ThreadPoolMetric(collector.getApplicationName(), name, executor); - - list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_CORE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getCorePoolSize)); - list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_LARGEST_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getLargestPoolSize)); - list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_MAX_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getMaximumPoolSize)); - list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_ACTIVE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getActiveCount)); - list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_THREAD_COUNT, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getPoolSize)); - list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_QUEUE_SIZE, poolMetrics.getTags(), THREAD_POOL, poolMetrics, ThreadPoolMetric::getQueueSize)); + ThreadPoolMetric threadPoolMetric = ConcurrentHashMapUtils.computeIfAbsent(threadPoolMetricMap, name, + v -> new ThreadPoolMetric(collector.getApplicationName(), name, executor)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_CORE_SIZE, threadPoolMetric.getTags(), THREAD_POOL, threadPoolMetric, ThreadPoolMetric::getCorePoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_LARGEST_SIZE, threadPoolMetric.getTags(), THREAD_POOL, threadPoolMetric, ThreadPoolMetric::getLargestPoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_MAX_SIZE, threadPoolMetric.getTags(), THREAD_POOL, threadPoolMetric, ThreadPoolMetric::getMaximumPoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_ACTIVE_SIZE, threadPoolMetric.getTags(), THREAD_POOL, threadPoolMetric, ThreadPoolMetric::getActiveCount)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_THREAD_COUNT, threadPoolMetric.getTags(), THREAD_POOL, threadPoolMetric, ThreadPoolMetric::getPoolSize)); + list.add(new GaugeMetricSample<>(MetricsKey.THREAD_POOL_QUEUE_SIZE, threadPoolMetric.getTags(), THREAD_POOL, threadPoolMetric, ThreadPoolMetric::getQueueSize)); return list; } From 9ea60943493a79e8e4ddf38e0decfd232d7c8d8a Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:05:57 +0800 Subject: [PATCH 108/144] Reuse qos port for metrics (#11719) * init * init * reuse qos port for metrics * reuse qos port for metrics * fix * fix * add logResult * allow all&&use exist * remove unuse * fix testcase * fix testcase * public permission level * revert permission level * fix --------- Co-authored-by: x-shadow-man <1494445739@qq.com> Co-authored-by: Albumen Kevin --- .../deploy/DefaultApplicationDeployer.java | 1 + .../dubbo/metrics/report/MetricsReporter.java | 4 + .../report/nop/NopMetricsReporter.java | 10 ++ .../dubbo-metrics-prometheus/pom.xml | 6 + .../prometheus/PrometheusMetricsReporter.java | 64 +------- .../PrometheusMetricsReporterCmd.java | 142 ++++++++++++++++++ .../org.apache.dubbo.qos.command.BaseCommand | 1 + .../PrometheusMetricsReporterTest.java | 32 +++- .../apache/dubbo/qos/command/BaseCommand.java | 7 +- .../qos/command/DefaultCommandExecutor.java | 17 ++- .../command/decoder/HttpCommandDecoder.java | 17 ++- 11 files changed, 227 insertions(+), 74 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java create mode 100644 dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index 919265bd5a..3e4221737a 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -373,6 +373,7 @@ public class DefaultApplicationDeployer extends AbstractDeployerhttpclient test + + org.apache.dubbo + dubbo-qos + ${project.parent.version} + compile + diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java index 8227d4d4f1..ac484ab2a8 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporter.java @@ -17,7 +17,6 @@ package org.apache.dubbo.metrics.prometheus; -import com.sun.net.httpserver.HttpServer; import io.micrometer.prometheus.PrometheusConfig; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.prometheus.client.exporter.BasicAuthHttpConnectionFactory; @@ -31,26 +30,19 @@ import org.apache.dubbo.metrics.report.AbstractMetricsReporter; import org.apache.dubbo.rpc.model.ApplicationModel; import java.io.IOException; -import java.io.OutputStream; -import java.net.InetSocketAddress; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_EXPORTER_ENABLED_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_EXPORTER_METRICS_PORT_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_DEFAULT_METRICS_PORT; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_EXPORTER_METRICS_PATH_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_DEFAULT_METRICS_PATH; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_ENABLED_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_BASE_URL_KEY; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_JOB_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_DEFAULT_JOB_NAME; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_PUSH_INTERVAL_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_DEFAULT_PUSH_INTERVAL; -import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_USERNAME_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_BASE_URL_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_ENABLED_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_JOB_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_PASSWORD_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_PUSH_INTERVAL_KEY; +import static org.apache.dubbo.common.constants.MetricsConstants.PROMETHEUS_PUSHGATEWAY_USERNAME_KEY; /** * Metrics reporter for prometheus. @@ -61,8 +53,6 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter { private final PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); private ScheduledExecutorService pushJobExecutor = null; - private HttpServer prometheusExporterHttpServer = null; - private Thread httpServerThread = null; public PrometheusMetricsReporter(URL url, ApplicationModel applicationModel) { super(url, applicationModel); @@ -71,44 +61,11 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter { @Override public void doInit() { addMeterRegistry(prometheusRegistry); - exportHttpServer(); schedulePushJob(); } - private void exportHttpServer() { - boolean exporterEnabled = url.getParameter(PROMETHEUS_EXPORTER_ENABLED_KEY, false); - if (exporterEnabled) { - int port = url.getParameter(PROMETHEUS_EXPORTER_METRICS_PORT_KEY, PROMETHEUS_DEFAULT_METRICS_PORT); - String path = url.getParameter(PROMETHEUS_EXPORTER_METRICS_PATH_KEY, PROMETHEUS_DEFAULT_METRICS_PATH); - if (!path.startsWith("/")) { - path = "/" + path; - } - - try { - - prometheusExporterHttpServer = HttpServer.create(new InetSocketAddress(port), 0); - prometheusExporterHttpServer.createContext(path, httpExchange -> { - long begin = System.currentTimeMillis(); - if (logger.isDebugEnabled()) { - logger.debug("scrape begin"); - } - refreshData(); - String response = prometheusRegistry.scrape(); - httpExchange.sendResponseHeaders(200, response.getBytes().length); - try (OutputStream os = httpExchange.getResponseBody()) { - os.write(response.getBytes()); - } - if (logger.isDebugEnabled()) { - logger.debug(String.format("scrape end,Elapsed Time:%s",System.currentTimeMillis() - begin)); - } - }); - - httpServerThread = new Thread(prometheusExporterHttpServer::start); - httpServerThread.start(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + public String getResponse() { + return prometheusRegistry.scrape(); } private void schedulePushJob() { @@ -142,13 +99,6 @@ public class PrometheusMetricsReporter extends AbstractMetricsReporter { @Override public void doDestroy() { - if (prometheusExporterHttpServer != null) { - prometheusExporterHttpServer.stop(1); - } - - if (httpServerThread != null) { - httpServerThread.interrupt(); - } if (pushJobExecutor != null) { pushJobExecutor.shutdownNow(); diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java new file mode 100644 index 0000000000..0f8536d8b0 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.metrics.prometheus; + +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.JsonUtils; +import org.apache.dubbo.metrics.report.MetricsReporter; +import org.apache.dubbo.qos.command.BaseCommand; +import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import java.io.CharArrayReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@Cmd(name = "metrics", summary = "reuse qos report") +public class PrometheusMetricsReporterCmd implements BaseCommand { + + private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(PrometheusMetricsReporterCmd.class); + + public FrameworkModel frameworkModel; + + public PrometheusMetricsReporterCmd(FrameworkModel frameworkModel) { + this.frameworkModel = frameworkModel; + } + + @Override + public String execute(CommandContext commandContext, String[] args) { + + List models = frameworkModel.getApplicationModels(); + String result = "There is no application with data"; + + if (notSpecifyApplication(args)) { + result = useFirst(models, result); + } else { + result = specifyApplication(args[0], models); + } + return result; + } + + private boolean notSpecifyApplication(String[] args) { + return args == null || args.length == 0; + } + + private String useFirst(List models, String result) { + for (ApplicationModel model : models) { + String current = getResponseByApplication(model); + // Contains at least one line "text/plain; version=0.0.4; charset=utf-8" + if (getLineNumber(current) > 1) { + result = current; + break; + } + } + return result; + } + + private String specifyApplication(String appName, List models) { + if ("application_all".equals(appName)) { + return allApplication(models); + } else { + return specifySingleApplication(appName, models); + } + } + + private String specifySingleApplication(String appName, List models) { + Optional modelOptional = models.stream().filter(applicationModel -> appName.equals(applicationModel.getApplicationName())).findFirst(); + if (modelOptional.isPresent()) { + return getResponseByApplication(modelOptional.get()); + } else { + return "Not exist application: " + appName; + } + } + + private String allApplication(List models) { + Map appResultMap = new HashMap<>(); + for (ApplicationModel model : models) { + appResultMap.put(model.getApplicationName(), getResponseByApplication(model)); + } + return JsonUtils.getJson().toJson(appResultMap); + } + + @Override + public boolean logResult() { + return false; + } + + private String getResponseByApplication(ApplicationModel applicationModel) { + + String response = "MetricsReporter not init"; + MetricsReporter metricsReporter = applicationModel.getBeanFactory().getBean(MetricsReporter.class); + if (metricsReporter != null) { + long begin = System.currentTimeMillis(); + if (logger.isDebugEnabled()) { + logger.debug("scrape begin"); + } + + metricsReporter.refreshData(); + + if (logger.isDebugEnabled()) { + logger.debug(String.format("scrape end,Elapsed Time:%s", System.currentTimeMillis() - begin)); + } + response = metricsReporter.getResponse(); + + } + return response; + } + + + private static long getLineNumber(String content) { + + LineNumberReader lnr = new LineNumberReader(new CharArrayReader(content.toCharArray())); + try { + lnr.skip(Long.MAX_VALUE); + lnr.close(); + } catch (IOException ignore) { + } + return lnr.getLineNumber(); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand b/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand new file mode 100644 index 0000000000..131623f6d4 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand @@ -0,0 +1 @@ +metrics=org.apache.dubbo.metrics.prometheus.PrometheusMetricsReporterCmd diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java index 08186127ec..1c43927713 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/test/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterTest.java @@ -17,13 +17,13 @@ package org.apache.dubbo.metrics.prometheus; +import com.sun.net.httpserver.HttpServer; +import io.micrometer.prometheus.PrometheusMeterRegistry; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.MetricsConfig; import org.apache.dubbo.config.nested.PrometheusConfig; import org.apache.dubbo.metrics.collector.DefaultMetricsCollector; import org.apache.dubbo.rpc.model.ApplicationModel; - -import io.micrometer.prometheus.PrometheusMeterRegistry; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -35,8 +35,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.util.concurrent.ScheduledExecutorService; import java.util.stream.Collectors; @@ -96,8 +99,9 @@ class PrometheusMetricsReporterTest { ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(new ApplicationConfig("metrics-test")); PrometheusMetricsReporter reporter = new PrometheusMetricsReporter(metricsConfig.toUrl(), applicationModel); reporter.init(); + exportHttpServer(reporter, port); try { - Thread.sleep(60000); + Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -134,4 +138,26 @@ class PrometheusMetricsReporterTest { reporter.destroy(); Assertions.assertTrue(executor.isTerminated() || executor.isShutdown()); } + + + private void exportHttpServer(PrometheusMetricsReporter reporter, int port) { + + try { + HttpServer prometheusExporterHttpServer = HttpServer.create(new InetSocketAddress(port), 0); + prometheusExporterHttpServer.createContext("/metrics", httpExchange -> { + reporter.refreshData(); + String response = reporter.getPrometheusRegistry().scrape(); + httpExchange.sendResponseHeaders(200, response.getBytes().length); + try (OutputStream os = httpExchange.getResponseBody()) { + os.write(response.getBytes()); + } + }); + + Thread httpServerThread = new Thread(prometheusExporterHttpServer::start); + httpServerThread.start(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/BaseCommand.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/BaseCommand.java index c2a8419685..ee4d233024 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/BaseCommand.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/BaseCommand.java @@ -21,5 +21,10 @@ import org.apache.dubbo.common.extension.SPI; @SPI(scope = ExtensionScope.FRAMEWORK) public interface BaseCommand { - String execute(CommandContext commandContext,String[] args); + + default boolean logResult() { + return true; + } + + String execute(CommandContext commandContext, String[] args); } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java index 59273c1f18..19cb8ef82c 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java @@ -16,10 +16,7 @@ */ package org.apache.dubbo.qos.command; -import java.util.Arrays; -import java.util.Objects; -import java.util.Optional; - +import io.netty.channel.Channel; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.qos.command.annotation.Cmd; @@ -31,7 +28,9 @@ import org.apache.dubbo.qos.permission.PermissionChecker; import org.apache.dubbo.qos.permission.PermissionLevel; import org.apache.dubbo.rpc.model.FrameworkModel; -import io.netty.channel.Channel; +import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; public class DefaultCommandExecutor implements CommandExecutor { private final static Logger logger = LoggerFactory.getLogger(DefaultCommandExecutor.class); @@ -83,9 +82,11 @@ public class DefaultCommandExecutor implements CommandExecutor { try { String result = command.execute(commandContext, commandContext.getArgs()); - logger.info("[Dubbo QoS] Command Process success. Command: " + commandContext.getCommandName() + - ", Args: " + Arrays.toString(commandContext.getArgs()) + ", Result: " + result + - ", Remote Address: " + remoteAddress); + if (command.logResult()) { + logger.info("[Dubbo QoS] Command Process success. Command: " + commandContext.getCommandName() + + ", Args: " + Arrays.toString(commandContext.getArgs()) + ", Result: " + result + + ", Remote Address: " + remoteAddress); + } return result; } catch (Throwable t) { logger.info("[Dubbo QoS] Command Process Failed. Command: " + commandContext.getCommandName() + diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java index b941bfe237..4aa29375f1 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java @@ -16,15 +16,14 @@ */ package org.apache.dubbo.qos.command.decoder; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.CommandContextFactory; - import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.multipart.Attribute; import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.command.CommandContextFactory; import java.io.IOException; import java.util.ArrayList; @@ -50,7 +49,7 @@ public class HttpCommandDecoder { for (List values : queryStringDecoder.parameters().values()) { valueList.addAll(values); } - commandContext = CommandContextFactory.newInstance(name, valueList.toArray(new String[]{}),true); + commandContext = CommandContextFactory.newInstance(name, valueList.toArray(new String[]{}), true); } } else if (request.method() == HttpMethod.POST) { HttpPostRequestDecoder httpPostRequestDecoder = new HttpPostRequestDecoder(request); @@ -69,10 +68,18 @@ public class HttpCommandDecoder { commandContext = CommandContextFactory.newInstance(name); commandContext.setHttp(true); } else { - commandContext = CommandContextFactory.newInstance(name, valueList.toArray(new String[]{}),true); + commandContext = CommandContextFactory.newInstance(name, valueList.toArray(new String[]{}), true); } } + } else if (array.length == 3) { + String name = array[1]; + String appName = array[2]; + if (request.method() == HttpMethod.GET) { + commandContext = CommandContextFactory.newInstance(name, new String[]{appName}, true); + commandContext.setHttp(true); + } } + } return commandContext; From 27c614ba1d1f90efe059ee25c7bb2772a5649ad5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:35:19 +0800 Subject: [PATCH 109/144] Bump bytebuddy.version from 1.14.0 to 1.14.1 (#11808) Bumps `bytebuddy.version` from 1.14.0 to 1.14.1. Updates `byte-buddy` from 1.14.0 to 1.14.1 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.0...byte-buddy-1.14.1) Updates `byte-buddy-agent` from 1.14.0 to 1.14.1 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.0...byte-buddy-1.14.1) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: net.bytebuddy:byte-buddy-agent dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-spring-boot/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index c67931eace..bd4e0035a2 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -45,7 +45,7 @@ 2.20.0 - 1.14.0 + 1.14.1 From a6ef8910ca7cc2332f23fd4f285d23afe9791849 Mon Sep 17 00:00:00 2001 From: Xiang Wei Zhang Date: Mon, 13 Mar 2023 20:15:54 +0800 Subject: [PATCH 110/144] Fix 2.6.x LoadBalance SPI not work (#11730) --- .../src/main/java/com/alibaba/dubbo/rpc/Invoker.java | 5 +++++ .../src/main/java/com/alibaba/dubbo/rpc/Result.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java index 5ad026f620..124b063de6 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java @@ -50,6 +50,11 @@ public interface Invoker extends org.apache.dubbo.rpc.Invoker { return invoker.getInterface(); } + @Override + public org.apache.dubbo.rpc.Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws org.apache.dubbo.rpc.RpcException { + return new Result.CompatibleResult(invoker.invoke(invocation)); + } + @Override public Result invoke(Invocation invocation) throws RpcException { return new Result.CompatibleResult(invoker.invoke(invocation.getOriginal())); diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java index ff690c1dfc..3a1da951c0 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java @@ -103,6 +103,11 @@ public interface Result extends org.apache.dubbo.rpc.Result { return delegate; } + @Override + public org.apache.dubbo.rpc.Result whenCompleteWithContext(BiConsumer fn) { + return delegate.whenCompleteWithContext(fn); + } + @Override public Object getValue() { return delegate.getValue(); From 03562680ee08effaca6b89b4b85902f9ba3e23e8 Mon Sep 17 00:00:00 2001 From: chenrenhang <53365835+1137396708@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:17:30 +0800 Subject: [PATCH 111/144] fix remove unused param (#11787) * fix remove unused param * fix remove unused param --- .../apache/dubbo/registry/client/ServiceDiscoveryRegistry.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java index 88c04eadb9..5cb52f08dd 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java @@ -39,7 +39,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import static org.apache.dubbo.common.constants.CommonConstants.CHECK_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR; @@ -192,8 +191,6 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { serviceDiscovery.subscribe(url, listener); - boolean check = url.getParameter(CHECK_KEY, false); - Set mappingByUrl = ServiceNameMapping.getMappingByUrl(url); String key = ServiceNameMapping.buildMappingKey(url); From e6ee6088bffec78c25bae6849e28aa0dada2d0c2 Mon Sep 17 00:00:00 2001 From: kanghailin <37978579+kang-hl@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:55:41 +0800 Subject: [PATCH 112/144] Remove redundant synchronized (#11811) --- .../main/java/org/apache/dubbo/config/ReferenceConfig.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java index 86796a9139..ad47b82261 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java @@ -228,11 +228,7 @@ public class ReferenceConfig extends ReferenceConfigBase { // ensure start module, compatible with old api usage getScopeModel().getDeployer().start(); - synchronized (this) { - if (ref == null) { - init(); - } - } + init(); } return ref; From 69edf4ef8c158b95a0ce510bffdf17b3a4de1ec8 Mon Sep 17 00:00:00 2001 From: huazhongming Date: Tue, 14 Mar 2023 11:31:48 +0800 Subject: [PATCH 113/144] Dynamically generate native image config (#11795) * ADD dubbo-maven-plugin * add dubbo-maven-plugin module Signed-off-by: crazyhzm * fix license and compiler error Signed-off-by: crazyhzm * fix license and ci error Signed-off-by: crazyhzm * fix ci error Signed-off-by: crazyhzm * Remove proxy-config, hard code Signed-off-by: crazyhzm * ignoredModulesInDubboAll Signed-off-by: crazyhzm * throw exception for generated adaptive class sources Signed-off-by: crazyhzm * remove useless reflect config Signed-off-by: crazyhzm * Dynamically generate native image config for graalvm, and remove the original native image config Signed-off-by: crazyhzm * fix conflict Signed-off-by: crazyhzm * remove .git.exec.error Signed-off-by: crazyhzm * remove .git.exec.error Signed-off-by: crazyhzm * remove useless import Signed-off-by: crazyhzm --------- Signed-off-by: crazyhzm Co-authored-by: Albumen Kevin --- .gitignore | 2 + .licenserc.yaml | 3 + .../beans/factory/ScopeBeanFactory.java | 6 + .../META-INF/native-image/reflect-config.json | 17 + .../src/main/resources/Log4j.properties | 12 +- .../META-INF/native-image/reflect-config.json | 25 + .../native-image/resource-config.json | 13 + .../maven/plugin/aot/DubboProcessAotMojo.java | 38 +- .../META-INF/native-image/jni-config.json | 2 - .../META-INF/native-image/proxy-config.json | 3 - .../META-INF/native-image/reflect-config.json | 3032 ----------------- .../native-image/resource-config.json | 169 - .../native-image/serialization-config.json | 2 - .../dubbo/aot/generate/AotProcessor.java | 54 + .../dubbo/aot/generate/BasicJsonWriter.java | 288 ++ .../dubbo/aot/generate/ClassSourceFinder.java | 92 - .../aot/generate/ClassSourceScanner.java | 174 + .../aot/generate/ConditionalDescriber.java | 26 + .../aot/generate/ExecutableDescriber.java | 72 + .../dubbo/aot/generate/ExecutableMode.java | 48 + .../dubbo/aot/generate/FieldDescriber.java | 38 + .../apache/dubbo/aot/generate/JarScanner.java | 146 + .../dubbo/aot/generate/MemberCategory.java | 125 + .../dubbo/aot/generate/MemberDescriber.java | 40 + ...ator.java => NativeClassSourceWriter.java} | 44 +- .../generate/NativeConfigurationWriter.java | 85 + .../ReflectConfigMetadataRepository.java | 66 + .../aot/generate/ReflectionConfigWriter.java | 134 + .../aot/generate/ResourceBundleDescriber.java | 70 + .../ResourceConfigMetadataRepository.java | 72 + .../aot/generate/ResourceConfigWriter.java | 87 + .../generate/ResourcePatternDescriber.java | 58 + .../dubbo/aot/generate/ResourceScanner.java | 57 + .../dubbo/aot/generate/TypeDescriber.java | 74 + .../ResourcePatternDescriberTest.java | 28 + pom.xml | 3 + 36 files changed, 1827 insertions(+), 3378 deletions(-) create mode 100644 dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/resource-config.json delete mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json delete mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json delete mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json delete mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json delete mode 100644 dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java delete mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceFinder.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceScanner.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ConditionalDescriber.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableDescriber.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/FieldDescriber.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/JarScanner.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberDescriber.java rename dubbo-native/src/main/java/org/apache/dubbo/aot/generate/{CodeGenerator.java => NativeClassSourceWriter.java} (68%) create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/NativeConfigurationWriter.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectionConfigWriter.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceBundleDescriber.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigMetadataRepository.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigWriter.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourcePatternDescriber.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceScanner.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/aot/generate/TypeDescriber.java create mode 100644 dubbo-native/src/test/java/org/apache/dubbo/aot/generate/ResourcePatternDescriberTest.java diff --git a/.gitignore b/.gitignore index 1f1a579238..0dffb48ba3 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ dubbo-demo/dubbo-demo-triple/build/* # global registry center .tmp +.git.exec.error + diff --git a/.licenserc.yaml b/.licenserc.yaml index 70b039fe23..5b8980c95e 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -95,6 +95,9 @@ 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' comment: on-failure diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java index 304bfa90d8..c2b52897ca 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/beans/factory/ScopeBeanFactory.java @@ -53,6 +53,7 @@ public class ScopeBeanFactory { private final List registeredBeanInfos = new CopyOnWriteArrayList<>(); private InstantiationStrategy instantiationStrategy; private final AtomicBoolean destroyed = new AtomicBoolean(); + private List> registeredClasses = new ArrayList<>(); public ScopeBeanFactory(ScopeBeanFactory parent, ExtensionAccessor extensionAccessor) { this.parent = parent; @@ -131,6 +132,7 @@ public class ScopeBeanFactory { } } } + registeredClasses.add(type); return bean; } @@ -281,4 +283,8 @@ public class ScopeBeanFactory { this.instance = instance; } } + + public List> getRegisteredClasses() { + return registeredClasses; + } } diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 0000000000..eee360499b --- /dev/null +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,17 @@ +[ + { + "name": "org.apache.zookeeper.ClientCnxnSocketNIO", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.zookeeper.client.ZKClientConfig" + ] + }, + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/Log4j.properties b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/Log4j.properties index 4e90fa24e7..192673cfec 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/Log4j.properties +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/Log4j.properties @@ -18,8 +18,10 @@ # -log4j.rootLogger=error, console - -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=[%-12d{HH\:mm\:ss.SS}] [%p] %l %m%n +###set log levels### +log4j.rootLogger=info, stdout +###output to the console### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 0000000000..0c8a2c368c --- /dev/null +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,25 @@ +[ + { + "name": "org.apace.dubbo.graalvm.demo.DemoService", + "allPublicMethods": true + }, + { + "name": "org.apache.dubbo.demo.graalvm.provider.DemoServiceImpl", + "allDeclaredMethods": true + }, + { + "name": "org.apache.zookeeper.ClientCnxnSocketNIO", + "methods": [ + { + "name": "", + "parameterTypes": [ + "org.apache.zookeeper.client.ZKClientConfig" + ] + }, + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/resource-config.json b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/resource-config.json new file mode 100644 index 0000000000..6bc4f4cc3b --- /dev/null +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image/resource-config.json @@ -0,0 +1,13 @@ +{ + "resources": { + "includes": [ + { + "pattern": "\\Qdubbo.properties\\E" + }, + { + "pattern": "\\Qlog4j.properties\\E" + } + ] + }, + "bundles": [] +} diff --git a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java index 5b4f26b8b4..fbcc05a466 100644 --- a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java +++ b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DubboProcessAotMojo.java @@ -17,18 +17,14 @@ package org.apache.dubbo.maven.plugin.aot; -import org.apache.commons.io.FileUtils; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.project.MavenProject; import java.io.File; -import java.io.InputStream; import java.net.URL; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; @Mojo(name = "dubbo-process-aot", defaultPhase = LifecyclePhase.PREPARE_PACKAGE, threadSafe = true, @@ -36,7 +32,7 @@ import java.util.List; requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME) public class DubboProcessAotMojo extends AbstractAotMojo { - private static final String AOT_PROCESSOR_CLASS_NAME = "org.apache.dubbo.aot.generate.CodeGenerator"; + private static final String AOT_PROCESSOR_CLASS_NAME = "org.apache.dubbo.aot.generate.AotProcessor"; /** * Directory containing the classes and resource files that should be packaged into @@ -83,7 +79,6 @@ public class DubboProcessAotMojo extends AbstractAotMojo { URL[] classPath = getClassPath().toArray(new URL[0]); generateAotAssets(classPath, AOT_PROCESSOR_CLASS_NAME, getAotArguments(mainClass)); compileSourceFiles(classPath, this.generatedSources, this.classesDirectory); - copyNativeConfigFile(project); copyAll(this.generatedResources.toPath(), this.classesDirectory.toPath()); copyAll(this.generatedClasses.toPath(), this.classesDirectory.toPath()); } @@ -104,35 +99,4 @@ public class DubboProcessAotMojo extends AbstractAotMojo { File[] directories = new File[]{this.classesDirectory, this.generatedClasses}; return getClassPath(directories, new ExcludeTestScopeArtifactFilter()); } - - private void copyNativeConfigFile(MavenProject project) { - String[] nativeFiles = {"META-INF/native-image/reflect-config.json", - "META-INF/native-image/jni-config.json", - "META-INF/native-image/proxy-config.json", - "META-INF/native-image/resource-config.json", - "META-INF/native-image/serialization-config.json"}; - - Arrays.stream(nativeFiles).forEach(nativeFile -> { - InputStream is = this.getClass().getClassLoader().getResourceAsStream(nativeFile); - project.getResources().stream().findFirst().ifPresent(resource -> { - try { - String path = generatedResources + File.separator + "META-INF" + File.separator + "native-image" + File.separator - + File.separator + this.project.getGroupId() + File.separator + this.project.getArtifactId(); - FileUtils.forceMkdir(new File(path)); - String[] str = nativeFile.split("/"); - File file = new File(path + File.separator + str[str.length - 1]); - if (!file.exists()) { - FileUtils.copyInputStreamToFile(is, file); - getLog().info("Copy native config file:" + file); - } else { - getLog().info("Skip copy config file:" + file); - } - } catch (Throwable ex) { - getLog().error("Copy native config file error:" + ex.getMessage()); - } - }); - }); - } - - } diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json deleted file mode 100644 index 0d4f101c7a..0000000000 --- a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/jni-config.json +++ /dev/null @@ -1,2 +0,0 @@ -[ -] diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json deleted file mode 100644 index 41b42e677b..0000000000 --- a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/proxy-config.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - -] diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json deleted file mode 100644 index 59853eab5b..0000000000 --- a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/reflect-config.json +++ /dev/null @@ -1,3032 +0,0 @@ -[ - { - "name": "boolean", - "allPublicMethods": true - }, - { - "name": "com.intellij.rt.execution.application.AppMainV2$Agent", - "methods": [ - { - "name": "premain", - "parameterTypes": [ - "java.lang.String", - "java.lang.instrument.Instrumentation" - ] - } - ] - }, - { - "name": "io.netty.bootstrap.ServerBootstrap$1" - }, - { - "name": "io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor", - "methods": [ - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - } - ] - }, - { - "name": "io.netty.buffer.AbstractByteBufAllocator", - "allDeclaredMethods": true - }, - { - "name": "io.netty.buffer.AbstractReferenceCountedByteBuf", - "fields": [ - { - "name": "refCnt", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "io.netty.channel.ChannelDuplexHandler", - "methods": [ - { - "name": "bind", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.net.SocketAddress", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "close", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "connect", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.net.SocketAddress", - "java.net.SocketAddress", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "deregister", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "disconnect", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "flush", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "read", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - } - ] - }, - { - "name": "io.netty.channel.ChannelHandlerAdapter", - "methods": [ - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - } - ] - }, - { - "name": "io.netty.channel.ChannelInboundHandlerAdapter", - "methods": [ - { - "name": "channelActive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelInactive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "channelReadComplete", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRegistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelUnregistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelWritabilityChanged", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - }, - { - "name": "userEventTriggered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - } - ] - }, - { - "name": "io.netty.channel.ChannelInitializer", - "methods": [ - { - "name": "channelRegistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - } - ] - }, - { - "name": "io.netty.channel.ChannelOutboundHandlerAdapter", - "methods": [ - { - "name": "bind", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.net.SocketAddress", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "close", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "connect", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.net.SocketAddress", - "java.net.SocketAddress", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "deregister", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "disconnect", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "flush", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "read", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - } - ] - }, - { - "name": "io.netty.channel.DefaultChannelPipeline$HeadContext", - "methods": [ - { - "name": "bind", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.net.SocketAddress", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "channelActive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelInactive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "channelReadComplete", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRegistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelUnregistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelWritabilityChanged", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "close", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "connect", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.net.SocketAddress", - "java.net.SocketAddress", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "deregister", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "disconnect", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "io.netty.channel.ChannelPromise" - ] - }, - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - }, - { - "name": "flush", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "read", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "userEventTriggered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "write", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object", - "io.netty.channel.ChannelPromise" - ] - } - ] - }, - { - "name": "io.netty.channel.DefaultChannelPipeline$TailContext", - "methods": [ - { - "name": "channelActive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelInactive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "channelReadComplete", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRegistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelUnregistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelWritabilityChanged", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - }, - { - "name": "userEventTriggered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - } - ] - }, - { - "name": "io.netty.channel.socket.nio.NioServerSocketChannel", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "io.netty.channel.socket.nio.NioSocketChannel", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "io.netty.handler.codec.ByteToMessageDecoder", - "methods": [ - { - "name": "channelInactive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "channelReadComplete", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "userEventTriggered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - } - ] - }, - { - "name": "io.netty.handler.codec.MessageToByteEncoder", - "methods": [ - { - "name": "write", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object", - "io.netty.channel.ChannelPromise" - ] - } - ] - }, - { - "name": "io.netty.handler.timeout.IdleStateHandler", - "methods": [ - { - "name": "channelActive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelInactive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "channelReadComplete", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRegistered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "write", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object", - "io.netty.channel.ChannelPromise" - ] - } - ] - }, - { - "name": "io.netty.util.ReferenceCountUtil", - "allDeclaredMethods": true - }, - { - "name": "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields", - "fields": [ - { - "name": "producerLimit", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields", - "fields": [ - { - "name": "consumerIndex", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields", - "fields": [ - { - "name": "producerIndex", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField", - "fields": [ - { - "name": "consumerIndex", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField", - "fields": [ - { - "name": "producerIndex", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField", - "fields": [ - { - "name": "producerLimit", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "java.io.File", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.String" - ] - } - ] - }, - { - "name": "java.io.Serializable", - "allDeclaredMethods": true - }, - { - "name": "java.lang.Cloneable", - "allDeclaredMethods": true - }, - { - "name": "java.lang.Comparable", - "allDeclaredMethods": true - }, - { - "name": "java.lang.Enum", - "allDeclaredFields": true, - "allDeclaredMethods": true - }, - { - "name": "java.lang.Integer", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "java.lang.Number", - "allDeclaredFields": true, - "allDeclaredMethods": true - }, - { - "name": "java.lang.Object", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allPublicMethods": true - }, - { - "name": "java.lang.StackTraceElement", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "java.lang.String" - }, - { - "name": "java.lang.String[]" - }, - { - "name": "java.lang.Thread", - "methods": [ - { - "name": "getContextClassLoader", - "parameterTypes": [] - } - ] - }, - { - "name": "java.lang.Throwable", - "fields": [ - { - "name": "detailMessage" - }, - { - "name": "stackTrace" - } - ] - }, - { - "name": "java.lang.management.ManagementFactory", - "methods": [ - { - "name": "getRuntimeMXBean", - "parameterTypes": [] - } - ] - }, - { - "name": "java.lang.management.RuntimeMXBean", - "methods": [ - { - "name": "getName", - "parameterTypes": [] - } - ] - }, - { - "name": "java.math.BigDecimal", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.String" - ] - } - ] - }, - { - "name": "java.math.BigInteger", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "java.net.URL", - "fields": [ - { - "name": "ref" - } - ] - }, - { - "name": "java.nio.Bits", - "methods": [ - { - "name": "unaligned", - "parameterTypes": [] - } - ] - }, - { - "name": "java.nio.Buffer", - "fields": [ - { - "name": "address", - "allowUnsafeAccess": true - } - ] - }, - { - "name": "java.nio.DirectByteBuffer", - "fields": [ - { - "name": "cleaner", - "allowUnsafeAccess": true - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [ - "long", - "int" - ] - } - ] - }, - { - "name": "java.security.MessageDigestSpi" - }, - { - "name": "java.sql.Date", - "methods": [ - { - "name": "", - "parameterTypes": [ - "long" - ] - } - ] - }, - { - "name": "java.sql.Time", - "methods": [ - { - "name": "", - "parameterTypes": [ - "long" - ] - } - ] - }, - { - "name": "java.sql.Timestamp", - "methods": [ - { - "name": "", - "parameterTypes": [ - "long" - ] - } - ] - }, - { - "name": "java.time.Duration" - }, - { - "name": "java.time.Instant" - }, - { - "name": "java.time.LocalDate" - }, - { - "name": "java.time.LocalDateTime" - }, - { - "name": "java.time.LocalTime" - }, - { - "name": "java.time.MonthDay" - }, - { - "name": "java.time.OffsetDateTime" - }, - { - "name": "java.time.OffsetTime" - }, - { - "name": "java.time.Period" - }, - { - "name": "java.time.Year" - }, - { - "name": "java.time.YearMonth" - }, - { - "name": "java.time.ZoneId" - }, - { - "name": "java.time.ZoneOffset" - }, - { - "name": "java.time.ZonedDateTime" - }, - { - "name": "java.util.AbstractMap", - "allDeclaredFields": true, - "allDeclaredMethods": true - }, - { - "name": "java.util.ArrayList", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "java.util.BitSet", - "allDeclaredFields": true - }, - { - "name": "java.util.HashMap", - "allDeclaredMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "java.util.LinkedHashMap", - "allPublicConstructors": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "java.util.Map", - "allDeclaredMethods": true - }, - { - "name": "java.util.NavigableMap", - "allDeclaredMethods": true - }, - { - "name": "java.util.SortedMap", - "allDeclaredMethods": true - }, - { - "name": "java.util.TreeMap", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "java.util.Map", - "allPublicConstructors": true - }, - { - "name": "java.util.concurrent.ConcurrentNavigableMap" - }, - { - "name": "java.util.concurrent.ConcurrentSkipListMap" - }, - { - "name": "javax.management.ObjectName", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.String" - ] - } - ] - }, - { - "name": "org.apace.dubbo.graalvm.demo.DemoService", - "allPublicMethods": true - }, - { - "name": "org.apache.curator.x.discovery.ServiceType", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "org.apache.curator.x.discovery.details.OldServiceInstance", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "org.apache.dubbo.common.CommonScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.serialize.hessian2.Hessian2ScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.serialize.fastjson2.Fastjson2ScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.URL", - "allDeclaredFields": true - }, - { - "name": "org.apache.dubbo.common.beans.ScopeBeanExtensionInjector", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.compiler.support.AdaptiveCompiler", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.compiler.support.JavassistCompiler", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.compiler.support.JdkCompiler", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.config.Environment", - "allPublicMethods": true, - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.common.config.ModuleEnvironment", - "allPublicMethods": true, - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigurationFactory" - }, - { - "name": "org.apache.dubbo.common.config.configcenter.nop.NopDynamicConfigurationFactory" - }, - { - "name": "org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.extension.inject.SpiExtensionInjector", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.infra.support.EnvironmentAdapter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.lang.ShutdownHookCallbacks", - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.common.logger.jcl.JclLoggerAdapter" - }, - { - "name": "org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter" - }, - { - "name": "org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter" - }, - { - "name": "org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.serialize.hessian2.Hessian2FactoryManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.FrameworkModel" - ] - } - ] - }, - { - "name": "org.apache.dubbo.common.serialize.fastjson2.FastJson2Serialization", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.serialize.fastjson2.Fastjson2CreatorManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.FrameworkModel" - ] - } - ] - }, - { - "name": "org.apache.dubbo.common.serialize.fastjson2.Fastjson2SecurityManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.FrameworkModel" - ] - } - ] - }, - { - "name": "org.apache.dubbo.common.utils.SerializeSecurityConfigurator", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ModuleModel" - ] - } - ] - }, - { - "name": "org.apache.dubbo.common.utils.SerializeSecurityManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - ] - } - ] - }, - { - "name": "org.apache.dubbo.common.utils.DefaultSerializeClassChecker", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.FrameworkModel" - ] - } - ] - }, - { - "name": "org.apache.dubbo.common.utils.SerializeClassChecker", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.status.reporter.FrameworkStatusReportService", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.threadpool.ThreadPool", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.common.threadpool.ThreadPool$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.threadpool.manager.DefaultExecutorRepository", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] - } - ] - }, - { - "name": "org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool" - }, - { - "name": "org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool" - }, - { - "name": "org.apache.dubbo.common.url.component.URLAddress", - "allDeclaredFields": true - }, - { - "name": "org.apache.dubbo.common.url.component.URLParam", - "allDeclaredFields": true - }, - { - "name": "org.apache.dubbo.common.url.component.param.DefaultDynamicParamSource", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.AbstractConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.AbstractInterfaceConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.AbstractMethodConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.AbstractReferenceConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.AbstractServiceConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.ApplicationConfig", - "allPublicMethods": true, - "fields": [ - { - "name": "monitor" - }, - { - "name": "registries" - } - ] - }, - { - "name": "org.apache.dubbo.config.ArgumentConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.ConfigCenterConfig", - "allPublicMethods": true, - "fields": [ - { - "name": "appExternalConfiguration" - }, - { - "name": "externalConfiguration" - } - ] - }, - { - "name": "org.apache.dubbo.config.ConfigScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.ConsumerConfig", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.MethodConfig", - "allPublicMethods": true, - "fields": [ - { - "name": "arguments" - } - ] - }, - { - "name": "org.apache.dubbo.config.ModuleConfig", - "allPublicMethods": true, - "fields": [ - { - "name": "monitor" - }, - { - "name": "registries" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.ProtocolConfig", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.ProviderConfig", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.ReferenceConfig", - "allPublicMethods": true, - "fields": [ - { - "name": "invoker" - } - ] - }, - { - "name": "org.apache.dubbo.config.ReferenceConfigBase", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.RegistryConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.ServiceConfig", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.ServiceConfigBase", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.config.SslConfig", - "allPublicMethods": true, - "fields": [ - { - "name": "clientKeyCertChainPathStream" - }, - { - "name": "clientPrivateKeyPathStream" - }, - { - "name": "clientTrustCertCollectionPathStream" - }, - { - "name": "serverKeyCertChainPathStream" - }, - { - "name": "serverPrivateKeyPathStream" - }, - { - "name": "serverTrustCertCollectionPathStream" - } - ], - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.context.ConfigManager", - "allPublicMethods": true, - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.config.deploy.DefaultApplicationDeployer", - "allPublicConstructors": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] - } - ] - }, - { - "name": "org.apache.dubbo.config.deploy.DefaultModuleDeployer", - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.metadata.ServiceInstanceHostPortCustomizer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.utils.DefaultConfigValidator", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ApplicationModel" - ] - } - ] - }, - { - "name": "org.apache.dubbo.demo.graalvm.provider.DemoServiceImpl", - "methods": [ - { - "name": "sayHello", - "parameterTypes": [ - "java.lang.String" - ] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.InstanceMetadataChangedListener", - "allDeclaredFields": true - }, - { - "name": "org.apache.dubbo.metadata.MetadataInfo", - "allDeclaredFields": true - }, - { - "name": "org.apache.dubbo.metadata.MetadataInfo$ServiceInfo", - "allDeclaredFields": true - }, - { - "name": "org.apache.dubbo.metadata.MetadataService", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.metadata.definition.builder.ArrayTypeBuilder", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.definition.builder.CollectionTypeBuilder", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.definition.builder.EnumTypeBuilder", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.definition.builder.MapTypeBuilder", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.definition.model.MethodDefinition", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.definition.model.ServiceDefinition", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.definition.model.TypeDefinition", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.report.MetadataReportInstance", - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] - } - ] - }, - { - "name": "org.apache.dubbo.metadata.report.MetadataScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.monitor.MetricsService", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.monitor.MonitorService", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.monitor.support.MetricsServiceDetector", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.monitor.support.MonitorFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.monitor.support.MonitorClusterFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.monitor.support.MonitorFilter" - }, - { - "name": "org.apache.dubbo.monitor.support.MonitorServiceDetector", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.RegistryFactory", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.registry.RegistryFactory$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.RegistryFactoryWrapper", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.registry.RegistryFactory" - ] - } - ] - }, - { - "name": "org.apache.dubbo.registry.RegistryScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.DefaultRegistryClusterIdentifier", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.DefaultServiceInstance$Endpoint", - "allDeclaredFields": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.ServiceDiscoveryRegistryFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.metadata.MetadataServiceNameMapping", - "allPublicMethods": true, - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.registry.client.metadata.MetadataServiceURLParamsMetadataCustomizer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.metadata.ProtocolPortsMetadataCustomizer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataCustomizer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.migration.DefaultMigrationAddressComparator", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.client.migration.MigrationRuleListener", - "allPublicMethods": true, - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.integration.RegistryProtocol", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.multicast.MulticastRegistryFactory" - }, - { - "name": "org.apache.dubbo.registry.multicast.MulticastServiceDiscoveryFactory" - }, - { - "name": "org.apache.dubbo.registry.support.DefaultProviderFirstParams", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.support.RegistryManager", - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.registry.zookeeper.ZookeeperInstance", - "allDeclaredFields": true, - "allDeclaredMethods": true, - "allDeclaredConstructors": true - }, - { - "name": "org.apache.dubbo.registry.zookeeper.ZookeeperRegistryFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscoveryFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.Dispatcher", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.remoting.Dispatcher$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.Transporter", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.remoting.Transporter$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.exchange.codec.ExchangeCodec" - }, - { - "name": "org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.telnet.codec.TelnetCodec" - }, - { - "name": "org.apache.dubbo.remoting.transport.codec.TransportCodec" - }, - { - "name": "org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher" - }, - { - "name": "org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher" - }, - { - "name": "org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher" - }, - { - "name": "org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher" - }, - { - "name": "org.apache.dubbo.remoting.transport.netty4.NettyClient$1" - }, - { - "name": "org.apache.dubbo.remoting.transport.netty4.NettyClientHandler", - "methods": [ - { - "name": "channelActive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelInactive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - }, - { - "name": "userEventTriggered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "write", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object", - "io.netty.channel.ChannelPromise" - ] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalDecoder" - }, - { - "name": "org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder" - }, - { - "name": "org.apache.dubbo.remoting.transport.netty4.NettyServer$1" - }, - { - "name": "org.apache.dubbo.remoting.transport.netty4.NettyServerHandler", - "methods": [ - { - "name": "channelActive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelInactive", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext" - ] - }, - { - "name": "channelRead", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "exceptionCaught", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Throwable" - ] - }, - { - "name": "userEventTriggered", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object" - ] - }, - { - "name": "write", - "parameterTypes": [ - "io.netty.channel.ChannelHandlerContext", - "java.lang.Object", - "io.netty.channel.ChannelPromise" - ] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.transport.netty4.NettyTransporter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.remoting.zookeeper.curator5.Curator5ZookeeperTransporter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.Invoker", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.Protocol", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.Protocol$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.ProxyFactory", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.ProxyFactory$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.Cluster", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.cluster.Cluster$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.ClusterScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metrics.MetricsScopeModelInitializer", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.ConfiguratorFactory", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.cluster.ConfiguratorFactory$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.Directory", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.cluster.RouterFactory", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.cluster.RouterFactory$Adaptive", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.configurator.absent.AbsentConfiguratorFactory" - }, - { - "name": "org.apache.dubbo.rpc.cluster.configurator.override.OverrideConfiguratorFactory" - }, - { - "name": "org.apache.dubbo.rpc.cluster.filter.DefaultFilterChainBuilder", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.Protocol" - ] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter", - "allPublicMethods": true, - "allPublicConstructors": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.filter.support.ZoneAwareFilter" - }, - { - "name": "org.apache.dubbo.rpc.cluster.governance.DefaultGovernanceRuleRepositoryImpl", - "allPublicMethods": true, - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance" - }, - { - "name": "org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance" - }, - { - "name": "org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance" - }, - { - "name": "org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance" - }, - { - "name": "org.apache.dubbo.rpc.cluster.merger.MergerFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.ClusterUtils", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.AccessLogFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.ClassLoaderFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.CompatibleFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.ContextFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.DeprecatedFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.EchoFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.ExceptionFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.ExecuteLimitFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.GenericFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.GenericImplFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.model.ModuleModel" - ] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.TimeoutFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory" - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.file.FileStateRouterFactory" - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleAddressListenerInterceptor", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.mesh.route.StandardMeshRuleRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.mock.MockStateRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.tag.TagDynamicStateRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.tag.TagStaticStateRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.AvailableCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.BroadcastCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.ClusterUtils", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.FailbackCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.FailfastCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.FailoverCluster", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.FailsafeCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.ForkingCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.MergeableCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.merger.DefaultProviderURLMergeProcessor", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster" - }, - { - "name": "org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.cluster.Cluster" - ] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.filter.AccessLogFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.ClassLoaderFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.CompatibleFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.DeprecatedFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.EchoFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.ExceptionFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.ExecuteLimitFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.GenericFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.TimeoutFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.TokenFilter" - }, - { - "name": "org.apache.dubbo.rpc.filter.TpsLimitFilter" - }, - { - "name": "org.apache.dubbo.rpc.listener.DeprecatedInvokerListener" - }, - { - "name": "org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.Protocol" - ] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.Protocol" - ] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec", - "allPublicMethods": true, - "allPublicConstructors": true - }, - { - "name": "org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.AdaptiveMetrics", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter" - }, - { - "name": "org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.ssl.impl.SSLConfigCertProvider", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.security.cert.DubboCertManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] - } - ] - }, - { - "name": "org.apache.dubbo.common.ssl.CertManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory" - }, - { - "name": "org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.proxy.wrapper.StubProxyFactoryWrapper", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [ - "org.apache.dubbo.rpc.ProxyFactory" - ] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.service.Destroyable", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.service.EchoService", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.service.EchoServiceDetector", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.service.GenericService", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.rpc.service.GenericServiceDetector", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.support.MockProtocol" - }, - { - "name": "org.apache.log4j.Appender" - }, - { - "name": "org.apache.log4j.Category" - }, - { - "name": "org.apache.log4j.CategoryKey" - }, - { - "name": "org.apache.log4j.ConsoleAppender", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.log4j.Layout", - "allPublicMethods": true - }, - { - "name": "org.apache.log4j.Logger" - }, - { - "name": "org.apache.log4j.PatternLayout", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.logging.log4j.Level", - "allPublicMethods": true - }, - { - "name": "org.apache.log4j.helpers.Loader" - }, - { - "name": "org.apache.log4j.spi.OptionHandler" - }, - { - "name": "org.apache.zookeeper.ClientCnxnSocketNIO", - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.zookeeper.client.ZKClientConfig"] - }, - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "sun.misc.Cleaner", - "methods": [ - { - "name": "clean", - "parameterTypes": [] - } - ] - }, - { - "name": "sun.misc.Unsafe", - "fields": [ - { - "name": "theUnsafe" - } - ], - "methods": [ - { - "name": "copyMemory", - "parameterTypes": [ - "java.lang.Object", - "long", - "java.lang.Object", - "long", - "long" - ] - }, - { - "name": "getAndAddLong", - "parameterTypes": [ - "java.lang.Object", - "long", - "long" - ] - }, - { - "name": "getAndSetObject", - "parameterTypes": [ - "java.lang.Object", - "long", - "java.lang.Object" - ] - } - ] - }, - { - "name": "sun.misc.VM", - "methods": [ - { - "name": "maxDirectMemory", - "parameterTypes": [] - } - ] - }, - { - "name": "sun.nio.ch.SelectorImpl", - "fields": [ - { - "name": "publicSelectedKeys" - }, - { - "name": "selectedKeys" - } - ] - }, - { - "name": "sun.security.provider.ConfigFile", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "sun.security.provider.MD5", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "sun.security.provider.NativePRNG", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "sun.security.provider.SHA", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "sun.security.provider.Sun", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.common.convert.ConverterUtil", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ModuleModel"] - } - ] - }, - { - "name": "org.apache.dubbo.config.context.ModuleConfigManager", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ModuleModel"] - } - ] - }, - { - "name": "org.apache.dubbo.common.store.support.SimpleDataStore", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.metrics.collector.DefaultMetricsCollector", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.config.deploy.DefaultMetricsServiceExporter", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.attachment.AttachmentConditionMatcherFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.argument.ArgumentConditionMatcherFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.param.UrlParamConditionMatcherFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.range.RangeValuePattern", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.wildcard.WildcardValuePattern", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.condition.config.ProviderAppStateRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "org.apache.dubbo.rpc.cluster.router.script.config.AppScriptRouterFactory", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "com.alibaba.fastjson.JSON", - "allPublicMethods": true - }, - { - "name": "java.util.Collections$UnmodifiableMap", - "allPublicMethods": true - }, - { - "name": "java.util.Collections$UnmodifiableCollection", - "allPublicMethods": true - }, - { - "name": "org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] - } - ] - } -] diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json deleted file mode 100644 index 51f17b21af..0000000000 --- a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/resource-config.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "resources": { - "includes": [ - { - "pattern": "\\QDENY_CLASS\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.context.ApplicationExt\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.context.ModuleExt\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.infra.InfraAdapter\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.threadpool.manager.ExecutorRepository\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.url.component.param.DynamicParamSource\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.AddressListener\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.ProviderFirstParams\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.RegistryClusterIdentifier\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.client.migration.MigrationAddressComparator\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.registry.integration.RegistryProtocolListener\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.Codec2\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.Dispatcher\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.exchange.Exchanger\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.Filter\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.InvokerListener\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.ProxyFactory\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.ConfiguratorFactory\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.LoadBalance\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.ProviderURLMergeProcessor\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.model.BuiltinServiceDetector\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer\\E" - }, - { - "pattern": "\\QMETA-INF/services/org.apache.dubbo.common.extension.LoadingStrategy\\E" - }, - { - "pattern": "\\Qdubbo.properties\\E" - }, - { - "pattern": "\\Qlog4j.properties\\E" - }, - { - "pattern": "\\Qorg/apache/dubbo/common/Version.class\\E" - }, - { - "pattern": "\\Qorg/apache/dubbo/remoting/RemotingException.class\\E" - }, - { - "pattern": "\\Qorg/apache/dubbo/remoting/Transporters.class\\E" - }, - { - "pattern": "\\Qorg/apache/dubbo/remoting/exchange/Exchangers.class\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore\\E" - }, - { - "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.metrics.service.MetricsServiceExporter\\E" - }, - { - "pattern": "\\Qsecurity/serialize.blockedlist\\E" - }, - { - "pattern": "\\Qsecurity/serialize.allowlist\\E" - } - ] - }, - "bundles": [] -} diff --git a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json b/dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json deleted file mode 100644 index 0d4f101c7a..0000000000 --- a/dubbo-maven-plugin/src/main/resources/META-INF/native-image/serialization-config.json +++ /dev/null @@ -1,2 +0,0 @@ -[ -] diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java new file mode 100644 index 0000000000..c375c0934f --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/AotProcessor.java @@ -0,0 +1,54 @@ +/* + * 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.aot.generate; + +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +/** + * generate related self-adaptive code (native image does not support dynamic code generation. Therefore, code needs to be generated before compilation) + */ +public class AotProcessor { + + public static void main(String[] args) { + String generatedSources = args[1]; + + List> classes = ClassSourceScanner.INSTANCE.spiClassesWithAdaptive(); + NativeClassSourceWriter.INSTANCE.writeTo(classes, generatedSources); + + NativeConfigurationWriter writer = new NativeConfigurationWriter(Paths.get(args[2]), args[4], args[5]); + + ResourceConfigMetadataRepository resourceRepository = new ResourceConfigMetadataRepository(); + resourceRepository.registerIncludesPatterns(ResourceScanner.INSTANCE.distinctSpiResource().toArray(new String[]{})); + resourceRepository.registerIncludesPatterns(ResourceScanner.INSTANCE.distinctSecurityResource().toArray(new String[]{})); + writer.writeResourceConfig(resourceRepository); + + + ReflectConfigMetadataRepository reflectRepository = new ReflectConfigMetadataRepository(); + reflectRepository + .registerSpiExtensionType(new ArrayList<>(ClassSourceScanner.INSTANCE.distinctSpiExtensionClasses(ResourceScanner.INSTANCE.distinctSpiResource()).values())) + .registerAdaptiveType(new ArrayList<>(ClassSourceScanner.INSTANCE.adaptiveClasses().values())) + .registerBeanType(ClassSourceScanner.INSTANCE.scopeModelInitializer()) + .registerConfigType(ClassSourceScanner.INSTANCE.configClasses()); + writer.writeReflectionConfig(reflectRepository); + + + } + + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java new file mode 100644 index 0000000000..0a8263e0e9 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java @@ -0,0 +1,288 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed 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 + * + * https://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.aot.generate; + + +import java.io.IOException; +import java.io.Writer; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + + +/** + * Very basic json writer for the purposes of translating runtime hints to native + * configuration. + * + * @author Stephane Nicoll + */ +class BasicJsonWriter { + + private final IndentingWriter writer; + + /** + * Create a new instance with the specified indent value. + * + * @param writer the writer to use + * @param singleIndent the value of one indent + */ + public BasicJsonWriter(Writer writer, String singleIndent) { + this.writer = new IndentingWriter(writer, singleIndent); + } + + /** + * Create a new instance using two whitespaces for the indent. + * + * @param writer the writer to use + */ + public BasicJsonWriter(Writer writer) { + this(writer, " "); + } + + + /** + * Write an object with the specified attributes. Each attribute is + * written according to its value type: + *
    + *
  • Map: write the value as a nested object
  • + *
  • List: write the value as a nested array
  • + *
  • Otherwise, write a single value
  • + *
+ * + * @param attributes the attributes of the object + */ + public void writeObject(Map attributes) { + writeObject(attributes, true); + } + + /** + * Write an array with the specified items. Each item in the + * list is written either as a nested object or as an attribute + * depending on its type. + * + * @param items the items to write + * @see #writeObject(Map) + */ + public void writeArray(List items) { + writeArray(items, true); + } + + private void writeObject(Map attributes, boolean newLine) { + if (attributes.isEmpty()) { + this.writer.print("{ }"); + } else { + this.writer.println("{").indented(writeAll(attributes.entrySet().iterator(), + entry -> writeAttribute(entry.getKey(), entry.getValue()))).print("}"); + } + if (newLine) { + this.writer.println(); + } + } + + private void writeArray(List items, boolean newLine) { + if (items.isEmpty()) { + this.writer.print("[ ]"); + } else { + this.writer.println("[") + .indented(writeAll(items.iterator(), this::writeValue)).print("]"); + } + if (newLine) { + this.writer.println(); + } + } + + private Runnable writeAll(Iterator it, Consumer writer) { + return () -> { + while (it.hasNext()) { + writer.accept(it.next()); + if (it.hasNext()) { + this.writer.println(","); + } else { + this.writer.println(); + } + } + }; + } + + private void writeAttribute(String name, Object value) { + this.writer.print(quote(name) + ": "); + writeValue(value); + } + + @SuppressWarnings("unchecked") + private void writeValue(Object value) { + if (value instanceof Map) { + writeObject((Map) value, false); + } else if (value instanceof List) { + writeArray((List) value, false); + } else if (value instanceof CharSequence) { + this.writer.print(quote(escape((CharSequence) value))); + } else if (value instanceof Boolean) { + this.writer.print(Boolean.toString((Boolean) value)); + } else { + throw new IllegalStateException("unsupported type: " + value.getClass()); + } + } + + private String quote(String name) { + return "\"" + name + "\""; + } + + + private static String escape(CharSequence input) { + StringBuilder builder = new StringBuilder(); + input.chars().forEach(c -> { + if (c == '"') { + builder.append("\\\""); + } else if (c == '\\') { + builder.append("\\\\"); + } else if (c == '\b') { + builder.append("\\b"); + } else if (c == '\f') { + builder.append("\\f"); + } else if (c == '\n') { + builder.append("\\n"); + } else if (c == '\r') { + builder.append("\\r"); + } else if (c == '\t') { + builder.append("\\t"); + } else if (c <= 0x1F) { + builder.append(String.format("\\u%04x", c)); + } else { + builder.append((char) c); + } + }); + return builder.toString(); + } + + + static class IndentingWriter extends Writer { + + private final Writer out; + + private final String singleIndent; + + private int level = 0; + + private String currentIndent = ""; + + private boolean prependIndent = false; + + IndentingWriter(Writer out, String singleIndent) { + this.out = out; + this.singleIndent = singleIndent; + } + + /** + * Write the specified text. + * + * @param string the content to write + */ + public IndentingWriter print(String string) { + write(string.toCharArray(), 0, string.length()); + return this; + } + + /** + * Write the specified text and append a new line. + * + * @param string the content to write + */ + public IndentingWriter println(String string) { + write(string.toCharArray(), 0, string.length()); + return println(); + } + + /** + * Write a new line. + */ + public IndentingWriter println() { + String separator = System.lineSeparator(); + try { + this.out.write(separator.toCharArray(), 0, separator.length()); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + this.prependIndent = true; + return this; + } + + /** + * Increase the indentation level and execute the {@link Runnable}. Decrease the + * indentation level on completion. + * + * @param runnable the code to execute within an extra indentation level + */ + public IndentingWriter indented(Runnable runnable) { + indent(); + runnable.run(); + return outdent(); + } + + /** + * Increase the indentation level. + */ + private IndentingWriter indent() { + this.level++; + return refreshIndent(); + } + + /** + * Decrease the indentation level. + */ + private IndentingWriter outdent() { + this.level--; + return refreshIndent(); + } + + private IndentingWriter refreshIndent() { + int count = Math.max(0, this.level); + StringBuilder str = new StringBuilder(); + for (int i = 0; i < count; i++) { + str.append(this.singleIndent); + } + this.currentIndent = str.toString(); + return this; + } + + @Override + public void write(char[] chars, int offset, int length) { + try { + if (this.prependIndent) { + this.out.write(this.currentIndent.toCharArray(), 0, this.currentIndent.length()); + this.prependIndent = false; + } + this.out.write(chars, offset, length); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + @Override + public void flush() throws IOException { + this.out.flush(); + } + + @Override + public void close() throws IOException { + this.out.close(); + } + + } + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceFinder.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceFinder.java deleted file mode 100644 index 545c427442..0000000000 --- a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceFinder.java +++ /dev/null @@ -1,92 +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.aot.generate; - - -import java.io.File; -import java.net.JarURLConnection; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -public class ClassSourceFinder { - - public Set findClassSet(String packageName) { - packageName = packageName.replace(".", "/"); - try { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - Enumeration resources = classLoader.getResources(packageName); - Set result = new HashSet<>(); - while (resources.hasMoreElements()) { - URL resource = (URL) resources.nextElement(); - if (resource != null) { - String protocol = resource.getProtocol(); - if ("file".equals(protocol)) { - findClassesByFile(packageName, resource.getPath(), result); - } else if ("jar".equals(protocol)) { - JarFile jar = ((JarURLConnection) resource.openConnection()).getJarFile(); - System.out.println("findClassSet jar:" + jar.getName()); - findClassesByJar(packageName, jar, result); - } - } - } - return result; - } catch (Throwable ex) { - throw new RuntimeException(ex); - } - } - - private void findClassesByFile(String packageName, String resource, Set result) { - File directory = new File(resource); - File[] listFiles = directory.listFiles(); - if (listFiles != null) { - for (File file : listFiles) { - if (file.isDirectory()) { - findClassesByFile(packageName, file.getPath(), result); - } else { - String path = file.getPath(); - if (path.endsWith(".class")) { - int packageIndex = path.indexOf(packageName.replace("/", File.separator)); - String classPath = path.substring(packageIndex, path.length() - 6); - result.add(classPath.replace(File.separator, ".")); - } - } - } - } - } - - private static void findClassesByJar(String packageName, JarFile jar, Set classes) { - Enumeration entry = jar.entries(); - JarEntry jarEntry; - String name; - while (entry.hasMoreElements()) { - jarEntry = entry.nextElement(); - name = jarEntry.getName(); - if (name.charAt(0) == '/') { - name = name.substring(1); - } - if (jarEntry.isDirectory() || !name.startsWith(packageName) || !name.endsWith(".class")) { - continue; - } - String className = name.substring(0, name.length() - 6); - classes.add(className.replace("/", ".")); - } - } -} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceScanner.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceScanner.java new file mode 100644 index 0000000000..b3fda54d4a --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ClassSourceScanner.java @@ -0,0 +1,174 @@ +/* + * 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.aot.generate; + + +import org.apache.dubbo.common.extension.Adaptive; +import org.apache.dubbo.common.extension.SPI; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.config.AbstractConfig; +import org.apache.dubbo.rpc.model.FrameworkModel; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * A scanner for processing and filtering specific types of classes + */ +public class ClassSourceScanner extends JarScanner { + + public static final ClassSourceScanner INSTANCE = new ClassSourceScanner(); + + /** + * Filter out the spi classes with adaptive annotations + * from all the class collections that can be loaded. + * @return All spi classes with adaptive annotations + */ + public List> spiClassesWithAdaptive() { + Map> allClasses = getClasses(); + List> spiClasses = new ArrayList<>(allClasses.values()).stream().filter(it -> { + if (null == it) { + return false; + } + Annotation anno = it.getAnnotation(SPI.class); + if (null == anno) { + return false; + } + Optional optional = Arrays.stream(it.getMethods()).filter(it2 -> it2.getAnnotation(Adaptive.class) != null).findAny(); + return optional.isPresent(); + }).collect(Collectors.toList()); + + return spiClasses; + } + + /** + * The required adaptive class. + * For example: LoadBalance$Adaptive.class + * @return adaptive class + */ + public Map> adaptiveClasses() { + List res = spiClassesWithAdaptive().stream().map((c) -> c.getName() + "$Adaptive").collect(Collectors.toList()); + return forNames(res); + } + + /** + * The required configuration class, which is a subclass of AbstractConfig, + * but which excludes abstract classes. + * @return configuration class + */ + public List> configClasses() { + return getClasses().values().stream().filter(c -> AbstractConfig.class.isAssignableFrom(c) && !Modifier.isAbstract(c.getModifiers())).collect(Collectors.toList()); + } + + public Map> distinctSpiExtensionClasses(Set spiResource) { + + Map> extensionClasses = new HashMap<>(); + spiResource.forEach((fileName) -> { + Enumeration resources; + try { + resources = ClassLoader.getSystemResources(fileName); + if (resources != null) { + while (resources.hasMoreElements()) { + extensionClasses.putAll(loadResource(resources.nextElement())); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + + return extensionClasses; + } + + /** + * Beans that need to be injected in advance in different ScopeModels. + * For example, the RouterSnapshotSwitcher that needs to be injected when ClusterScopeModelInitializer executes initializeFrameworkModel + * @return Beans that need to be injected in advance + */ + public List> scopeModelInitializer(){ + List> classes = new ArrayList<>(); + classes.addAll(FrameworkModel.defaultModel().getBeanFactory().getRegisteredClasses()); + classes.addAll(FrameworkModel.defaultModel().defaultApplication().getBeanFactory().getRegisteredClasses()); + classes.addAll(FrameworkModel.defaultModel().defaultApplication().getDefaultModule().getBeanFactory().getRegisteredClasses()); + return classes.stream().distinct().collect(Collectors.toList()); + } + + + private Map> loadResource(URL resourceUrl) { + Map> extensionClasses = new HashMap<>(); + try { + List newContentList = getResourceContent(resourceUrl); + String clazz; + for (String line : newContentList) { + try { + int i = line.indexOf('='); + if (i > 0) { + clazz = line.substring(i + 1).trim(); + } else { + clazz = line; + } + if (StringUtils.isNotEmpty(clazz)) { + extensionClasses.put(clazz, getClasses().get(clazz)); + } + } catch (Throwable t) { + } + } + } catch (Throwable t) { + } + + return extensionClasses; + } + + private List getResourceContent(URL resourceUrl) throws IOException { + List newContentList = new ArrayList<>(); + + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(resourceUrl.openStream(), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + final int ci = line.indexOf('#'); + if (ci >= 0) { + line = line.substring(0, ci); + } + line = line.trim(); + if (line.length() > 0) { + newContentList.add(line); + } + } + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + return newContentList; + } + + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ConditionalDescriber.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ConditionalDescriber.java new file mode 100644 index 0000000000..bf158f0500 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ConditionalDescriber.java @@ -0,0 +1,26 @@ +/* + * 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.aot.generate; + +/** + * A describer that describes the conditions for the configuration to take effect. + */ +public interface ConditionalDescriber { + + String getReachableType(); + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableDescriber.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableDescriber.java new file mode 100644 index 0000000000..3423a50e00 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableDescriber.java @@ -0,0 +1,72 @@ +/* + * 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.aot.generate; + + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * A describer that describes the need for reflection on a {@link Executable}. + */ +public class ExecutableDescriber extends MemberDescriber { + + private final List parameterTypes; + + private final ExecutableMode mode; + + + public ExecutableDescriber(Constructor constructor, ExecutableMode mode) { + this("", Arrays.stream(constructor.getParameterTypes()).map(Class::getName).collect(Collectors.toList()),mode); + } + + public ExecutableDescriber(String name, List parameterTypes, ExecutableMode mode) { + super(name); + this.parameterTypes = parameterTypes; + this.mode = mode; + } + + + public List getParameterTypes() { + return parameterTypes; + } + + public ExecutableMode getMode() { + return mode; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ExecutableDescriber that = (ExecutableDescriber) o; + return Objects.equals(parameterTypes, that.parameterTypes) && mode == that.mode; + } + + @Override + public int hashCode() { + return Objects.hash(parameterTypes, mode); + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java new file mode 100644 index 0000000000..c5ea9bd02a --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.aot.generate; + +import java.lang.reflect.Executable; + +/** + * Represent the need of reflection for a given {@link Executable}. + * + * @author Stephane Nicoll + */ +public enum ExecutableMode { + + /** + * Only retrieving the {@link Executable} and its metadata is required. + */ + INTROSPECT, + + /** + * Full reflection support is required, including the ability to invoke + * the {@link Executable}. + */ + INVOKE; + + /** + * Specify if this mode already includes the specified {@code other} mode. + * @param other the other mode to check + * @return {@code true} if this mode includes the other mode + */ + boolean includes(ExecutableMode other) { + return (other == null || this.ordinal() >= other.ordinal()); + } + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/FieldDescriber.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/FieldDescriber.java new file mode 100644 index 0000000000..d38b8fbe92 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/FieldDescriber.java @@ -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.aot.generate; + +import java.lang.reflect.Field; + +/** + * A describer that describes the need for reflection on a {@link Field}. + */ +public class FieldDescriber extends MemberDescriber { + protected FieldDescriber(String name) { + super(name); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/JarScanner.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/JarScanner.java new file mode 100644 index 0000000000..e39da4818c --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/JarScanner.java @@ -0,0 +1,146 @@ +/* + * 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.aot.generate; + +import java.io.File; +import java.net.JarURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * A scanner that scan the dependent jar packages + * to obtain the classes source and resources in them. + */ +public class JarScanner { + + private static final String PACKAGE_NAME_PREFIX = "org/apache/dubbo"; + + private final Map classNameCache; + + private Map> classesCache; + + private final List resourcePathCache; + + + protected Map> getClasses() { + if (classesCache == null || classesCache.size() == 0) { + this.classesCache = forNames(classNameCache.values()); + } + return classesCache; + } + + public JarScanner() { + classNameCache = new HashMap<>(); + resourcePathCache = new ArrayList<>(); + scanURL(PACKAGE_NAME_PREFIX); + } + + protected Map> forNames(Collection classNames) { + Map> classes = new HashMap<>(); + classNames.forEach((it) -> { + try { + Class c = Class.forName(it); + classes.put(it, c); + } catch (Throwable ignored) { + } + }); + return classes; + } + + + private void scanURL(String prefixName) { + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Enumeration resources = classLoader.getResources(prefixName); + while (resources.hasMoreElements()) { + URL resource = resources.nextElement(); + String protocol = resource.getProtocol(); + if ("file".equals(protocol)) { + scanFile(resource.getPath()); + } else if ("jar".equals(protocol)) { + JarFile jar = ((JarURLConnection) resource.openConnection()).getJarFile(); + scanJar(jar); + } + } + } catch (Throwable ex) { + throw new RuntimeException(ex); + } + } + + private void scanFile(String resource) { + File directory = new File(resource); + File[] listFiles = directory.listFiles(); + if (listFiles != null) { + for (File file : listFiles) { + System.out.println("scanFile: " + file.getPath()); + if (file.isDirectory()) { + scanFile(file.getPath()); + } else { + String path = file.getPath(); + if (matchedDubboClasses(path)) { + classNameCache.put(path, toClassName(path)); + } + } + } + } + } + + private void scanJar(JarFile jar) { + Enumeration entry = jar.entries(); + JarEntry jarEntry; + String name; + while (entry.hasMoreElements()) { + jarEntry = entry.nextElement(); + name = jarEntry.getName(); + + if (name.charAt(0) == '/') { + name = name.substring(1); + } + + if (jarEntry.isDirectory()) { + continue; + } + + if (matchedDubboClasses(name)) { + classNameCache.put(name, toClassName(name)); + } else { + resourcePathCache.add(name); + } + + } + } + + protected List getResourcePath() { + return resourcePathCache; + } + + private boolean matchedDubboClasses(String path) { + return path.startsWith(PACKAGE_NAME_PREFIX) && path.endsWith(".class"); + } + + private String toClassName(String path) { + return path.substring(0, path.length() - 6).replace(File.separator, "."); + } + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java new file mode 100644 index 0000000000..7da49da4fb --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java @@ -0,0 +1,125 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed 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 + * + * https://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.aot.generate; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +/** + * Represent predefined {@linkplain Member members} groups. + * + * @author Andy Clement + * @author Sebastien Deleuze + * @author Stephane Nicoll + */ +public enum MemberCategory { + + /** + * A category that represents public {@linkplain Field fields}. + * @see Class#getFields() + */ + PUBLIC_FIELDS, + + /** + * A category that represents {@linkplain Class#getDeclaredFields() declared + * fields}, that is all fields defined by the class, but not inherited ones. + * @see Class#getDeclaredFields() + */ + DECLARED_FIELDS, + + /** + * A category that defines public {@linkplain Constructor constructors} can + * be introspected, but not invoked. + * @see Class#getConstructors() + * @see ExecutableMode#INTROSPECT + */ + INTROSPECT_PUBLIC_CONSTRUCTORS, + + /** + * A category that defines {@linkplain Class#getDeclaredConstructors() all + * constructors} can be introspected, but not invoked. + * @see Class#getDeclaredConstructors() + * @see ExecutableMode#INTROSPECT + */ + INTROSPECT_DECLARED_CONSTRUCTORS, + + /** + * A category that defines public {@linkplain Constructor constructors} can + * be invoked. + * @see Class#getConstructors() + * @see ExecutableMode#INVOKE + */ + INVOKE_PUBLIC_CONSTRUCTORS, + + /** + * A category that defines {@linkplain Class#getDeclaredConstructors() all + * constructors} can be invoked. + * @see Class#getDeclaredConstructors() + * @see ExecutableMode#INVOKE + */ + INVOKE_DECLARED_CONSTRUCTORS, + + /** + * A category that defines public {@linkplain Method methods}, including + * inherited ones can be introspect, but not invoked. + * @see Class#getMethods() + * @see ExecutableMode#INTROSPECT + */ + INTROSPECT_PUBLIC_METHODS, + + /** + * A category that defines {@linkplain Class#getDeclaredMethods() all + * methods}, excluding inherited ones can be introspected, but not invoked. + * @see Class#getDeclaredMethods() + * @see ExecutableMode#INTROSPECT + */ + INTROSPECT_DECLARED_METHODS, + + /** + * A category that defines public {@linkplain Method methods}, including + * inherited ones can be invoked. + * @see Class#getMethods() + * @see ExecutableMode#INVOKE + */ + INVOKE_PUBLIC_METHODS, + + /** + * A category that defines {@linkplain Class#getDeclaredMethods() all + * methods}, excluding inherited ones can be invoked. + * @see Class#getDeclaredMethods() + * @see ExecutableMode#INVOKE + */ + INVOKE_DECLARED_METHODS, + + /** + * A category that represents public {@linkplain Class#getClasses() inner + * classes}. Contrary to other categories, this does not register any + * particular reflection for them but rather make sure they are available + * via a call to {@link Class#getClasses}. + */ + PUBLIC_CLASSES, + + /** + * A category that represents all {@linkplain Class#getDeclaredClasses() + * inner classes}. Contrary to other categories, this does not register any + * particular reflection for them but rather make sure they are available + * via a call to {@link Class#getDeclaredClasses}. + */ + DECLARED_CLASSES; + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberDescriber.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberDescriber.java new file mode 100644 index 0000000000..2e66c3d662 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberDescriber.java @@ -0,0 +1,40 @@ +/* + * 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.aot.generate; + +import java.lang.reflect.Member; + +/** + * Base describer that describes the need for reflection on a {@link Member}. + * + */ +public class MemberDescriber { + + private final String name; + + protected MemberDescriber(String name) { + this.name = name; + } + + /** + * Return the name of the member. + * @return the name + */ + public String getName() { + return this.name; + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/CodeGenerator.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/NativeClassSourceWriter.java similarity index 68% rename from dubbo-native/src/main/java/org/apache/dubbo/aot/generate/CodeGenerator.java rename to dubbo-native/src/main/java/org/apache/dubbo/aot/generate/NativeClassSourceWriter.java index 2e6a68cb97..2e727fc0d1 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/CodeGenerator.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/NativeClassSourceWriter.java @@ -16,54 +16,27 @@ */ package org.apache.dubbo.aot.generate; -import org.apache.dubbo.common.extension.Adaptive; +import org.apache.commons.io.FileUtils; import org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator; import org.apache.dubbo.common.extension.SPI; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.commons.io.FileUtils; - import java.io.File; import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; import java.nio.charset.Charset; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.regex.Matcher; -import java.util.stream.Collectors; /** - * generate related self-adaptive code (native image does not support dynamic code generation. Therefore, code needs to be generated before compilation) + * Write the Adaptive bytecode class dynamically generated. */ -public class CodeGenerator { +public class NativeClassSourceWriter { - private static final String PACKAGE_NAME_PREFIX = "org.apache.dubbo"; + public static final NativeClassSourceWriter INSTANCE = new NativeClassSourceWriter(); - public static void main(String[] args) { - String generatedSources = args[1]; - - List> classes = new ClassSourceFinder().findClassSet(PACKAGE_NAME_PREFIX).stream().map(it -> { - try { - return Class.forName(it); - } catch (Throwable e) { - } - return null; - }).collect(Collectors.toList()); - new ArrayList<>(classes).stream().filter(it -> { - if (null == it) { - return false; - } - Annotation anno = it.getAnnotation(SPI.class); - if (null == anno) { - return false; - } - Optional optional = Arrays.stream(it.getMethods()).filter(it2 -> it2.getAnnotation(Adaptive.class) != null).findAny(); - return optional.isPresent(); - }).forEach(it -> { + public void writeTo(List> classes, String generatedSources) { + classes.forEach(it -> { SPI spi = it.getAnnotation(SPI.class); String value = spi.value(); if (StringUtils.isEmpty(value)) { @@ -76,14 +49,14 @@ public class CodeGenerator { String dir = Paths.get(file).getParent().toString(); FileUtils.forceMkdir(new File(dir)); code = LICENSED_STR + code + "\n"; - FileUtils.write(new File(file + "$Adaptive.java"), code, Charset.defaultCharset()); + String fileName = file + "$Adaptive.java"; + FileUtils.write(new File(fileName), code, Charset.defaultCharset()); } catch (IOException e) { throw new IllegalStateException("Failed to generated adaptive class sources", e); } }); } - private static final String LICENSED_STR = "/*\n" + " * Licensed to the Apache Software Foundation (ASF) under one or more\n" + " * contributor license agreements. See the NOTICE file distributed with\n" + @@ -100,5 +73,4 @@ public class CodeGenerator { " * See the License for the specific language governing permissions and\n" + " * limitations under the License.\n" + " */\n"; - } diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/NativeConfigurationWriter.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/NativeConfigurationWriter.java new file mode 100644 index 0000000000..86299d02af --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/NativeConfigurationWriter.java @@ -0,0 +1,85 @@ +/* + * 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.aot.generate; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.nio.file.Path; +import java.util.function.Consumer; + +/** + * Write Write configuration metadata information in + * {@link ResourceConfigMetadataRepository} and {@link ReflectConfigMetadataRepository} + * as GraalVM native configuration. + * @see Native Image Build Configuration + */ +public class NativeConfigurationWriter { + + private final Path basePath; + + private final String groupId; + + private final String artifactId; + + public NativeConfigurationWriter(Path basePath, String groupId, String artifactId) { + this.basePath = basePath; + this.groupId = groupId; + this.artifactId = artifactId; + } + + protected void writeTo(String fileName, Consumer writer) { + try { + File file = createIfNecessary(fileName); + try (FileWriter out = new FileWriter(file)) { + writer.accept(createJsonWriter(out)); + } + } + catch (IOException ex) { + throw new IllegalStateException("Failed to write native configuration for " + fileName, ex); + } + } + + private File createIfNecessary(String filename) throws IOException { + Path outputDirectory = this.basePath.resolve("META-INF").resolve("native-image"); + if (this.groupId != null && this.artifactId != null) { + outputDirectory = outputDirectory.resolve(this.groupId).resolve(this.artifactId); + } + outputDirectory.toFile().mkdirs(); + File file = outputDirectory.resolve(filename).toFile(); + file.createNewFile(); + return file; + } + + + public void writeReflectionConfig(ReflectConfigMetadataRepository repository) { + writeTo("reflect-config.json", writer -> + ReflectionConfigWriter.INSTANCE.write(writer, repository)); + } + + public void writeResourceConfig(ResourceConfigMetadataRepository repository) { + writeTo("resource-config.json", writer -> + ResourceConfigWriter.INSTANCE.write(writer, repository)); + } + + private BasicJsonWriter createJsonWriter(Writer out) { + return new BasicJsonWriter(out); + } + + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java new file mode 100644 index 0000000000..cfc4aac7a6 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java @@ -0,0 +1,66 @@ +/* + * 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.aot.generate; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.apache.dubbo.aot.generate.ExecutableMode.INVOKE; + +public class ReflectConfigMetadataRepository { + + List types; + + public ReflectConfigMetadataRepository() { + this.types = new ArrayList<>(); + } + + public ReflectConfigMetadataRepository registerSpiExtensionType(List> classes) { + types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + return this; + } + + public ReflectConfigMetadataRepository registerAdaptiveType(List> classes) { + types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + return this; + } + + public ReflectConfigMetadataRepository registerBeanType(List> classes) { + types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + return this; + } + + public ReflectConfigMetadataRepository registerConfigType(List> classes) { + types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + return this; + } + + private TypeDescriber buildTypeDescriberWithConstructor(Class c) { + Set constructors = Arrays.stream(c.getConstructors()).map((constructor) -> new ExecutableDescriber(constructor, INVOKE)).collect(Collectors.toSet()); + Set memberCategories = new HashSet<>(); + memberCategories.add(MemberCategory.INVOKE_PUBLIC_METHODS); + return new TypeDescriber(c.getName(), null, new HashSet<>(), constructors, new HashSet<>(), memberCategories); + } + + public List getTypes() { + return types; + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectionConfigWriter.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectionConfigWriter.java new file mode 100644 index 0000000000..16ad5cb211 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectionConfigWriter.java @@ -0,0 +1,134 @@ +/* + * 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.aot.generate; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Write {@link ReflectConfigMetadataRepository} to the JSON output expected by the GraalVM + * {@code native-image} compiler, typically named {@code reflect-config.json} + * or {@code jni-config.json}. + */ +public class ReflectionConfigWriter { + + public static final ReflectionConfigWriter INSTANCE = new ReflectionConfigWriter(); + + public void write(BasicJsonWriter writer, ReflectConfigMetadataRepository repository) { + writer.writeArray(repository.getTypes().stream().map(this::toAttributes).collect(Collectors.toList())); + } + + private Map toAttributes(TypeDescriber describer) { + Map attributes = new LinkedHashMap<>(); + attributes.put("name", describer.getName()); + handleCondition(attributes, describer); + handleCategories(attributes, describer.getMemberCategories()); + handleFields(attributes, describer.getFields()); + handleExecutables(attributes, describer.getConstructors()); + handleExecutables(attributes, describer.getMethods()); + return attributes; + } + + private void handleCondition(Map attributes, TypeDescriber describer) { + if (describer.getReachableType() != null) { + Map conditionAttributes = new LinkedHashMap<>(); + conditionAttributes.put("typeReachable", describer.getReachableType()); + attributes.put("condition", conditionAttributes); + } + } + + private void handleFields(Map attributes, Set fieldDescribers) { + addIfNotEmpty(attributes, "fields", fieldDescribers.stream().map(this::toAttributes).collect(Collectors.toList())); + } + + private Map toAttributes(FieldDescriber describer) { + Map attributes = new LinkedHashMap<>(); + attributes.put("name", describer.getName()); + return attributes; + } + + private void handleExecutables(Map attributes, Set executableDescribers) { + addIfNotEmpty(attributes, "methods", executableDescribers.stream() + .filter(h -> h.getMode().equals(ExecutableMode.INVOKE)) + .map(this::toAttributes).collect(Collectors.toList())); + addIfNotEmpty(attributes, "queriedMethods", executableDescribers.stream() + .filter(h -> h.getMode().equals(ExecutableMode.INTROSPECT)) + .map(this::toAttributes).collect(Collectors.toList())); + } + + private Map toAttributes(ExecutableDescriber describer) { + Map attributes = new LinkedHashMap<>(); + attributes.put("name", describer.getName()); + attributes.put("parameterTypes", describer.getParameterTypes()); + return attributes; + } + + private void handleCategories(Map attributes, Set categories) { + categories.forEach(category -> { + switch (category) { + case PUBLIC_FIELDS: + attributes.put("allPublicFields", true); + break; + case DECLARED_FIELDS: + attributes.put("allDeclaredFields", true); + break; + case INTROSPECT_PUBLIC_CONSTRUCTORS: + attributes.put("queryAllPublicConstructors", true); + break; + case INTROSPECT_DECLARED_CONSTRUCTORS: + attributes.put("queryAllDeclaredConstructors", true); + break; + case INVOKE_PUBLIC_CONSTRUCTORS: + attributes.put("allPublicConstructors", true); + break; + case INVOKE_DECLARED_CONSTRUCTORS: + attributes.put("allDeclaredConstructors", true); + break; + case INTROSPECT_PUBLIC_METHODS: + attributes.put("queryAllPublicMethods", true); + break; + case INTROSPECT_DECLARED_METHODS: + attributes.put("queryAllDeclaredMethods", true); + break; + case INVOKE_PUBLIC_METHODS: + attributes.put("allPublicMethods", true); + break; + case INVOKE_DECLARED_METHODS: + attributes.put("allDeclaredMethods", true); + break; + case PUBLIC_CLASSES: + attributes.put("allPublicClasses", true); + break; + case DECLARED_CLASSES: + attributes.put("allDeclaredClasses", true); + break; + default: + break; + } + } + ); + } + + private void addIfNotEmpty(Map attributes, String name, Object value) { + if ((value instanceof Collection && ((Collection) value).size() != 0)) { + attributes.put(name, value); + } + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceBundleDescriber.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceBundleDescriber.java new file mode 100644 index 0000000000..35fab65e49 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceBundleDescriber.java @@ -0,0 +1,70 @@ +/* + * 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.aot.generate; + +import java.util.List; +import java.util.Objects; +import java.util.ResourceBundle; + +/** + * A describer that describes the need to access a {@link ResourceBundle}. + */ +public class ResourceBundleDescriber implements ConditionalDescriber { + + private final String name; + + private final List locales; + + private final String reachableType; + + + public ResourceBundleDescriber(String name, List locales, String reachableType) { + this.name = name; + this.locales = locales; + this.reachableType = reachableType; + } + + public String getName() { + return name; + } + + public List getLocales() { + return locales; + } + + @Override + public String getReachableType() { + return reachableType; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ResourceBundleDescriber that = (ResourceBundleDescriber) o; + return name.equals(that.name) && locales.equals(that.locales) && reachableType.equals(that.reachableType); + } + + @Override + public int hashCode() { + return Objects.hash(name, locales, reachableType); + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigMetadataRepository.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigMetadataRepository.java new file mode 100644 index 0000000000..372d6c40ba --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigMetadataRepository.java @@ -0,0 +1,72 @@ +/* + * 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.aot.generate; + + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +public class ResourceConfigMetadataRepository { + + private final List includes; + + private final List excludes; + + private final Set resourceBundles; + + public ResourceConfigMetadataRepository() { + this.includes = new ArrayList<>(); + this.excludes = new ArrayList<>(); + this.resourceBundles = new LinkedHashSet<>(); + } + + public ResourceConfigMetadataRepository registerIncludesPatterns(String... patterns) { + for (String pattern : patterns) { + registerIncludesPattern(new ResourcePatternDescriber(pattern,null)); + } + return this; + } + + public ResourceConfigMetadataRepository registerIncludesPattern(ResourcePatternDescriber describer) { + this.includes.add(describer); + return this; + } + + public ResourceConfigMetadataRepository registerExcludesPattern(ResourcePatternDescriber describer) { + this.excludes.add(describer); + return this; + } + + public ResourceConfigMetadataRepository registerBundles(ResourceBundleDescriber describer) { + this.resourceBundles.add(describer); + return this; + } + + public List getIncludes() { + return includes; + } + + public List getExcludes() { + return excludes; + } + + public Set getResourceBundles() { + return resourceBundles; + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigWriter.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigWriter.java new file mode 100644 index 0000000000..6d1b551dd6 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceConfigWriter.java @@ -0,0 +1,87 @@ +/* + * 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.aot.generate; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Write a {@link ResourceConfigMetadataRepository} to the JSON output expected by the GraalVM + * {@code native-image} compiler, typically named {@code resource-config.json}. + */ +public class ResourceConfigWriter { + + public static final ResourceConfigWriter INSTANCE = new ResourceConfigWriter(); + + public void write(BasicJsonWriter writer, ResourceConfigMetadataRepository repository) { + Map attributes = new LinkedHashMap<>(); + addIfNotEmpty(attributes, "resources", toAttributes(repository.getIncludes(), repository.getExcludes())); + handleResourceBundles(attributes, repository.getResourceBundles()); + writer.writeObject(attributes); + } + + private Map toAttributes(List includes, List excludes) { + Map attributes = new LinkedHashMap<>(); + addIfNotEmpty(attributes, "includes", includes.stream().distinct().map(this::toAttributes).collect(Collectors.toList())); + addIfNotEmpty(attributes, "excludes", excludes.stream().distinct().map(this::toAttributes).collect(Collectors.toList())); + return attributes; + } + + private void handleResourceBundles(Map attributes, Set resourceBundleDescribers) { + addIfNotEmpty(attributes, "bundles", resourceBundleDescribers.stream().map(this::toAttributes).collect(Collectors.toList())); + } + + private Map toAttributes(ResourceBundleDescriber describer) { + Map attributes = new LinkedHashMap<>(); + handleCondition(attributes, describer); + attributes.put("name", describer.getName()); + return attributes; + } + + private Map toAttributes(ResourcePatternDescriber describer) { + Map attributes = new LinkedHashMap<>(); + handleCondition(attributes, describer); + attributes.put("pattern", describer.toRegex().toString()); + return attributes; + } + + private void addIfNotEmpty(Map attributes, String name, Object value) { + if (value instanceof Collection) { + if (!((Collection) value).isEmpty()) { + attributes.put(name, value); + } + } else if (value instanceof Map) { + if (!((Map) value).isEmpty()) { + attributes.put(name, value); + } + } else if (value != null) { + attributes.put(name, value); + } + } + + private void handleCondition(Map attributes, ConditionalDescriber conditionalDescriber) { + if (conditionalDescriber.getReachableType() != null) { + Map conditionAttributes = new LinkedHashMap<>(); + conditionAttributes.put("typeReachable", conditionalDescriber.getReachableType()); + attributes.put("condition", conditionAttributes); + } + } +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourcePatternDescriber.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourcePatternDescriber.java new file mode 100644 index 0000000000..1e557c7330 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourcePatternDescriber.java @@ -0,0 +1,58 @@ +/* + * 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.aot.generate; + +import java.util.Arrays; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * A describer that describes resources that should be made available at runtime. + */ +public class ResourcePatternDescriber implements ConditionalDescriber { + + private final String pattern; + + private final String reachableType; + + public ResourcePatternDescriber(String pattern, String reachableType) { + this.pattern = pattern; + this.reachableType = reachableType; + } + + public String getPattern() { + return pattern; + } + + @Override + public String getReachableType() { + return reachableType; + } + + public Pattern toRegex() { + String prefix = (this.pattern.startsWith("*") ? ".*" : ""); + String suffix = (this.pattern.endsWith("*") ? ".*" : ""); + String regex = Arrays.stream(this.pattern.split("\\*")) + .filter(s -> !s.isEmpty()) + .map(Pattern::quote) + .collect(Collectors.joining(".*", prefix, suffix)); + return Pattern.compile(regex); + } + + + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceScanner.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceScanner.java new file mode 100644 index 0000000000..a2191caf48 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ResourceScanner.java @@ -0,0 +1,57 @@ +/* + * 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.aot.generate; + + +import java.util.Set; +import java.util.stream.Collectors; + +/** + * A scanner for processing and filtering specific resource. + */ +public class ResourceScanner extends JarScanner { + + private static final String DUBBO_INTERNAL_RESOURCE_DIRECTORY = "META-INF/dubbo/internal/"; + + private static final String DUBBO_RESOURCE_DIRECTORY = "META-INF/dubbo/"; + + private static final String SERVICES_RESOURCE_DIRECTORY = "META-INF/services/"; + + private static final String SECURITY_RESOURCE_DIRECTORY = "security/"; + + public static final ResourceScanner INSTANCE = new ResourceScanner(); + + public Set distinctSpiResource() { + return getResourcePath().stream().distinct().filter(this::matchedSpiResource).collect(Collectors.toSet()); + } + + public Set distinctSecurityResource() { + return getResourcePath().stream().distinct().filter(this::matchedSecurityResource).collect(Collectors.toSet()); + } + + private boolean matchedSecurityResource(String path) { + return path.startsWith(SECURITY_RESOURCE_DIRECTORY); + } + + private boolean matchedSpiResource(String path) { + return path.startsWith(DUBBO_INTERNAL_RESOURCE_DIRECTORY) + || path.startsWith(DUBBO_RESOURCE_DIRECTORY) + || path.startsWith(SERVICES_RESOURCE_DIRECTORY); + } + + +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/TypeDescriber.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/TypeDescriber.java new file mode 100644 index 0000000000..a41f0bb2b8 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/TypeDescriber.java @@ -0,0 +1,74 @@ +/* + * 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.aot.generate; + +import java.util.Set; + +/** + * A describer that describes the need for reflection on a type. + */ +public class TypeDescriber implements ConditionalDescriber { + + private final String name; + + private final String reachableType; + + private final Set fields; + + private final Set constructors; + + private final Set methods; + + private final Set memberCategories; + + public TypeDescriber(String name, String reachableType, Set fields, + Set constructors, Set methods, + Set memberCategories) { + this.name = name; + this.reachableType = reachableType; + this.fields = fields; + this.constructors = constructors; + this.methods = methods; + this.memberCategories = memberCategories; + } + + + public String getName() { + return name; + } + + public Set getMemberCategories() { + return memberCategories; + } + + public Set getFields() { + return fields; + } + + public Set getConstructors() { + return constructors; + } + + public Set getMethods() { + return methods; + } + + @Override + public String getReachableType() { + return reachableType; + } +} diff --git a/dubbo-native/src/test/java/org/apache/dubbo/aot/generate/ResourcePatternDescriberTest.java b/dubbo-native/src/test/java/org/apache/dubbo/aot/generate/ResourcePatternDescriberTest.java new file mode 100644 index 0000000000..dd4e489efc --- /dev/null +++ b/dubbo-native/src/test/java/org/apache/dubbo/aot/generate/ResourcePatternDescriberTest.java @@ -0,0 +1,28 @@ +/* + * 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.aot.generate; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ResourcePatternDescriberTest { + @Test + public void testToRegex() { + ResourcePatternDescriber describer = new ResourcePatternDescriber("META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector", null); + Assertions.assertEquals("\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector\\E",describer.toRegex().toString()); + } +} diff --git a/pom.xml b/pom.xml index 60f7de473b..1701cf0038 100644 --- a/pom.xml +++ b/pom.xml @@ -334,6 +334,9 @@ **/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java, **/org/apache/dubbo/maven/plugin/aot/RunArguments.java, **/org/apache/dubbo/maven/plugin/aot/RunProcess.java, + **/org/apache/dubbo/aot/generate/BasicJsonWriter.java, + **/org/apache/dubbo/aot/generate/ExecutableMode.java, + **/org/apache/dubbo/aot/generate/MemberCategory.java, **/org/apache/dubbo/common/threadpool/serial/SerializingExecutor.java, **/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java, **/org/apache/dubbo/common/threadlocal/InternalThreadLocalMap.java, From eeab34eb6780a332ead4d48c9b9932e07effd3e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:19:38 +0800 Subject: [PATCH 114/144] Bump bytebuddy.version from 1.14.1 to 1.14.2 (#11814) Bumps `bytebuddy.version` from 1.14.1 to 1.14.2. Updates `byte-buddy` from 1.14.1 to 1.14.2 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.1...byte-buddy-1.14.2) Updates `byte-buddy-agent` from 1.14.1 to 1.14.2 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.1...byte-buddy-1.14.2) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: net.bytebuddy:byte-buddy-agent dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-spring-boot/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml index bd4e0035a2..8eebf37be6 100644 --- a/dubbo-spring-boot/pom.xml +++ b/dubbo-spring-boot/pom.xml @@ -45,7 +45,7 @@ 2.20.0 - 1.14.1 + 1.14.2 From 96dfd20c108550cf563aec317911195ae8c31cb4 Mon Sep 17 00:00:00 2001 From: earthchen Date: Wed, 15 Mar 2023 13:14:22 +0800 Subject: [PATCH 115/144] Reactor tri diy exception api (#11829) * refactor * fix --- .../dubbo/rpc/model/PackableMethod.java | 5 +++++ .../tri/ReflectionPackableMethod.java | 12 +++++++++-- .../protocol/tri/call/AbstractServerCall.java | 20 +++++++++---------- .../tri/call/AbstractServerCallListener.java | 7 ++++++- .../tri/call/UnaryServerCallListener.java | 13 +++++++++++- 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/PackableMethod.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/PackableMethod.java index 779e969d4f..86bd18ad07 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/PackableMethod.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/PackableMethod.java @@ -62,6 +62,11 @@ public interface PackableMethod { return getResponsePack().pack(response); } + + default boolean needWrapper() { + return false; + } + Pack getRequestPack(); Pack getResponsePack(); diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java index 989b7017c4..5316fc5452 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java @@ -53,6 +53,13 @@ public class ReflectionPackableMethod implements PackableMethod { private final UnPack requestUnpack; private final UnPack responseUnpack; + private final boolean needWrapper; + + @Override + public boolean needWrapper() { + return this.needWrapper; + } + public ReflectionPackableMethod(MethodDescriptor method, URL url, String serializeName) { Class[] actualRequestTypes; Class actualResponseType; @@ -79,7 +86,8 @@ public class ReflectionPackableMethod implements PackableMethod { } boolean singleArgument = method.getRpcType() != MethodDescriptor.RpcType.UNARY; - if (!needWrap(method, actualRequestTypes, actualResponseType)) { + this.needWrapper = needWrap(method, actualRequestTypes, actualResponseType); + if (!needWrapper) { requestPack = new PbArrayPacker(singleArgument); responsePack = PB_PACK; requestUnpack = new PbUnpack<>(actualRequestTypes[0]); @@ -336,7 +344,6 @@ public class ReflectionPackableMethod implements PackableMethod { private final URL url; private final Class returnClass; - private WrapResponseUnpack(MultipleSerialization serialization, URL url, Class returnClass) { this.serialization = serialization; this.url = url; @@ -362,6 +369,7 @@ public class ReflectionPackableMethod implements PackableMethod { private final URL url; private final boolean singleArgument; + private WrapRequestPack(MultipleSerialization multipleSerialization, URL url, String serialize, diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java index 7780579a69..01ea3a1e79 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java @@ -80,13 +80,13 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis protected Map requestMetadata; AbstractServerCall(Invoker invoker, - ServerStream stream, - FrameworkModel frameworkModel, - ServiceDescriptor serviceDescriptor, - String acceptEncoding, - String serviceName, - String methodName, - Executor executor + ServerStream stream, + FrameworkModel frameworkModel, + ServiceDescriptor serviceDescriptor, + String acceptEncoding, + String serviceName, + String methodName, + Executor executor ) { Objects.requireNonNull(serviceDescriptor, "No service descriptor found for " + invoker.getUrl()); @@ -146,7 +146,7 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis } catch (Exception e) { close(TriRpcStatus.INTERNAL.withDescription("Serialize response failed") .withCause(e), null); - LOGGER.error(PROTOCOL_FAILED_SERIALIZE_TRIPLE,"","",String.format("Serialize triple response failed, service=%s method=%s", + LOGGER.error(PROTOCOL_FAILED_SERIALIZE_TRIPLE, "", "", String.format("Serialize triple response failed, service=%s method=%s", serviceName, methodName), e); return; } @@ -192,7 +192,7 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis final TriRpcStatus status = TriRpcStatus.UNKNOWN.withDescription("Server error") .withCause(e); close(status, null); - LOGGER.error(PROTOCOL_FAILED_REQUEST,"","","Process request failed. service=" + serviceName + + LOGGER.error(PROTOCOL_FAILED_REQUEST, "", "", "Process request failed. service=" + serviceName + " method=" + methodName, e); } finally { ClassLoadUtil.switchContextLoader(tccl); @@ -373,7 +373,7 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis ServerCall.Listener listener; switch (methodDescriptor.getRpcType()) { case UNARY: - listener = new UnaryServerCallListener(invocation, invoker, responseObserver); + listener = new UnaryServerCallListener(invocation, invoker, responseObserver, packableMethod.needWrapper()); request(2); break; case SERVER_STREAM: diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java index 3bfb57f891..f645a80468 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java @@ -70,7 +70,7 @@ public abstract class AbstractServerCallListener implements AbstractServerCall.L return; } if (response.hasException()) { - onReturn(response.getException()); + doOnResponseHasException(response.getException()); return; } final long cost = System.currentTimeMillis() - stInMillis; @@ -93,5 +93,10 @@ public abstract class AbstractServerCallListener implements AbstractServerCall.L } } + + protected void doOnResponseHasException(Throwable t) { + responseObserver.onError(t); + } + public abstract void onReturn(Object value); } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/UnaryServerCallListener.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/UnaryServerCallListener.java index 92d5398120..08f761a600 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/UnaryServerCallListener.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/UnaryServerCallListener.java @@ -24,9 +24,12 @@ import org.apache.dubbo.rpc.protocol.tri.observer.ServerCallToObserverAdapter; public class UnaryServerCallListener extends AbstractServerCallListener { + private final boolean needWrapper; + public UnaryServerCallListener(RpcInvocation invocation, Invoker invoker, - ServerCallToObserverAdapter responseObserver) { + ServerCallToObserverAdapter responseObserver, boolean needWrapper) { super(invocation, invoker, responseObserver); + this.needWrapper = needWrapper; } @Override @@ -49,6 +52,14 @@ public class UnaryServerCallListener extends AbstractServerCallListener { // ignored } + @Override + protected void doOnResponseHasException(Throwable t) { + if (needWrapper) { + onReturn(t); + } else { + super.doOnResponseHasException(t); + } + } @Override public void onComplete() { From df0241b6dde0463517be3f5fd6968ea0a2dd9cf0 Mon Sep 17 00:00:00 2001 From: icodening Date: Wed, 15 Mar 2023 14:03:44 +0800 Subject: [PATCH 116/144] fix npe (#11830) * fix npe * fix npe --- .../dubbo/rpc/protocol/tri/call/AbstractServerCall.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java index 01ea3a1e79..c385f46bd1 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCall.java @@ -178,6 +178,11 @@ public abstract class AbstractServerCall implements ServerCall, ServerStream.Lis // It will enter here when there is an error in the header return; } + //Both 'onError' and 'onComplete' are termination operators. + // The stream will be closed when 'onError' was called, and 'onComplete' is not allowed to be called again. + if (isClosed()) { + return; + } listener.onComplete(); } From 8b063766c92d859c58dfc0da3c0a160cb41ef992 Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:42:13 +0800 Subject: [PATCH 117/144] gc bug fix (#11842) Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../metrics/metadata/collector/stat/MetadataStatComposite.java | 2 +- .../metrics/registry/collector/stat/RegistryStatComposite.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java index bfb4b07c7e..e26f98d727 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/stat/MetadataStatComposite.java @@ -113,7 +113,7 @@ public class MetadataStatComposite implements MetricsExport { for (LongContainer rtContainer : rtStats) { MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); for (Map.Entry entry : rtContainer.entrySet()) { - list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, entry, value -> rtContainer.getValueSupplier().apply(value.getKey()))); + list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, entry.getKey().intern(), value -> rtContainer.getValueSupplier().apply(value.intern()))); } } return list; diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java index 3f97210876..9bfa2532e5 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java @@ -130,7 +130,7 @@ public class RegistryStatComposite implements MetricsExport { for (LongContainer rtContainer : rtStats) { MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); for (Map.Entry entry : rtContainer.entrySet()) { - list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, entry, value -> rtContainer.getValueSupplier().apply(value.getKey()))); + list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, entry.getKey().intern(), value -> rtContainer.getValueSupplier().apply(value.intern()))); } } return list; From c0574962ecf48cf7331daf7d3ce43027300ca14e Mon Sep 17 00:00:00 2001 From: huazhongming Date: Thu, 16 Mar 2023 09:42:33 +0800 Subject: [PATCH 118/144] fix npe in the native compilation phase (#11837) Signed-off-by: crazyhzm --- .../aot/generate/ReflectConfigMetadataRepository.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java index cfc4aac7a6..1a22d35e33 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ReflectConfigMetadataRepository.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -34,22 +35,22 @@ public class ReflectConfigMetadataRepository { } public ReflectConfigMetadataRepository registerSpiExtensionType(List> classes) { - types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + types.addAll(classes.stream().filter(Objects::nonNull).map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); return this; } public ReflectConfigMetadataRepository registerAdaptiveType(List> classes) { - types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + types.addAll(classes.stream().filter(Objects::nonNull).map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); return this; } public ReflectConfigMetadataRepository registerBeanType(List> classes) { - types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + types.addAll(classes.stream().filter(Objects::nonNull).map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); return this; } public ReflectConfigMetadataRepository registerConfigType(List> classes) { - types.addAll(classes.stream().map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); + types.addAll(classes.stream().filter(Objects::nonNull).map(this::buildTypeDescriberWithConstructor).collect(Collectors.toList())); return this; } From a9bff0d6e951c3ebcbcb8e14fb3efcc2d59f1ba7 Mon Sep 17 00:00:00 2001 From: xiaohuashengpeanut <125560790+xiaohuashengpeanut@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:43:02 +0800 Subject: [PATCH 119/144] add commit id metrics (#11843) * add commit id metrics * reslove * problem --------- Co-authored-by: PEANUT --- .../org/apache/dubbo/metrics/model/ApplicationMetric.java | 6 ++++-- .../java/org/apache/dubbo/metrics/model/MetricsKey.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java index ff23c7d8b0..b0e583806f 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java @@ -22,16 +22,17 @@ import org.apache.dubbo.common.Version; import java.util.HashMap; import java.util.Map; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; -import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_VERSION_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_VERSION_KEY; import static org.apache.dubbo.common.utils.NetUtils.getLocalHost; import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName; public class ApplicationMetric implements Metric { private final String applicationName; private static final String version = Version.getVersion(); + private static final String commitId = Version.getLastCommitId(); public ApplicationMetric(String applicationName) { this.applicationName = applicationName; @@ -56,6 +57,7 @@ public class ApplicationMetric implements Metric { tags.put(TAG_HOSTNAME, getLocalHostName()); tags.put(TAG_APPLICATION_NAME, applicationName); tags.put(TAG_APPLICATION_VERSION_KEY, version); + tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId); return tags; } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java index 86b2c873c9..8fe6d1a96e 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java @@ -91,7 +91,7 @@ public enum MetricsKey { METADATA_SUBSCRIBE_METRIC_NUM("dubbo.metadata.subscribe.num.total", "Total Metadata Subscribe Num"), METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.metadata.subscribe.num.succeed.total", "Succeed Metadata Subscribe Num"), METADATA_SUBSCRIBE_METRIC_NUM_FAILED("dubbo.metadata.subscribe.num.failed.total", "Failed Metadata Subscribe Num"), - + METADATA_GIT_COMMITID_METRIC("git.commit.id","Git Commit Id Metrics"); // consumer metrics key ; From d061b29b390eba6c6e73d61496cf2e78badeb429 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 16 Mar 2023 09:43:57 +0800 Subject: [PATCH 120/144] Some code optimization (#11825) * Code optimization * Code optimization: modifier optimization, condition simplification, etc. * Fix CI error * Fix CI error --- .../configurator/AbstractConfigurator.java | 12 +++++------ .../DefaultGovernanceRuleRepositoryImpl.java | 2 +- .../loadbalance/AdaptiveLoadBalance.java | 2 +- .../loadbalance/RandomLoadBalance.java | 4 ++-- .../loadbalance/RoundRobinLoadBalance.java | 4 ++-- .../ShortestResponseLoadBalance.java | 6 +++--- .../config/AppStateRouterFactory.java | 2 ++ .../config/ListenableStateRouter.java | 2 +- .../config/ProviderAppStateRouter.java | 2 +- .../support/AbstractClusterInvoker.java | 2 +- .../support/wrapper/AbstractCluster.java | 9 ++++---- .../config/context/AbstractConfigManager.java | 2 +- .../context/ConfigConfigurationAdapter.java | 2 +- .../dubbo/config/context/ConfigManager.java | 4 +--- .../config/context/ModuleConfigManager.java | 2 +- .../definition/TypeDefinitionBuilder.java | 2 +- .../rpc/model/FrameworkServiceRepository.java | 11 +++++----- .../dubbo/rpc/model/ServiceRepository.java | 6 +++--- .../apache/dubbo/gen/AbstractGenerator.java | 21 +++++++------------ .../config/bootstrap/DubboBootstrap.java | 12 +++++------ .../DelegateProviderMetaDataInvoker.java | 2 +- ...ConfigurableSourceBeanMetadataElement.java | 2 +- .../DubboConfigApplicationListener.java | 2 +- .../context/DubboConfigBeanInitializer.java | 2 +- .../context/DubboSpringInitContext.java | 2 +- .../DubboSpringInitCustomizerHolder.java | 3 +-- .../context/DubboSpringInitializer.java | 2 +- .../event/DubboApplicationStateEvent.java | 2 +- .../nacos/NacosConfigServiceWrapper.java | 2 +- .../nacos/NacosDynamicConfiguration.java | 4 ++-- .../support/zookeeper/CacheListener.java | 2 +- .../zookeeper/ZookeeperDataListener.java | 8 +++---- .../ZookeeperDynamicConfiguration.java | 4 ++-- .../ZookeeperDynamicConfigurationFactory.java | 5 +---- .../cache/support/expiring/ExpiringMap.java | 4 ++-- .../dubbo/cache/support/lfu/LfuCache.java | 4 ++++ .../support/jvalidation/JValidator.java | 6 +++--- .../support/jvalidation/JValidatorNew.java | 8 +++---- .../dubbo/auth/AccessKeyAuthenticator.java | 2 +- .../dubbo/auth/filter/ConsumerSignFilter.java | 2 +- .../dubbo/auth/filter/ProviderAuthFilter.java | 2 +- .../dubbo/qos/command/impl/BaseOffline.java | 2 +- .../dubbo/qos/command/impl/ChangeTelnet.java | 2 +- .../dubbo/qos/command/impl/CountTelnet.java | 2 +- .../qos/command/impl/GetRouterSnapshot.java | 2 +- .../apache/dubbo/qos/command/impl/Help.java | 6 +++--- .../dubbo/qos/command/impl/InvokeTelnet.java | 2 +- .../org/apache/dubbo/qos/command/impl/Ls.java | 2 +- .../dubbo/qos/command/impl/PortTelnet.java | 2 +- .../qos/command/impl/ShutdownTelnet.java | 2 +- .../dubbo/qos/command/impl/Startup.java | 2 +- .../dubbo/qos/command/util/CommandHelper.java | 2 +- .../probe/impl/ProviderReadinessProbe.java | 4 ++-- .../qos/protocol/QosProtocolWrapper.java | 4 ++-- .../handler/ForeignHostPermitHandler.java | 2 +- .../security/jackson/ObjectMapperCodec.java | 2 +- 56 files changed, 104 insertions(+), 113 deletions(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java index 56c35c8965..55ebed253c 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/AbstractConfigurator.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.cluster.configurator; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.NetUtils; @@ -155,12 +156,12 @@ public abstract class AbstractConfigurator implements Configurator { String providers = configuratorUrl.getParameter(OVERRIDE_PROVIDERS_KEY); if (StringUtils.isNotEmpty(providers)) { boolean match = false; - String[] providerAddresses = providers.split(","); + String[] providerAddresses = providers.split(CommonConstants.COMMA_SEPARATOR); for (String address : providerAddresses) { if (address.equals(url.getAddress()) || address.equals(ANYHOST_VALUE) - || address.equals(ANYHOST_VALUE + ":" + ANY_VALUE) - || address.equals(ANYHOST_VALUE + ":" + url.getPort()) + || address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + ANY_VALUE) + || address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + url.getPort()) || address.equals(url.getHost())) { match = true; } @@ -228,10 +229,7 @@ public abstract class AbstractConfigurator implements Configurator { } private boolean startWithTilde(String key) { - if (StringUtils.isNotEmpty(key) && key.startsWith(TILDE)) { - return true; - } - return false; + return StringUtils.isNotEmpty(key) && key.startsWith(TILDE); } protected abstract URL doConfigure(URL currentUrl, URL configUrl); diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java index a5f4a3e0b1..6d6770876b 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/governance/DefaultGovernanceRuleRepositoryImpl.java @@ -22,7 +22,7 @@ import org.apache.dubbo.rpc.model.ModuleModel; public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleRepository { - private ModuleModel moduleModel; + private final ModuleModel moduleModel; public DefaultGovernanceRuleRepositoryImpl(ModuleModel moduleModel) { this.moduleModel = moduleModel; diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/AdaptiveLoadBalance.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/AdaptiveLoadBalance.java index 8bf9648300..a406987c97 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/AdaptiveLoadBalance.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/AdaptiveLoadBalance.java @@ -44,7 +44,7 @@ public class AdaptiveLoadBalance extends AbstractLoadBalance { //default key private String attachmentKey = "mem,load"; - private AdaptiveMetrics adaptiveMetrics; + private final AdaptiveMetrics adaptiveMetrics; public AdaptiveLoadBalance(ApplicationModel scopeModel){ adaptiveMetrics = scopeModel.getBeanFactory().getBean(AdaptiveMetrics.class); diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RandomLoadBalance.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RandomLoadBalance.java index f8c2089519..cc06c0d902 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RandomLoadBalance.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RandomLoadBalance.java @@ -61,7 +61,7 @@ public class RandomLoadBalance extends AbstractLoadBalance { // Every invoker has the same weight? boolean sameWeight = true; - // the maxWeight of every invokers, the minWeight = 0 or the maxWeight of the last invoker + // the maxWeight of every invoker, the minWeight = 0 or the maxWeight of the last invoker int[] weights = new int[length]; // The sum of weights int totalWeight = 0; @@ -78,7 +78,7 @@ public class RandomLoadBalance extends AbstractLoadBalance { if (totalWeight > 0 && !sameWeight) { // If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight. int offset = ThreadLocalRandom.current().nextInt(totalWeight); - // Return a invoker based on the random value. + // Return an invoker based on the random value. for (int i = 0; i < length; i++) { if (offset < weights[i]) { return invokers.get(i); diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RoundRobinLoadBalance.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RoundRobinLoadBalance.java index 4d4f7bfbf2..8a24a4af4a 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RoundRobinLoadBalance.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RoundRobinLoadBalance.java @@ -36,11 +36,11 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance { private static final int RECYCLE_PERIOD = 60000; - private ConcurrentMap> methodWeightMap = new ConcurrentHashMap<>(); + private final ConcurrentMap> methodWeightMap = new ConcurrentHashMap<>(); protected static class WeightedRoundRobin { private int weight; - private AtomicLong current = new AtomicLong(0); + private final AtomicLong current = new AtomicLong(0); private long lastUpdate; public int getWeight() { diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/ShortestResponseLoadBalance.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/ShortestResponseLoadBalance.java index 906c49642f..9b9eae5005 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/ShortestResponseLoadBalance.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/ShortestResponseLoadBalance.java @@ -48,9 +48,9 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements private int slidePeriod = 30_000; - private ConcurrentMap methodMap = new ConcurrentHashMap<>(); + private final ConcurrentMap methodMap = new ConcurrentHashMap<>(); - private AtomicBoolean onResetSlideWindow = new AtomicBoolean(false); + private final AtomicBoolean onResetSlideWindow = new AtomicBoolean(false); private volatile long lastUpdateTime = System.currentTimeMillis(); @@ -67,7 +67,7 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements private long succeededOffset; private long succeededElapsedOffset; - private RpcStatus rpcStatus; + private final RpcStatus rpcStatus; public SlideWindowData(RpcStatus rpcStatus) { this.rpcStatus = rpcStatus; diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppStateRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppStateRouterFactory.java index ecfb2220a1..14d05cde10 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppStateRouterFactory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/AppStateRouterFactory.java @@ -29,8 +29,10 @@ import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory; public class AppStateRouterFactory implements StateRouterFactory { public static final String NAME = "app"; + @SuppressWarnings("rawtypes") private volatile StateRouter router; + @SuppressWarnings("unchecked") @Override public StateRouter getRouter(Class interfaceClass, URL url) { if (router != null) { diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java index 3daf71104e..40758c4f3e 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableStateRouter.java @@ -53,7 +53,7 @@ public abstract class ListenableStateRouter extends AbstractStateRouter im private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class); private volatile ConditionRouterRule routerRule; private volatile List> conditionRouters = Collections.emptyList(); - private String ruleKey; + private final String ruleKey; public ListenableStateRouter(URL url, String ruleKey) { super(url); diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java index 470a4daf06..9057ac455a 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ProviderAppStateRouter.java @@ -36,7 +36,7 @@ public class ProviderAppStateRouter extends ListenableStateRouter { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class); public static final String NAME = "PROVIDER_APP_ROUTER"; private String application; - private String currentApplication; + private final String currentApplication; public ProviderAppStateRouter(URL url) { super(url, url.getApplication()); diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java index 3fdd1fbfff..b03447676d 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java @@ -70,7 +70,7 @@ public abstract class AbstractClusterInvoker implements ClusterInvoker { private volatile boolean enableConnectivityValidation = true; - private AtomicBoolean destroyed = new AtomicBoolean(false); + private final AtomicBoolean destroyed = new AtomicBoolean(false); private volatile Invoker stickyInvoker = null; diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/AbstractCluster.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/AbstractCluster.java index 968ef3e2c0..2a19a54e68 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/AbstractCluster.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/AbstractCluster.java @@ -43,7 +43,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER public abstract class AbstractCluster implements Cluster { private Invoker buildClusterInterceptors(AbstractClusterInvoker clusterInvoker) { -// AbstractClusterInvoker last = clusterInvoker; AbstractClusterInvoker last = buildInterceptorInvoker(new ClusterFilterInvoker<>(clusterInvoker)); if (Boolean.parseBoolean(ConfigurationUtils.getProperty(clusterInvoker.getDirectory().getConsumerUrl().getScopeModel(), CLUSTER_INTERCEPTOR_COMPATIBLE_KEY, "false"))) { @@ -72,7 +71,7 @@ public abstract class AbstractCluster implements Cluster { protected abstract AbstractClusterInvoker doJoin(Directory directory) throws RpcException; static class ClusterFilterInvoker extends AbstractClusterInvoker { - private ClusterInvoker filterInvoker; + private final ClusterInvoker filterInvoker; public ClusterFilterInvoker(AbstractClusterInvoker invoker) { List builders = ScopeModelUtil.getApplicationModel(invoker.getUrl().getScopeModel()).getExtensionLoader(FilterChainBuilder.class).getActivateExtensions(); @@ -191,9 +190,9 @@ public abstract class AbstractCluster implements Cluster { @Deprecated static class InterceptorInvokerNode extends AbstractClusterInvoker { - private AbstractClusterInvoker clusterInvoker; - private ClusterInterceptor interceptor; - private AbstractClusterInvoker next; + private final AbstractClusterInvoker clusterInvoker; + private final ClusterInterceptor interceptor; + private final AbstractClusterInvoker next; public InterceptorInvokerNode(AbstractClusterInvoker clusterInvoker, ClusterInterceptor interceptor, diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java index 76bd79672f..ed587a47e5 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java @@ -69,7 +69,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter { private static final String CONFIG_NAME_READ_METHOD = "getName"; private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AbstractConfigManager.class); - private static Set> uniqueConfigTypes = new ConcurrentHashSet<>(); + private static final Set> uniqueConfigTypes = new ConcurrentHashSet<>(); final Map> configsCache = new ConcurrentHashMap<>(); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java index 2b141e8a8b..1197e62817 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java @@ -27,7 +27,7 @@ import java.util.Map; */ public class ConfigConfigurationAdapter implements Configuration { - private Map metaData; + private final Map metaData; public ConfigConfigurationAdapter(AbstractConfig config, String prefix) { if (StringUtils.hasText(prefix)) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java index 0ed0a3aa51..dba0870771 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java @@ -298,9 +298,7 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE // Log the current configurations. logger.info("The current configurations or effective configurations are as follows:"); for (Class configType : multipleConfigTypes) { - getConfigs(configType).stream().forEach((config) -> { - logger.info(config.toString()); - }); + getConfigs(configType).forEach((config) -> logger.info(config.toString())); } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java index 884d060740..72d3e97efc 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java @@ -58,7 +58,7 @@ public class ModuleConfigManager extends AbstractConfigManager implements Module public static final String NAME = "moduleConfig"; - private Map serviceConfigCache = new ConcurrentHashMap<>(); + private final Map serviceConfigCache = new ConcurrentHashMap<>(); private final ConfigManager applicationConfigManager; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java index d3029b0e97..a9f9d2d984 100755 --- a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java @@ -73,7 +73,7 @@ public class TypeDefinitionBuilder { return null; } - private Map typeCache = new HashMap<>(); + private final Map typeCache = new HashMap<>(); public TypeDefinition build(Type type, Class clazz) { return build(type, clazz, typeCache); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkServiceRepository.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkServiceRepository.java index 9f217ccaab..5d8df222e8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkServiceRepository.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkServiceRepository.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.model; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -36,16 +37,16 @@ import static org.apache.dubbo.common.BaseServiceMetadata.versionFromServiceKey; */ public class FrameworkServiceRepository { - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; // useful to find a provider model quickly with group/serviceInterfaceName:version - private ConcurrentMap providers = new ConcurrentHashMap<>(); + private final ConcurrentMap providers = new ConcurrentHashMap<>(); // useful to find a provider model quickly with serviceInterfaceName:version - private ConcurrentMap> providersWithoutGroup = new ConcurrentHashMap<>(); + private final ConcurrentMap> providersWithoutGroup = new ConcurrentHashMap<>(); // useful to find a url quickly with serviceInterfaceName:version - private ConcurrentMap> providerUrlsWithoutGroup = new ConcurrentHashMap<>(); + private final ConcurrentMap> providerUrlsWithoutGroup = new ConcurrentHashMap<>(); public FrameworkServiceRepository(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; @@ -111,7 +112,7 @@ public class FrameworkServiceRepository { if (StringUtils.isEmpty(version)) { return interfaceName; } - return interfaceName + ":" + version; + return interfaceName + CommonConstants.GROUP_CHAR_SEPARATOR + version; } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceRepository.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceRepository.java index 153cedd663..204a5180de 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceRepository.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceRepository.java @@ -28,8 +28,8 @@ public class ServiceRepository { public static final String NAME = "repository"; - private AtomicBoolean inited = new AtomicBoolean(false); - private ApplicationModel applicationModel; + private final AtomicBoolean initialized = new AtomicBoolean(false); + private final ApplicationModel applicationModel; public ServiceRepository(ApplicationModel applicationModel) { this.applicationModel = applicationModel; @@ -37,7 +37,7 @@ public class ServiceRepository { } private void initialize() { - if (inited.compareAndSet(false, true)) { + if (initialized.compareAndSet(false, true)) { Set builtinServices = applicationModel.getExtensionLoader(BuiltinServiceDetector.class).getSupportedExtensionInstances(); if (CollectionUtils.isNotEmpty(builtinServices)) { diff --git a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java index 8d95ecdf87..de9e67bd8c 100644 --- a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java +++ b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java @@ -104,7 +104,7 @@ public abstract class AbstractGenerator extends Generator { } serviceContext.commonPackageName = extractCommonPackageName(fileProto); serviceContext.multipleFiles = - fileProto.getOptions() != null && fileProto.getOptions().getJavaMultipleFiles(); + fileProto.getOptions().getJavaMultipleFiles(); contexts.add(serviceContext); } }); @@ -114,11 +114,9 @@ public abstract class AbstractGenerator extends Generator { private String extractPackageName(FileDescriptorProto proto) { FileOptions options = proto.getOptions(); - if (options != null) { - String javaPackage = options.getJavaPackage(); - if (!Strings.isNullOrEmpty(javaPackage)) { - return javaPackage; - } + String javaPackage = options.getJavaPackage(); + if (!Strings.isNullOrEmpty(javaPackage)) { + return javaPackage; } return Strings.nullToEmpty(proto.getPackage()); @@ -139,7 +137,7 @@ public abstract class AbstractGenerator extends Generator { serviceContext.interfaceClassName = serviceProto.getName(); serviceContext.serviceName = serviceProto.getName(); serviceContext.deprecated = - serviceProto.getOptions() != null && serviceProto.getOptions().getDeprecated(); + serviceProto.getOptions().getDeprecated(); List allLocationsForService = locations.stream() .filter(location -> @@ -179,7 +177,7 @@ public abstract class AbstractGenerator extends Generator { methodContext.inputType = typeMap.toJavaTypeName(methodProto.getInputType()); methodContext.outputType = typeMap.toJavaTypeName(methodProto.getOutputType()); methodContext.deprecated = - methodProto.getOptions() != null && methodProto.getOptions().getDeprecated(); + methodProto.getOptions().getDeprecated(); methodContext.isManyInput = methodProto.getClientStreaming(); methodContext.isManyOutput = methodProto.getServerStreaming(); methodContext.methodNumber = methodNumber; @@ -265,11 +263,6 @@ public abstract class AbstractGenerator extends Generator { private String absoluteDir(ServiceContext ctx) { return ctx.packageName.replace('.', '/'); -// if (Strings.isNullOrEmpty(dir)) { -// return ctx.fileName; -// } else { -// return dir + "/" + ctx.fileName; -// }if () } private String getFileName(String dir, String fileName) { @@ -359,7 +352,7 @@ public abstract class AbstractGenerator extends Generator { /** * Template class for proto RPC objects. */ - private class MethodContext { + private static class MethodContext { // CHECKSTYLE DISABLE VisibilityModifier FOR 10 LINES public String originMethodName; diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java index 8eda1a9845..b3b9d5e630 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java @@ -81,7 +81,7 @@ public final class DubboBootstrap { private static final Logger logger = LoggerFactory.getLogger(DubboBootstrap.class); - private static volatile ConcurrentMap instanceMap = new ConcurrentHashMap<>(); + private static final ConcurrentMap instanceMap = new ConcurrentHashMap<>(); private static volatile DubboBootstrap instance; private final AtomicBoolean awaited = new AtomicBoolean(false); @@ -92,15 +92,15 @@ public final class DubboBootstrap { private final Condition condition = lock.newCondition(); - private ExecutorRepository executorRepository; + private final ExecutorRepository executorRepository; + + private final Environment environment; private final ApplicationModel applicationModel; - protected final ConfigManager configManager; + private final ConfigManager configManager; - protected final Environment environment; - - private ApplicationDeployer applicationDeployer; + private final ApplicationDeployer applicationDeployer; /** * See {@link ApplicationModel} and {@link ExtensionLoader} for why DubboBootstrap is designed to be singleton. diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java index 394063edb4..2579d431f4 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvoker.java @@ -28,7 +28,7 @@ import org.apache.dubbo.rpc.RpcException; */ public class DelegateProviderMetaDataInvoker implements Invoker { protected final Invoker invoker; - private ServiceConfig metadata; + private final ServiceConfig metadata; public DelegateProviderMetaDataInvoker(Invoker invoker, ServiceConfig metadata) { this.invoker = invoker; diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/ConfigurableSourceBeanMetadataElement.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/ConfigurableSourceBeanMetadataElement.java index 95693c251e..8b092dac12 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/ConfigurableSourceBeanMetadataElement.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/ConfigurableSourceBeanMetadataElement.java @@ -33,7 +33,7 @@ public interface ConfigurableSourceBeanMetadataElement { */ default void setSource(BeanMetadataElement beanMetadataElement) { if (beanMetadataElement instanceof BeanMetadataAttributeAccessor) { - BeanMetadataAttributeAccessor.class.cast(beanMetadataElement).setSource(this); + ((BeanMetadataAttributeAccessor) beanMetadataElement).setSource(this); } } } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigApplicationListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigApplicationListener.java index 0097382fae..17343637bb 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigApplicationListener.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboConfigApplicationListener.java @@ -42,7 +42,7 @@ public class DubboConfigApplicationListener implements ApplicationListener moduleAttributes = new HashMap<>(); + private final Map moduleAttributes = new HashMap<>(); private volatile boolean bound; diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitCustomizerHolder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitCustomizerHolder.java index 0e6a951bd5..de9ebdd812 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitCustomizerHolder.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitCustomizerHolder.java @@ -34,8 +34,7 @@ import java.util.Set; */ public class DubboSpringInitCustomizerHolder { - private static final ThreadLocal holders = ThreadLocal.withInitial(() -> - new DubboSpringInitCustomizerHolder()); + private static final ThreadLocal holders = ThreadLocal.withInitial(DubboSpringInitCustomizerHolder::new); public static DubboSpringInitCustomizerHolder get() { return holders.get(); diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitializer.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitializer.java index 28f277837c..774cfc1e8e 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitializer.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboSpringInitializer.java @@ -41,7 +41,7 @@ public class DubboSpringInitializer { private static final Logger logger = LoggerFactory.getLogger(DubboSpringInitializer.class); - private static Map contextMap = new ConcurrentHashMap<>(); + private static final Map contextMap = new ConcurrentHashMap<>(); private DubboSpringInitializer() { } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboApplicationStateEvent.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboApplicationStateEvent.java index fd8a1ba676..f3c5e688bd 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboApplicationStateEvent.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboApplicationStateEvent.java @@ -26,7 +26,7 @@ import org.springframework.context.ApplicationEvent; */ public class DubboApplicationStateEvent extends ApplicationEvent { - private DeployState state; + private final DeployState state; private Throwable cause; diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosConfigServiceWrapper.java b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosConfigServiceWrapper.java index c6a0a4457e..d6b2ff7910 100644 --- a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosConfigServiceWrapper.java +++ b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosConfigServiceWrapper.java @@ -31,7 +31,7 @@ public class NacosConfigServiceWrapper { private static final long DEFAULT_TIMEOUT = 3000L; - private ConfigService configService; + private final ConfigService configService; public NacosConfigServiceWrapper(ConfigService configService) { this.configService = configService; diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java index 55bd14b40c..359d33770a 100644 --- a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java +++ b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java @@ -67,7 +67,7 @@ public class NacosDynamicConfiguration implements DynamicConfiguration { */ private static final long DEFAULT_TIMEOUT = 5000L; - private Properties nacosProperties; + private final Properties nacosProperties; private static final String NACOS_RETRY_KEY = "nacos.retry"; @@ -85,7 +85,7 @@ public class NacosDynamicConfiguration implements DynamicConfiguration { */ private final ConcurrentMap watchListenerMap; - private MD5Utils md5Utils = new MD5Utils(); + private final MD5Utils md5Utils = new MD5Utils(); NacosDynamicConfiguration(URL url) { this.nacosProperties = buildNacosProperties(url); diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java index 4f565d0ae0..7ae31afca0 100644 --- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java +++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java @@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentMap; */ public class CacheListener { - private ConcurrentMap pathKeyListeners = new ConcurrentHashMap<>(); + private final ConcurrentMap pathKeyListeners = new ConcurrentHashMap<>(); public CacheListener() { } diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDataListener.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDataListener.java index c489ca0e33..22243d55ed 100644 --- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDataListener.java +++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDataListener.java @@ -30,10 +30,10 @@ import java.util.concurrent.CopyOnWriteArraySet; * one path has multi configurationListeners */ public class ZookeeperDataListener implements DataListener { - private String path; - private String key; - private String group; - private Set listeners; + private final String path; + private final String key; + private final String group; + private final Set listeners; public ZookeeperDataListener(String path, String key, String group) { this.path = path; diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java index 4836ed1b2f..423c2834f6 100644 --- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java +++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java @@ -40,10 +40,10 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ZOO public class ZookeeperDynamicConfiguration extends TreePathDynamicConfiguration { - private Executor executor; + private final Executor executor; private ZookeeperClient zkClient; - private CacheListener cacheListener; + private final CacheListener cacheListener; private static final int DEFAULT_ZK_EXECUTOR_THREADS_NUM = 1; private static final int DEFAULT_QUEUE = 10000; private static final Long THREAD_KEEP_ALIVE_TIME = 0L; diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationFactory.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationFactory.java index 962c7bd028..f470654ca5 100644 --- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationFactory.java +++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationFactory.java @@ -24,12 +24,9 @@ import org.apache.dubbo.rpc.model.ApplicationModel; public class ZookeeperDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory { - private ZookeeperTransporter zookeeperTransporter; - - private ApplicationModel applicationModel; + private final ZookeeperTransporter zookeeperTransporter; public ZookeeperDynamicConfigurationFactory(ApplicationModel applicationModel) { - this.applicationModel = applicationModel; this.zookeeperTransporter = ZookeeperTransporter.getExtension(applicationModel); } diff --git a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java index b5306e2243..3516b0a214 100644 --- a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java +++ b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/expiring/ExpiringMap.java @@ -41,7 +41,7 @@ public class ExpiringMap implements Map { */ private static final int DEFAULT_EXPIRATION_INTERVAL = 1; - private static AtomicInteger expireCount = new AtomicInteger(1); + private static final AtomicInteger expireCount = new AtomicInteger(1); private final ConcurrentHashMap delegateMap; @@ -86,7 +86,7 @@ public class ExpiringMap implements Map { if (object != null) { long timeIdle = System.currentTimeMillis() - object.getLastAccessTime(); int timeToLive = expireThread.getTimeToLive(); - if (timeToLive > 0 && timeIdle >= timeToLive * 1000) { + if (timeToLive > 0 && timeIdle >= timeToLive * 1000L) { delegateMap.remove(object.getKey()); return null; } diff --git a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java index 9ccc979ff0..f505c16b1d 100644 --- a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java +++ b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/support/lfu/LfuCache.java @@ -43,6 +43,7 @@ public class LfuCache implements Cache { /** * This is used to store cache records */ + @SuppressWarnings("rawtypes") private final LFUCache store; /** @@ -51,6 +52,7 @@ public class LfuCache implements Cache { * If nothing is provided then it will use 0.3 as default value. * @param url A valid URL instance */ + @SuppressWarnings("rawtypes") public LfuCache (URL url) { final int max = url.getParameter("cache.size", 1000); final float factor = url.getParameter("cache.evictionFactor", 0.75f); @@ -62,6 +64,7 @@ public class LfuCache implements Cache { * @param key Unique identifier for the object being store. * @param value Value getting store */ + @SuppressWarnings("unchecked") @Override public void put(Object key, Object value) { store.put(key, value); @@ -72,6 +75,7 @@ public class LfuCache implements Cache { * @param key Unique identifier for cache lookup * @return Return stored object against key */ + @SuppressWarnings("unchecked") @Override public Object get(Object key) { return store.get(key); diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java index b63fb4b349..f5c06a7bba 100644 --- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java +++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java @@ -81,7 +81,7 @@ public class JValidator implements Validator { private final Class clazz; - private final Map methodClassMap; + private final Map> methodClassMap; private final javax.validation.Validator validator; @@ -298,10 +298,10 @@ public class JValidator implements Validator { } } - private Class methodClass(String methodName) { + private Class methodClass(String methodName) { Class methodClass = null; String methodClassName = clazz.getName() + "$" + toUpperMethoName(methodName); - Class cached = methodClassMap.get(methodClassName); + Class cached = methodClassMap.get(methodClassName); if (cached != null) { return cached == clazz ? null : cached; } diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java index 96dcc12666..c52d1a85c1 100644 --- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java +++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java @@ -81,7 +81,7 @@ public class JValidatorNew implements Validator { private final Class clazz; - private final Map methodClassMap; + private final Map> methodClassMap; private final jakarta.validation.Validator validator; @@ -202,7 +202,7 @@ public class JValidatorNew implements Validator { private static boolean hasConstraintParameter(Method method) { Annotation[][] parameterAnnotations = method.getParameterAnnotations(); - if (parameterAnnotations != null && parameterAnnotations.length > 0) { + if (parameterAnnotations.length > 0) { for (Annotation[] annotations : parameterAnnotations) { for (Annotation annotation : annotations) { if (annotation.annotationType().isAnnotationPresent(Constraint.class)) { @@ -298,10 +298,10 @@ public class JValidatorNew implements Validator { } } - private Class methodClass(String methodName) { + private Class methodClass(String methodName) { Class methodClass = null; String methodClassName = clazz.getName() + "$" + toUpperMethoName(methodName); - Class cached = methodClassMap.get(methodClassName); + Class cached = methodClassMap.get(methodClassName); if (cached != null) { return cached == clazz ? null : cached; } diff --git a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java index bddd67c401..d4c7750ed1 100644 --- a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java +++ b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/AccessKeyAuthenticator.java @@ -29,7 +29,7 @@ import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.model.ApplicationModel; public class AccessKeyAuthenticator implements Authenticator { - private ApplicationModel applicationModel; + private final ApplicationModel applicationModel; public AccessKeyAuthenticator(ApplicationModel applicationModel) { this.applicationModel = applicationModel; diff --git a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ConsumerSignFilter.java b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ConsumerSignFilter.java index aad5279150..fea562fde2 100644 --- a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ConsumerSignFilter.java +++ b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ConsumerSignFilter.java @@ -35,7 +35,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel; */ @Activate(group = CommonConstants.CONSUMER, value = Constants.SERVICE_AUTH, order = -10000) public class ConsumerSignFilter implements Filter { - private ApplicationModel applicationModel; + private final ApplicationModel applicationModel; public ConsumerSignFilter(ApplicationModel applicationModel) { this.applicationModel = applicationModel; diff --git a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ProviderAuthFilter.java b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ProviderAuthFilter.java index ba5c3bd643..fb76cdfdf4 100644 --- a/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ProviderAuthFilter.java +++ b/dubbo-plugin/dubbo-auth/src/main/java/org/apache/dubbo/auth/filter/ProviderAuthFilter.java @@ -31,7 +31,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel; @Activate(group = CommonConstants.PROVIDER, value = Constants.SERVICE_AUTH, order = -10000) public class ProviderAuthFilter implements Filter { - private ApplicationModel applicationModel; + private final ApplicationModel applicationModel; public ProviderAuthFilter(ApplicationModel applicationModel) { this.applicationModel = applicationModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java index d7b4baf6b2..9879d0de92 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java @@ -32,7 +32,7 @@ import java.util.Collection; import java.util.List; public class BaseOffline implements BaseCommand { - private Logger logger = LoggerFactory.getLogger(BaseOffline.class); + private static final Logger logger = LoggerFactory.getLogger(BaseOffline.class); public FrameworkServiceRepository serviceRepository; public BaseOffline(FrameworkModel frameworkModel) { diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java index 96d6d3c5e2..2643bd689d 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java @@ -34,7 +34,7 @@ public class ChangeTelnet implements BaseCommand { public static final AttributeKey SERVICE_KEY = AttributeKey.valueOf("telnet.service"); - private DubboProtocol dubboProtocol; + private final DubboProtocol dubboProtocol; public ChangeTelnet(FrameworkModel frameworkModel) { this.dubboProtocol = DubboProtocol.getDubboProtocol(frameworkModel); diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java index 1064e9f19b..8525614430 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java @@ -45,7 +45,7 @@ import static org.apache.dubbo.qos.server.handler.QosProcessHandler.PROMPT; "count [service] [method] [times]" }) public class CountTelnet implements BaseCommand { - private DubboProtocol dubboProtocol; + private final DubboProtocol dubboProtocol; public CountTelnet(FrameworkModel frameworkModel) { this.dubboProtocol = DubboProtocol.getDubboProtocol(frameworkModel); diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java index 0c34f18f9e..497cf52b23 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java @@ -33,7 +33,7 @@ import java.util.Map; @Cmd(name = "getRouterSnapshot", summary = "Get State Router Snapshot.", example = "getRouterSnapshot xx.xx.xxx.service") public class GetRouterSnapshot implements BaseCommand { - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; public GetRouterSnapshot(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java index 2e074580a7..5f8a21c12f 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java @@ -36,11 +36,11 @@ import java.util.WeakHashMap; }) public class Help implements BaseCommand { - private CommandHelper commandHelper; + private final CommandHelper commandHelper; private static final String MAIN_HELP = "mainHelp"; - private static Map processedTable = new WeakHashMap<>(); + private static final Map processedTable = new WeakHashMap<>(); public Help(FrameworkModel frameworkModel) { this.commandHelper = new CommandHelper(frameworkModel); @@ -49,7 +49,7 @@ public class Help implements BaseCommand { @Override public String execute(CommandContext commandContext, String[] args) { if (ArrayUtils.isNotEmpty(args)) { - return processedTable.computeIfAbsent(args[0], commandName -> commandHelp(commandName)); + return processedTable.computeIfAbsent(args[0], this::commandHelp); } else { return processedTable.computeIfAbsent(MAIN_HELP, commandName -> mainHelp()); } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java index 507282160e..8278d09226 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java @@ -50,7 +50,7 @@ public class InvokeTelnet implements BaseCommand { public static final AttributeKey> INVOKE_METHOD_LIST_KEY = AttributeKey.valueOf("telnet.invoke.method.list"); public static final AttributeKey INVOKE_METHOD_PROVIDER_KEY = AttributeKey.valueOf("telnet.invoke.method.provider"); - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; public InvokeTelnet(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java index 962a036a38..188f58224e 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java @@ -31,7 +31,7 @@ import java.util.Collection; "ls" }) public class Ls implements BaseCommand { - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; public Ls(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java index a28e411832..bd983dcfa7 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java @@ -32,7 +32,7 @@ import java.util.Collection; "ps -l [port]", "ps", "ps -l", "ps -l 20880" }) public class PortTelnet implements BaseCommand { - private DubboProtocol dubboProtocol; + private final DubboProtocol dubboProtocol; public PortTelnet(FrameworkModel frameworkModel) { this.dubboProtocol = DubboProtocol.getDubboProtocol(frameworkModel); diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java index 08f268d188..2c38b3b143 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java @@ -31,7 +31,7 @@ import java.util.List; }) public class ShutdownTelnet implements BaseCommand { - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; public ShutdownTelnet(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java index 8f2d2d0148..380ef9672d 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java @@ -33,7 +33,7 @@ import java.util.stream.Collectors; @Cmd(name = "startup", summary = "Judge if service has started? ", requiredPermissionLevel = PermissionLevel.PUBLIC) public class Startup implements BaseCommand { - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; public Startup(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java index 7c554f4e8a..23bfc3a1a4 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java @@ -25,7 +25,7 @@ import java.util.Set; public class CommandHelper { - private FrameworkModel frameworkModel; + private final FrameworkModel frameworkModel; public CommandHelper(FrameworkModel frameworkModel) { this.frameworkModel = frameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/probe/impl/ProviderReadinessProbe.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/probe/impl/ProviderReadinessProbe.java index 66a33d0292..653d2b9e35 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/probe/impl/ProviderReadinessProbe.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/probe/impl/ProviderReadinessProbe.java @@ -26,8 +26,8 @@ import java.util.Collection; @Activate public class ProviderReadinessProbe implements ReadinessProbe { - private FrameworkModel frameworkModel; - private FrameworkServiceRepository serviceRepository; + private final FrameworkModel frameworkModel; + private final FrameworkServiceRepository serviceRepository; public ProviderReadinessProbe(FrameworkModel frameworkModel) { if (frameworkModel != null) { diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java index c16a25f98c..737388c2a1 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java @@ -50,9 +50,9 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware { private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(QosProtocolWrapper.class); - private AtomicBoolean hasStarted = new AtomicBoolean(false); + private final AtomicBoolean hasStarted = new AtomicBoolean(false); - private Protocol protocol; + private final Protocol protocol; private FrameworkModel frameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java index b5b63f35ac..d7aafbafec 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java @@ -38,7 +38,7 @@ public class ForeignHostPermitHandler extends ChannelHandlerAdapter { // the whitelist of foreign IP when acceptForeignIp = false, the delimiter is colon(,) // support specific ip and an ip range from CIDR specification private final String acceptForeignIpWhitelist; - private Predicate whitelistPredicate; + private final Predicate whitelistPredicate; private final QosConfiguration qosConfiguration; diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java index 470ee6f57f..a97e520d65 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/jackson/ObjectMapperCodec.java @@ -30,7 +30,7 @@ import java.util.function.Consumer; public class ObjectMapperCodec { - private ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper mapper = new ObjectMapper(); public ObjectMapperCodec() { registerDefaultModule(); From c8e7ef7892bcead49f4b783c7d56afb5c145b9d2 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 16 Mar 2023 09:44:53 +0800 Subject: [PATCH 121/144] 1. Fix HeaderExchangeChannel close potential bug (#11834) 2. 'channel != null' must be satisfied, simplify hashCode and equals --- .../support/header/HeaderExchangeChannel.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java index ab576db76a..6c4e7fd09c 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java @@ -160,6 +160,11 @@ final class HeaderExchangeChannel implements ExchangeChannel { try { // graceful close DefaultFuture.closeChannel(channel); + } catch (Exception e) { + logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e); + } + + try { channel.close(); } catch (Exception e) { logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e); @@ -245,7 +250,7 @@ final class HeaderExchangeChannel implements ExchangeChannel { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((channel == null) ? 0 : channel.hashCode()); + result = prime * result + channel.hashCode(); return result; } @@ -261,14 +266,7 @@ final class HeaderExchangeChannel implements ExchangeChannel { return false; } HeaderExchangeChannel other = (HeaderExchangeChannel) obj; - if (channel == null) { - if (other.channel != null) { - return false; - } - } else if (!channel.equals(other.channel)) { - return false; - } - return true; + return channel.equals(other.channel); } @Override From 13f53368bbe9e1368788c5bd0402f62132d25740 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:45:30 +0800 Subject: [PATCH 122/144] Bump micrometer-bom from 1.10.4 to 1.10.5 (#11821) Bumps [micrometer-bom](https://github.com/micrometer-metrics/micrometer) from 1.10.4 to 1.10.5. - [Release notes](https://github.com/micrometer-metrics/micrometer/releases) - [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.10.4...v1.10.5) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- .../dubbo-spring-boot-observability-starter/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 7def2661c5..ea199bb840 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -134,7 +134,7 @@ 3.12.0 1.8.0 0.1.35 - 1.10.4 + 1.10.5 1.0.2 3.3 diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml index 7e0106a494..9ec2e95d15 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml @@ -29,7 +29,7 @@ dubbo-spring-boot-observability-starter - 1.10.4 + 1.10.5 1.0.2 From 91b7f5a1c865f072983f59aa8d894b78a12a1043 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:46:25 +0800 Subject: [PATCH 123/144] Bump byte-buddy from 1.14.1 to 1.14.2 (#11815) Bumps [byte-buddy](https://github.com/raphw/byte-buddy) from 1.14.1 to 1.14.2. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.1...byte-buddy-1.14.2) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index ea199bb840..949ebf783d 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -94,7 +94,7 @@ 5.3.25 5.8.2 3.29.2-GA - 1.14.1 + 1.14.2 3.2.10.Final 4.1.87.Final 2.2.1 From 7a4bcde906e6687ed674b657d964d2caa94e661a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:46:46 +0800 Subject: [PATCH 124/144] Bump protobuf-java.version from 3.22.0 to 3.22.2 (#11810) Bumps `protobuf-java.version` from 3.22.0 to 3.22.2. Updates `protobuf-java` from 3.22.0 to 3.22.2 - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.22.0...v3.22.2) Updates `protobuf-java-util` from 3.22.0 to 3.22.2 --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.google.protobuf:protobuf-java-util dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 949ebf783d..11c3acf74a 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -114,7 +114,7 @@ 3.5.5 0.18.1 4.0.66 - 3.22.0 + 3.22.2 1.3.2 3.1.0 5.0.0 From c76607dadcd2b777429ec490873ef135fcee5c55 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 16 Mar 2023 09:48:03 +0800 Subject: [PATCH 125/144] Add spring configuration for QOS function. (#11823) --- .../src/main/resources/META-INF/dubbo.xsd | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index 2ff4ebddbd..d801ffefc3 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -512,6 +512,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b19f89bef76b234ea0f80710356b0e9aae6a301a Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 16 Mar 2023 09:49:00 +0800 Subject: [PATCH 126/144] Fix issue #11790 (#11824) --- .../org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java index 99f235385b..1bff438b27 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java @@ -29,6 +29,7 @@ import org.apache.dubbo.rpc.FutureContext; 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.protocol.AbstractInvoker; @@ -103,6 +104,9 @@ public class DubboInvoker extends AbstractInvoker { } invocation.setAttachment(TIMEOUT_KEY, String.valueOf(timeout)); + + RpcContext.getServiceContext().setRemoteAddress(currentClient.getRemoteAddress()); + if (isOneway) { boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false); currentClient.send(inv, isSent); From 6cb053a8d6f8a402b0f81ca3790c4c81e5aea05f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:49:53 +0800 Subject: [PATCH 127/144] Bump micrometer-core from 1.10.4 to 1.10.5 (#11820) Bumps [micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.10.4 to 1.10.5. - [Release notes](https://github.com/micrometer-metrics/micrometer/releases) - [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.10.4...v1.10.5) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-demo/dubbo-demo-spring-boot/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-demo/dubbo-demo-spring-boot/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/pom.xml index 34a9a855d5..4ac5160226 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/pom.xml @@ -38,7 +38,7 @@ true 2.7.9 2.7.9 - 1.10.4 + 1.10.5 From d093579106bb4990e6795ecf6abe95bc08866460 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:52:05 +0800 Subject: [PATCH 128/144] Bump micrometer-tracing-bom from 1.0.2 to 1.0.3 (#11819) Bumps [micrometer-tracing-bom](https://github.com/micrometer-metrics/tracing) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/micrometer-metrics/tracing/releases) - [Commits](https://github.com/micrometer-metrics/tracing/compare/v1.0.2...v1.0.3) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-tracing-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- .../dubbo-spring-boot-observability-starter/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 11c3acf74a..3d847c2a0e 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -136,7 +136,7 @@ 0.1.35 1.10.5 - 1.0.2 + 1.0.3 3.3 0.16.0 1.0.4 diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml index 9ec2e95d15..7e4b5978f5 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml @@ -30,7 +30,7 @@ 1.10.5 - 1.0.2 + 1.0.3 From 4f6528fb86a843b2308167ffd1e5faac22e33a4b Mon Sep 17 00:00:00 2001 From: GuoHao Date: Thu, 16 Mar 2023 10:23:19 +0800 Subject: [PATCH 129/144] Call onClose() when deser error (#11838) --- .../dubbo/rpc/protocol/tri/call/TripleClientCall.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/TripleClientCall.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/TripleClientCall.java index a7d5e39d80..4ee3512adf 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/TripleClientCall.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/TripleClientCall.java @@ -74,8 +74,10 @@ public class TripleClientCall implements ClientCall, ClientStream.Listener { final Object unpacked = requestMetadata.packableMethod.parseResponse(message); listener.onMessage(unpacked); } catch (Throwable t) { - cancelByLocal(TriRpcStatus.INTERNAL.withDescription("Deserialize response failed") - .withCause(t).asException()); + TriRpcStatus status = TriRpcStatus.INTERNAL.withDescription("Deserialize response failed") + .withCause(t); + cancelByLocal(status.asException()); + listener.onClose(status,null); LOGGER.error(PROTOCOL_FAILED_RESPONSE, "", "", String.format("Failed to deserialize triple response, service=%s, method=%s,connection=%s", connection, requestMetadata.service, requestMetadata.method.getMethodName()), t); } From 6b7a735a4d44d214e618ebc2ef341d03a0ebe1eb Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Thu, 16 Mar 2023 18:36:21 +0800 Subject: [PATCH 130/144] Triple read compressor from config (#11850) --- .../dubbo/rpc/protocol/tri/TripleInvoker.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java index b5e8466068..6c11a1061a 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java @@ -18,6 +18,8 @@ package org.apache.dubbo.rpc.protocol.tri; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.config.Configuration; +import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -33,9 +35,11 @@ import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.TriRpcStatus; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ConsumerModel; import org.apache.dubbo.rpc.model.MethodDescriptor; import org.apache.dubbo.rpc.model.PackableMethod; +import org.apache.dubbo.rpc.model.ScopeModelUtil; import org.apache.dubbo.rpc.model.ServiceDescriptor; import org.apache.dubbo.rpc.model.StubMethodDescriptor; import org.apache.dubbo.rpc.protocol.AbstractInvoker; @@ -44,6 +48,7 @@ import org.apache.dubbo.rpc.protocol.tri.call.ObserverToClientCallListenerAdapte import org.apache.dubbo.rpc.protocol.tri.call.TripleClientCall; import org.apache.dubbo.rpc.protocol.tri.call.UnaryClientCallListener; import org.apache.dubbo.rpc.protocol.tri.compressor.Compressor; +import org.apache.dubbo.rpc.protocol.tri.compressor.Identity; import org.apache.dubbo.rpc.protocol.tri.observer.ClientCallToObserverAdapter; import org.apache.dubbo.rpc.protocol.tri.transport.TripleWriteQueue; import org.apache.dubbo.rpc.support.RpcUtils; @@ -62,6 +67,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_DESTROY_INVOKER; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_REQUEST; +import static org.apache.dubbo.rpc.Constants.COMPRESSOR_KEY; import static org.apache.dubbo.rpc.Constants.TOKEN_KEY; /** @@ -96,6 +102,12 @@ public class TripleInvoker extends AbstractInvoker { return ssl ? TripleConstant.HTTPS_SCHEME : TripleConstant.HTTP_SCHEME; } + private static Compressor getCompressorFromEnv() { + Configuration configuration = ConfigurationUtils.getEnvConfiguration(ApplicationModel.defaultModel()); + String compressorKey = configuration.getString(COMPRESSOR_KEY, Identity.MESSAGE_ENCODING); + return Compressor.getCompressor(ScopeModelUtil.getFrameworkModel(ApplicationModel.defaultModel()), compressorKey); + } + @Override protected Result doInvoke(final Invocation invocation) { if (!connectionClient.isConnected()) { @@ -240,8 +252,7 @@ public class TripleInvoker extends AbstractInvoker { meta.ignoreDefaultVersion = TripleProtocol.IGNORE_1_0_0_VERSION; meta.method = methodDescriptor; meta.scheme = getSchemeFromUrl(url); - // TODO read compressor from config - meta.compressor = Compressor.NONE; + meta.compressor = getCompressorFromEnv(); meta.cancellationContext = RpcContext.getCancellationContext(); meta.address = url.getAddress(); meta.service = url.getPath(); From 7d9e955cf888154c2d914688ca909545216b7b25 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 17 Mar 2023 10:03:06 +0800 Subject: [PATCH 131/144] Bump to 3.1.9-SNAPSHOT --- dubbo-dependencies-bom/pom.xml | 2 +- .../dubbo-dependencies-zookeeper-curator5/pom.xml | 2 +- dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index e8b55603cf..2ecc954a37 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -182,7 +182,7 @@ 2.0 1.1.0 1.21 - 3.1.8 + 3.1.9-SNAPSHOT diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml index c83716cd7d..6f06001ad4 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.8 + 3.1.9-SNAPSHOT 1.1.0 5.1.0 3.7.0 diff --git a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml index b617d591f6..05c0dc9611 100644 --- a/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml +++ b/dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml @@ -32,7 +32,7 @@ pom - 3.1.8 + 3.1.9-SNAPSHOT 1.1.0 4.2.0 3.4.14 diff --git a/pom.xml b/pom.xml index 3b6dae0cc0..23da357bed 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ true true true - 3.1.8 + 3.1.9-SNAPSHOT From ae259ce21b6a93fb19a4e92213e51735c7d7b9d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 10:12:14 +0800 Subject: [PATCH 132/144] Bump maven-surefire-plugin from 3.0.0-M9 to 3.0.0 (#11847) Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.0.0-M9 to 3.0.0. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.0.0-M9...surefire-3.0.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4067a15697..c5eb1de694 100644 --- a/pom.xml +++ b/pom.xml @@ -113,7 +113,7 @@ UTF-8 3.3.0 - 3.0.0-M9 + 3.0.0 3.0.0-M9 2.8.2 3.11.0 From cb0cdafc5a5cf20e00adfa3ad026db8ced19e25f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 10:12:29 +0800 Subject: [PATCH 133/144] Bump reactor-core from 3.5.3 to 3.5.4 (#11845) Bumps [reactor-core](https://github.com/reactor/reactor-core) from 3.5.3 to 3.5.4. - [Release notes](https://github.com/reactor/reactor-core/releases) - [Commits](https://github.com/reactor/reactor-core/compare/v3.5.3...v3.5.4) --- updated-dependencies: - dependency-name: io.projectreactor:reactor-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- dubbo-rpc/dubbo-rpc-triple/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 5be8a6a6fc..77b590f7d8 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -140,7 +140,7 @@ 3.3 0.16.0 1.0.4 - 3.5.3 + 3.5.4 3.14.2 2.1.1 diff --git a/dubbo-rpc/dubbo-rpc-triple/pom.xml b/dubbo-rpc/dubbo-rpc-triple/pom.xml index 42916180ec..a285ed5baf 100644 --- a/dubbo-rpc/dubbo-rpc-triple/pom.xml +++ b/dubbo-rpc/dubbo-rpc-triple/pom.xml @@ -31,7 +31,7 @@ false 0.0.4.1-SNAPSHOT 1.0.4 - 3.5.3 + 3.5.4 3.22.2 From f131a5d5b4dabfc5d9acf95846ac165145678980 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 11:48:07 +0800 Subject: [PATCH 134/144] Bump maven-failsafe-plugin from 3.0.0-M9 to 3.0.0 (#11846) Bumps [maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.0.0-M9 to 3.0.0. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.0.0-M9...surefire-3.0.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c5eb1de694..88c3e93d86 100644 --- a/pom.xml +++ b/pom.xml @@ -114,7 +114,7 @@ 3.3.0 3.0.0 - 3.0.0-M9 + 3.0.0 2.8.2 3.11.0 3.2.1 From af3f75acedd9e5ca964292b2f647a2766815367d Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Fri, 17 Mar 2023 11:51:52 +0800 Subject: [PATCH 135/144] ShutdownHook may be executed in advance, affecting CI results (#11848) --- .../main/java/org/apache/dubbo/common/utils/TimeUtils.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java index 79974d1864..0355b6cf9a 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/TimeUtils.java @@ -68,7 +68,10 @@ public final class TimeUtils { ticker.setDaemon(true); ticker.setName("time-millis-ticker-thread"); ticker.start(); - Runtime.getRuntime().addShutdownHook(new Thread(ticker::interrupt)); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + isFallback = true; + ticker.interrupt(); + })); isTickerAlive = true; } } From ec9eecfc821e6f56c5b1d1150d3a98a8509d969b Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Fri, 17 Mar 2023 13:02:56 +0800 Subject: [PATCH 136/144] gc bug (#11855) Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../metrics/report/AbstractMetricsReporter.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java index e88bd0cdc4..4a0558b387 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/report/AbstractMetricsReporter.java @@ -17,6 +17,7 @@ package org.apache.dubbo.metrics.report; +import io.micrometer.core.instrument.binder.MeterBinder; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; import org.apache.dubbo.common.constants.MetricsConstants; @@ -65,6 +66,8 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { protected final URL url; @SuppressWarnings("rawtypes") protected final List collectors = new ArrayList<>(); + // Avoid instances being gc due to weak references + protected final List instanceHolder = new ArrayList<>(); public static final CompositeMeterRegistry compositeRegistry = new CompositeMeterRegistry(); private final ApplicationModel applicationModel; @@ -116,12 +119,17 @@ public abstract class AbstractMetricsReporter implements MetricsReporter { jvmGcMetrics.bindTo(compositeRegistry); Runtime.getRuntime().addShutdownHook(new Thread(jvmGcMetrics::close)); - new ProcessorMetrics(extraTags).bindTo(compositeRegistry); + bindTo(new ProcessorMetrics(extraTags)); new JvmThreadMetrics(extraTags).bindTo(compositeRegistry); - new UptimeMetrics(extraTags).bindTo(compositeRegistry); + bindTo(new UptimeMetrics(extraTags)); } } + private void bindTo(MeterBinder binder) { + binder.bindTo(compositeRegistry); + instanceHolder.add(binder); + } + @SuppressWarnings("rawtypes") private void initCollectors() { ScopeBeanFactory beanFactory = applicationModel.getBeanFactory(); From 06605365c51fd4e8bbec50a9aa1061408063e50c Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Fri, 17 Mar 2023 13:33:49 +0800 Subject: [PATCH 137/144] splits qos-api pkg (#11853) * init * add licence * fix path name * add api for depall * add bom pom --------- Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../dubbo/qos/command/BaseCommand.java | 4 +- .../dubbo/qos/command/CommandContext.java | 4 +- dubbo-distribution/dubbo-all/pom.xml | 10 +++- dubbo-distribution/dubbo-bom/pom.xml | 5 ++ dubbo-distribution/dubbo-core-spi/pom.xml | 2 +- .../dubbo-metrics-prometheus/pom.xml | 2 +- .../PrometheusMetricsReporterCmd.java | 6 +-- ...d => org.apache.dubbo.qos.api.BaseCommand} | 0 dubbo-plugin/dubbo-qos-api/pom.xml | 46 +++++++++++++++++++ .../apache/dubbo/qos/api}/BaseCommand.java | 2 +- .../java/org/apache/dubbo/qos/api}/Cmd.java | 4 +- .../apache/dubbo/qos/api}/CommandContext.java | 4 +- .../dubbo/qos/api}/PermissionLevel.java | 2 +- .../dubbo/qos/api}/QosConfiguration.java | 9 ++-- dubbo-plugin/dubbo-qos/pom.xml | 5 ++ .../qos/command/CommandContextFactory.java | 2 + .../dubbo/qos/command/CommandExecutor.java | 1 + .../qos/command/DefaultCommandExecutor.java | 6 ++- .../command/decoder/HttpCommandDecoder.java | 2 +- .../command/decoder/TelnetCommandDecoder.java | 2 +- .../dubbo/qos/command/impl/BaseOffline.java | 4 +- .../dubbo/qos/command/impl/BaseOnline.java | 4 +- .../dubbo/qos/command/impl/ChangeTelnet.java | 6 +-- .../dubbo/qos/command/impl/CountTelnet.java | 6 +-- .../command/impl/DisableDetailProfiler.java | 6 +-- .../command/impl/DisableRouterSnapshot.java | 6 +-- .../command/impl/DisableSimpleProfiler.java | 6 +-- .../command/impl/EnableDetailProfiler.java | 6 +-- .../command/impl/EnableRouterSnapshot.java | 6 +-- .../command/impl/EnableSimpleProfiler.java | 6 +-- .../dubbo/qos/command/impl/GetConfig.java | 8 ++-- .../impl/GetEnabledRouterSnapshot.java | 6 +-- .../command/impl/GetRecentRouterSnapshot.java | 6 +-- .../qos/command/impl/GetRouterSnapshot.java | 6 +-- .../apache/dubbo/qos/command/impl/Help.java | 6 +-- .../dubbo/qos/command/impl/InvokeTelnet.java | 6 +-- .../apache/dubbo/qos/command/impl/Live.java | 8 ++-- .../dubbo/qos/command/impl/LoggerInfo.java | 6 +-- .../org/apache/dubbo/qos/command/impl/Ls.java | 6 +-- .../dubbo/qos/command/impl/Offline.java | 2 +- .../dubbo/qos/command/impl/OfflineApp.java | 2 +- .../qos/command/impl/OfflineInterface.java | 2 +- .../apache/dubbo/qos/command/impl/Online.java | 2 +- .../dubbo/qos/command/impl/OnlineApp.java | 2 +- .../qos/command/impl/OnlineInterface.java | 2 +- .../dubbo/qos/command/impl/PortTelnet.java | 6 +-- .../qos/command/impl/PublishMetadata.java | 6 +-- .../dubbo/qos/command/impl/PwdTelnet.java | 6 +-- .../apache/dubbo/qos/command/impl/Quit.java | 8 ++-- .../apache/dubbo/qos/command/impl/Ready.java | 8 ++-- .../dubbo/qos/command/impl/SelectTelnet.java | 6 +-- .../command/impl/SerializeCheckStatus.java | 6 +-- .../command/impl/SerializeWarnedClasses.java | 6 +-- .../command/impl/SetProfilerWarnPercent.java | 6 +-- .../qos/command/impl/ShutdownTelnet.java | 6 +-- .../dubbo/qos/command/impl/Startup.java | 8 ++-- .../qos/command/impl/SwitchLogLevel.java | 6 +-- .../dubbo/qos/command/impl/SwitchLogger.java | 6 +-- .../dubbo/qos/command/impl/Version.java | 6 +-- .../dubbo/qos/command/util/CommandHelper.java | 2 +- ...faultAnonymousAccessPermissionChecker.java | 6 +-- .../qos/permission/PermissionChecker.java | 3 +- .../qos/protocol/QosProtocolWrapper.java | 2 +- .../apache/dubbo/qos/pu/QosWireProtocol.java | 4 +- .../apache/dubbo/qos/pu/TelnetDetector.java | 4 +- .../org/apache/dubbo/qos/server/Server.java | 4 +- .../handler/ForeignHostPermitHandler.java | 2 +- .../server/handler/HttpProcessHandler.java | 4 +- .../qos/server/handler/QosProcessHandler.java | 2 +- .../server/handler/TelnetProcessHandler.java | 4 +- ...d => org.apache.dubbo.qos.api.BaseCommand} | 0 .../command/CommandContextFactoryTest.java | 1 + .../dubbo/qos/command/CommandContextTest.java | 3 +- .../command/DefaultCommandExecutorTest.java | 5 +- .../dubbo/qos/command/GreetingCommand.java | 4 +- .../decoder/HttpCommandDecoderTest.java | 2 +- .../decoder/TelnetCommandDecoderTest.java | 4 +- .../qos/command/impl/ChangeTelnetTest.java | 6 +-- .../qos/command/impl/CountTelnetTest.java | 6 +-- .../dubbo/qos/command/impl/GetConfigTest.java | 2 +- .../dubbo/qos/command/impl/HelpTest.java | 2 +- .../qos/command/impl/InvokeTelnetTest.java | 4 +- .../dubbo/qos/command/impl/LiveTest.java | 2 +- .../apache/dubbo/qos/command/impl/LsTest.java | 2 +- .../dubbo/qos/command/impl/OfflineTest.java | 2 +- .../dubbo/qos/command/impl/OnlineTest.java | 2 +- .../qos/command/impl/PortTelnetTest.java | 6 +-- .../qos/command/impl/PublishMetadataTest.java | 2 +- .../dubbo/qos/command/impl/PwdTelnetTest.java | 6 +-- .../dubbo/qos/command/impl/QuitTest.java | 4 +- .../dubbo/qos/command/impl/ReadyTest.java | 4 +- .../qos/command/impl/SelectTelnetTest.java | 6 +-- .../impl/SerializeCheckStatusTest.java | 2 +- .../impl/SerializeWarnedClassesTest.java | 2 +- .../qos/command/impl/ShutdownTelnetTest.java | 6 +-- .../dubbo/qos/command/impl/StartupTest.java | 4 +- ...tAnonymousAccessPermissionCheckerTest.java | 14 +++--- .../qos/protocol/QosProtocolWrapperTest.java | 2 +- .../handler/ForeignHostPermitHandlerTest.java | 4 +- .../handler/HttpProcessHandlerTest.java | 4 +- .../server/handler/QosProcessHandlerTest.java | 2 +- .../handler/TelnetProcessHandlerTest.java | 4 +- ...d => org.apache.dubbo.qos.api.BaseCommand} | 0 dubbo-plugin/pom.xml | 1 + dubbo-test/dubbo-dependencies-all/pom.xml | 4 ++ 105 files changed, 285 insertions(+), 210 deletions(-) rename dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/{org.apache.dubbo.qos.command.BaseCommand => org.apache.dubbo.qos.api.BaseCommand} (100%) create mode 100644 dubbo-plugin/dubbo-qos-api/pom.xml rename dubbo-plugin/{dubbo-qos/src/main/java/org/apache/dubbo/qos/command => dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api}/BaseCommand.java (96%) rename dubbo-plugin/{dubbo-qos/src/main/java/org/apache/dubbo/qos/command/annotation => dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api}/Cmd.java (94%) rename dubbo-plugin/{dubbo-qos/src/main/java/org/apache/dubbo/qos/command => dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api}/CommandContext.java (96%) rename dubbo-plugin/{dubbo-qos/src/main/java/org/apache/dubbo/qos/permission => dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api}/PermissionLevel.java (98%) rename dubbo-plugin/{dubbo-qos/src/main/java/org/apache/dubbo/qos/common => dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api}/QosConfiguration.java (98%) rename dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/{org.apache.dubbo.qos.command.BaseCommand => org.apache.dubbo.qos.api.BaseCommand} (100%) rename dubbo-plugin/dubbo-qos/src/test/resources/META-INF/services/{org.apache.dubbo.qos.command.BaseCommand => org.apache.dubbo.qos.api.BaseCommand} (100%) diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/BaseCommand.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/BaseCommand.java index 1f7bc5ba4c..e44d92311a 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/BaseCommand.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/BaseCommand.java @@ -17,10 +17,10 @@ package com.alibaba.dubbo.qos.command; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; @Deprecated -public interface BaseCommand extends org.apache.dubbo.qos.command.BaseCommand { +public interface BaseCommand extends org.apache.dubbo.qos.api.BaseCommand { String execute(com.alibaba.dubbo.qos.command.CommandContext commandContext, String[] args); diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/CommandContext.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/CommandContext.java index 98f799de2a..6428e1d5fb 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/CommandContext.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/qos/command/CommandContext.java @@ -18,9 +18,9 @@ package com.alibaba.dubbo.qos.command; @Deprecated -public class CommandContext extends org.apache.dubbo.qos.command.CommandContext { +public class CommandContext extends org.apache.dubbo.qos.api.CommandContext { - public CommandContext(org.apache.dubbo.qos.command.CommandContext context) { + public CommandContext(org.apache.dubbo.qos.api.CommandContext context) { super(context.getCommandName(), context.getArgs(), context.isHttp()); setRemote(context.getRemote()); setOriginRequest(context.getOriginRequest()); diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index a973e71da2..1e0501e7d4 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -236,6 +236,13 @@ compile true + + org.apache.dubbo + dubbo-qos-api + ${project.version} + compile + true + org.apache.dubbo dubbo-qos @@ -522,6 +529,7 @@ org.apache.dubbo:dubbo-monitor-api org.apache.dubbo:dubbo-monitor-default org.apache.dubbo:dubbo-qos + org.apache.dubbo:dubbo-qos-api org.apache.dubbo:dubbo-security org.apache.dubbo:dubbo-reactive org.apache.dubbo:dubbo-spring-security @@ -823,7 +831,7 @@ - META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand + META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand dubbo-security ${project.version} + + org.apache.dubbo + dubbo-qos-api + ${project.version} + org.apache.dubbo dubbo-qos diff --git a/dubbo-distribution/dubbo-core-spi/pom.xml b/dubbo-distribution/dubbo-core-spi/pom.xml index 846fde0a74..88939753e9 100644 --- a/dubbo-distribution/dubbo-core-spi/pom.xml +++ b/dubbo-distribution/dubbo-core-spi/pom.xml @@ -416,7 +416,7 @@ - META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand + META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand org.apache.dubbo - dubbo-qos + dubbo-qos-api ${project.parent.version} compile diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java index 0f8536d8b0..9bea988fb1 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterCmd.java @@ -21,9 +21,9 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.JsonUtils; import org.apache.dubbo.metrics.report.MetricsReporter; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.Cmd; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand b/dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand similarity index 100% rename from dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand rename to dubbo-metrics/dubbo-metrics-prometheus/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand diff --git a/dubbo-plugin/dubbo-qos-api/pom.xml b/dubbo-plugin/dubbo-qos-api/pom.xml new file mode 100644 index 0000000000..0e16ca8a17 --- /dev/null +++ b/dubbo-plugin/dubbo-qos-api/pom.xml @@ -0,0 +1,46 @@ + + + + org.apache.dubbo + dubbo-plugin + ${revision} + ../pom.xml + + 4.0.0 + + dubbo-qos-api + dubbo-qos-api + + + UTF-8 + false + + + + + org.apache.dubbo + dubbo-remoting-netty4 + ${project.version} + + + org.apache.dubbo + dubbo-common + ${project.version} + + + diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/BaseCommand.java b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/BaseCommand.java similarity index 96% rename from dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/BaseCommand.java rename to dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/BaseCommand.java index ee4d233024..7e6b353015 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/BaseCommand.java +++ b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/BaseCommand.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.qos.command; +package org.apache.dubbo.qos.api; import org.apache.dubbo.common.extension.ExtensionScope; import org.apache.dubbo.common.extension.SPI; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/annotation/Cmd.java b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/Cmd.java similarity index 94% rename from dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/annotation/Cmd.java rename to dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/Cmd.java index bccc1d77d2..ad890d3c81 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/annotation/Cmd.java +++ b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/Cmd.java @@ -14,9 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.qos.command.annotation; - -import org.apache.dubbo.qos.permission.PermissionLevel; +package org.apache.dubbo.qos.api; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContext.java b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/CommandContext.java similarity index 96% rename from dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContext.java rename to dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/CommandContext.java index fdd92514b1..72557c38ba 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContext.java +++ b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/CommandContext.java @@ -14,9 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.qos.command; - -import org.apache.dubbo.qos.common.QosConfiguration; +package org.apache.dubbo.qos.api; import io.netty.channel.Channel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/PermissionLevel.java b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/PermissionLevel.java similarity index 98% rename from dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/PermissionLevel.java rename to dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/PermissionLevel.java index 9d4a74b160..0d97638673 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/PermissionLevel.java +++ b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/PermissionLevel.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.qos.permission; +package org.apache.dubbo.qos.api; import org.apache.dubbo.common.utils.StringUtils; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/common/QosConfiguration.java b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/QosConfiguration.java similarity index 98% rename from dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/common/QosConfiguration.java rename to dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/QosConfiguration.java index 915022c2df..476079aa14 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/common/QosConfiguration.java +++ b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/QosConfiguration.java @@ -14,16 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.qos.common; +package org.apache.dubbo.qos.api; + +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.common.utils.StringUtils; import java.net.UnknownHostException; import java.util.Arrays; import java.util.function.Predicate; -import org.apache.dubbo.common.utils.NetUtils; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.permission.PermissionLevel; - public class QosConfiguration { private String welcome; private boolean acceptForeignIp; diff --git a/dubbo-plugin/dubbo-qos/pom.xml b/dubbo-plugin/dubbo-qos/pom.xml index 4586a6199a..3a84b3a798 100644 --- a/dubbo-plugin/dubbo-qos/pom.xml +++ b/dubbo-plugin/dubbo-qos/pom.xml @@ -70,5 +70,10 @@ dubbo-serialization-fastjson2 ${project.parent.version} + + org.apache.dubbo + dubbo-qos-api + ${project.version} + diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContextFactory.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContextFactory.java index 5cc3b5d6e3..b18d018a81 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContextFactory.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandContextFactory.java @@ -16,6 +16,8 @@ */ package org.apache.dubbo.qos.command; +import org.apache.dubbo.qos.api.CommandContext; + public class CommandContextFactory { public static CommandContext newInstance(String commandName) { return new CommandContext(commandName); diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandExecutor.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandExecutor.java index 0efec6f090..7bd3448c2d 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandExecutor.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/CommandExecutor.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.qos.command; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.command.exception.NoSuchCommandException; import org.apache.dubbo.qos.command.exception.PermissionDenyException; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java index 19cb8ef82c..441381941d 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/DefaultCommandExecutor.java @@ -19,13 +19,15 @@ package org.apache.dubbo.qos.command; import io.netty.channel.Channel; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.PermissionLevel; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.qos.command.exception.NoSuchCommandException; import org.apache.dubbo.qos.command.exception.PermissionDenyException; import org.apache.dubbo.qos.common.QosConstants; import org.apache.dubbo.qos.permission.DefaultAnonymousAccessPermissionChecker; import org.apache.dubbo.qos.permission.PermissionChecker; -import org.apache.dubbo.qos.permission.PermissionLevel; import org.apache.dubbo.rpc.model.FrameworkModel; import java.util.Arrays; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java index 4aa29375f1..e111e48fab 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoder.java @@ -22,7 +22,7 @@ import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.multipart.Attribute; import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; import io.netty.handler.codec.http.multipart.InterfaceHttpData; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.command.CommandContextFactory; import java.io.IOException; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoder.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoder.java index 3c559a590a..a43220f752 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoder.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoder.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.command.decoder; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.command.CommandContextFactory; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java index 9879d0de92..1832d0b55d 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOffline.java @@ -19,8 +19,8 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.RegistryFactory; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOnline.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOnline.java index a060fb8298..62e85b74bc 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOnline.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/BaseOnline.java @@ -19,8 +19,8 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.RegistryFactory; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java index 2643bd689d..0862823973 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ChangeTelnet.java @@ -17,9 +17,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.Exporter; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java index 8525614430..ef8538f87b 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/CountTelnet.java @@ -18,9 +18,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.telnet.support.TelnetUtils; import org.apache.dubbo.remoting.utils.PayloadDropper; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableDetailProfiler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableDetailProfiler.java index 82b01350ea..058349e018 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableDetailProfiler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableDetailProfiler.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.profiler.ProfilerSwitch; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_PROFILER_DISABLED; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableRouterSnapshot.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableRouterSnapshot.java index a2f9f2efe3..61f6acd5b6 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableRouterSnapshot.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableRouterSnapshot.java @@ -16,9 +16,9 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher; import org.apache.dubbo.rpc.model.ConsumerModel; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableSimpleProfiler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableSimpleProfiler.java index 5bde9b3666..3aace5d25c 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableSimpleProfiler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/DisableSimpleProfiler.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.profiler.ProfilerSwitch; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_PROFILER_DISABLED; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableDetailProfiler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableDetailProfiler.java index a2589f0335..f6dac6e3ec 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableDetailProfiler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableDetailProfiler.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.profiler.ProfilerSwitch; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_PROFILER_ENABLED; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableRouterSnapshot.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableRouterSnapshot.java index ef18cd75fd..47b58ee12c 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableRouterSnapshot.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableRouterSnapshot.java @@ -16,9 +16,9 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher; import org.apache.dubbo.rpc.model.ConsumerModel; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableSimpleProfiler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableSimpleProfiler.java index 14a40a74d1..2d93efda24 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableSimpleProfiler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/EnableSimpleProfiler.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.profiler.ProfilerSwitch; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_PROFILER_ENABLED; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java index 0fa00839f7..11e8884907 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java @@ -32,10 +32,10 @@ import org.apache.dubbo.config.ServiceConfigBase; import org.apache.dubbo.config.SslConfig; import org.apache.dubbo.config.context.ConfigManager; import org.apache.dubbo.config.context.ModuleConfigManager; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetEnabledRouterSnapshot.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetEnabledRouterSnapshot.java index 3f705bad2c..a71be3cdba 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetEnabledRouterSnapshot.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetEnabledRouterSnapshot.java @@ -16,9 +16,9 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRecentRouterSnapshot.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRecentRouterSnapshot.java index 5d14a1cc0b..57bd6c058b 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRecentRouterSnapshot.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRecentRouterSnapshot.java @@ -16,9 +16,9 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java index 497cf52b23..46d5bef84b 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetRouterSnapshot.java @@ -17,9 +17,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.constants.CommonConstants; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.client.migration.MigrationInvoker; import org.apache.dubbo.rpc.cluster.Directory; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java index 5f8a21c12f..60365cd665 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Help.java @@ -17,9 +17,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.qos.command.util.CommandHelper; import org.apache.dubbo.qos.textui.TTable; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java index 8278d09226..f9bdc1b393 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java @@ -21,9 +21,9 @@ import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.JsonUtils; import org.apache.dubbo.common.utils.ReflectUtils; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.MethodDescriptor; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Live.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Live.java index bc4870ac3f..cebd23f2b7 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Live.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Live.java @@ -19,10 +19,10 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.qos.probe.LivenessProbe; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/LoggerInfo.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/LoggerInfo.java index ba08675a35..13a14875e2 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/LoggerInfo.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/LoggerInfo.java @@ -18,9 +18,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.Level; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; @Cmd(name = "loggerInfo", summary = "Print logger info", example = { "loggerInfo" diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java index 188f58224e..bc1d18178a 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ls.java @@ -16,9 +16,9 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.qos.command.util.ServiceCheckUtils; import org.apache.dubbo.qos.textui.TTable; import org.apache.dubbo.rpc.model.ConsumerModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java index e7a5274171..3ad503e63c 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ProviderModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineApp.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineApp.java index 01776be47d..57303a0def 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineApp.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineApp.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.UrlUtils; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ProviderModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineInterface.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineInterface.java index b7bb3ba5a7..e98abab82f 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineInterface.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OfflineInterface.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.UrlUtils; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ProviderModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java index a099a99362..5fab71e847 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; @Cmd(name = "online", summary = "online app addresses", example = { diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java index ed9340cd80..540e7279d6 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java @@ -18,7 +18,7 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.UrlUtils; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ProviderModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java index e4a441bb33..a46b116379 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.UrlUtils; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ProviderModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java index bd983dcfa7..5a2299410d 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PortTelnet.java @@ -17,9 +17,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.remoting.exchange.ExchangeChannel; import org.apache.dubbo.remoting.exchange.ExchangeServer; import org.apache.dubbo.rpc.ProtocolServer; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java index 64f33f7398..30075490a7 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java @@ -20,9 +20,9 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PwdTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PwdTelnet.java index 17c38fe430..06d4a0a38b 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PwdTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PwdTelnet.java @@ -17,9 +17,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import java.util.Arrays; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Quit.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Quit.java index 90e34ea67d..793bcc744d 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Quit.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Quit.java @@ -16,10 +16,10 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.qos.common.QosConstants; @Cmd(name = "quit", summary = "quit telnet console", requiredPermissionLevel = PermissionLevel.PUBLIC) diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ready.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ready.java index 5b5d898a0a..ca1eecf470 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ready.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Ready.java @@ -19,10 +19,10 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.qos.probe.ReadinessProbe; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SelectTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SelectTelnet.java index ff15ed120e..9d7ca8cdea 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SelectTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SelectTelnet.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.ArrayUtils; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.channel.Channel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatus.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatus.java index 70b90cf11e..f2cda861cc 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatus.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatus.java @@ -21,9 +21,9 @@ import java.util.Map; import java.util.stream.Collectors; import org.apache.dubbo.common.utils.JsonUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.qos.command.util.SerializeCheckUtils; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClasses.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClasses.java index 09a61fd700..8a1d053568 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClasses.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClasses.java @@ -21,9 +21,9 @@ import java.util.Map; import java.util.stream.Collectors; import org.apache.dubbo.common.utils.JsonUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.qos.command.util.SerializeCheckUtils; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SetProfilerWarnPercent.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SetProfilerWarnPercent.java index 789c5331e1..f71fba40c8 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SetProfilerWarnPercent.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SetProfilerWarnPercent.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.profiler.ProfilerSwitch; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_PROFILER_WARN_PERCENT; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java index 2c38b3b143..07089481e7 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/ShutdownTelnet.java @@ -17,9 +17,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java index 380ef9672d..ce3f7f1ca4 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Startup.java @@ -19,10 +19,10 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.qos.probe.StartupProbe; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogLevel.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogLevel.java index 930b6dd865..f65fe01e6e 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogLevel.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogLevel.java @@ -18,9 +18,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.Level; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import java.util.Locale; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogger.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogger.java index ec9a31e2bc..bae3d44de9 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogger.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/SwitchLogger.java @@ -18,9 +18,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.logger.Level; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; @Cmd(name = "switchLogger", summary = "Switch logger", example = { diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Version.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Version.java index 5c41e3bc07..907702d1cc 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Version.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Version.java @@ -16,9 +16,9 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; @Cmd(name = "version", summary = "version command(show dubbo version)", example = { "version" diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java index 23bfc3a1a4..926a462b61 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/util/CommandHelper.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.util; -import org.apache.dubbo.qos.command.BaseCommand; +import org.apache.dubbo.qos.api.BaseCommand; import org.apache.dubbo.rpc.model.FrameworkModel; import java.util.ArrayList; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java index 02c5781a7e..8efd756e00 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java @@ -16,10 +16,10 @@ */ package org.apache.dubbo.qos.permission; -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.common.QosConfiguration; - import io.netty.channel.Channel; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.PermissionLevel; +import org.apache.dubbo.qos.api.QosConfiguration; import java.net.InetAddress; import java.net.InetSocketAddress; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/PermissionChecker.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/PermissionChecker.java index c7a8c6675f..33d11c8f7c 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/PermissionChecker.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/PermissionChecker.java @@ -18,7 +18,8 @@ package org.apache.dubbo.qos.permission; import org.apache.dubbo.common.extension.ExtensionScope; import org.apache.dubbo.common.extension.SPI; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.PermissionLevel; // qosPermissionChecker=xxx.xxx.xxxPermissionChecker @SPI(scope = ExtensionScope.FRAMEWORK) diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java index 737388c2a1..ef2f35c3dd 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java @@ -21,7 +21,7 @@ import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.qos.common.QosConstants; import org.apache.dubbo.qos.pu.QosWireProtocol; import org.apache.dubbo.qos.server.Server; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java index 14f20f4cb3..8d27679d6b 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.pu; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.qos.server.DubboLogo; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.qos.server.handler.QosProcessHandler; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.api.AbstractWireProtocol; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java index a7b7c47ff7..d40f858377 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java @@ -16,8 +16,8 @@ */ package org.apache.dubbo.qos.pu; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.command.decoder.TelnetCommandDecoder; import org.apache.dubbo.remoting.api.ProtocolDetector; import org.apache.dubbo.remoting.buffer.ChannelBuffer; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java index 836fa47379..4dc03d1cd7 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java @@ -19,8 +19,8 @@ package org.apache.dubbo.qos.server; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.permission.PermissionLevel; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.PermissionLevel; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.qos.server.handler.QosProcessHandler; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java index d7aafbafec..b9e86242a3 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java @@ -21,7 +21,7 @@ import java.net.InetSocketAddress; import java.util.function.Predicate; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.qos.common.QosConstants; import io.netty.buffer.ByteBuf; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/HttpProcessHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/HttpProcessHandler.java index 0d9acedaab..ef2ec861dd 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/HttpProcessHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/HttpProcessHandler.java @@ -18,13 +18,13 @@ package org.apache.dubbo.qos.server.handler; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.command.CommandExecutor; import org.apache.dubbo.qos.command.DefaultCommandExecutor; import org.apache.dubbo.qos.command.exception.NoSuchCommandException; import org.apache.dubbo.qos.command.exception.PermissionDenyException; import org.apache.dubbo.qos.command.decoder.HttpCommandDecoder; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.buffer.Unpooled; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java index 98cd08741e..40739f8022 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.server.handler; import org.apache.dubbo.common.utils.ExecutorUtil; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.buffer.ByteBuf; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandler.java index d5c7df4121..e2b240cc48 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandler.java @@ -19,14 +19,14 @@ package org.apache.dubbo.qos.server.handler; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.command.CommandExecutor; import org.apache.dubbo.qos.command.DefaultCommandExecutor; import org.apache.dubbo.qos.command.exception.NoSuchCommandException; import org.apache.dubbo.qos.command.exception.PermissionDenyException; import org.apache.dubbo.qos.command.decoder.TelnetCommandDecoder; import org.apache.dubbo.qos.common.QosConstants; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.channel.ChannelFutureListener; diff --git a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand similarity index 100% rename from dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand rename to dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java index fd0957f1e1..31ae32f3d7 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextFactoryTest.java @@ -17,6 +17,7 @@ package org.apache.dubbo.qos.command; +import org.apache.dubbo.qos.api.CommandContext; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java index cb4bc16e71..13d2cce945 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/CommandContextTest.java @@ -18,6 +18,7 @@ package org.apache.dubbo.qos.command; import io.netty.channel.Channel; +import org.apache.dubbo.qos.api.CommandContext; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -53,4 +54,4 @@ class CommandContextTest { assertFalse(context.isHttp()); assertThat(context.getRemote(), is(channel)); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java index c2da2c4b6f..aa2d727f24 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/DefaultCommandExecutorTest.java @@ -17,9 +17,10 @@ package org.apache.dubbo.qos.command; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.PermissionLevel; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.qos.command.exception.NoSuchCommandException; -import org.apache.dubbo.qos.common.QosConfiguration; -import org.apache.dubbo.qos.permission.PermissionLevel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/GreetingCommand.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/GreetingCommand.java index 221a81c0d6..6ad804bfc6 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/GreetingCommand.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/GreetingCommand.java @@ -18,7 +18,9 @@ package org.apache.dubbo.qos.command; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.qos.command.annotation.Cmd; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.Cmd; @Cmd(name = "greeting", summary = "greeting message", example = {"greeting dubbo",}) diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java index d068a51094..58100090e4 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/HttpCommandDecoderTest.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.decoder; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoderTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoderTest.java index 0bf55efc19..41d8d0da41 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoderTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/decoder/TelnetCommandDecoderTest.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.decoder; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.junit.jupiter.api.Test; @@ -33,4 +33,4 @@ class TelnetCommandDecoderTest { assertThat(context.isHttp(), is(false)); assertThat(context.getArgs(), arrayContaining("a", "b")); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ChangeTelnetTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ChangeTelnetTest.java index 1f352a185c..b761a62aeb 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ChangeTelnetTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ChangeTelnetTest.java @@ -18,8 +18,8 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.legacy.service.DemoService; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; @@ -124,4 +124,4 @@ class ChangeTelnetTest { String result = change.execute(mockCommandContext, new String[]{"/"}); assertEquals("Cancelled default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.", result); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/CountTelnetTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/CountTelnetTest.java index 753e3a017e..6e32cb3dd4 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/CountTelnetTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/CountTelnetTest.java @@ -18,8 +18,8 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.command.impl.channel.MockNettyChannel; import org.apache.dubbo.qos.legacy.service.DemoService; import org.apache.dubbo.remoting.telnet.support.TelnetUtils; @@ -118,4 +118,4 @@ class CountTelnetTest { return TelnetUtils.toTable(header, table); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java index bbdc5c255a..77dbf92695 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java @@ -30,7 +30,7 @@ import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.ServiceConfig; import org.apache.dubbo.config.SslConfig; import org.apache.dubbo.metadata.MetadataService; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleModel; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java index 9728fda5a9..e5db43ec08 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/HelpTest.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.Test; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/InvokeTelnetTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/InvokeTelnetTest.java index 3c49226a27..bb534ae6a2 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/InvokeTelnetTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/InvokeTelnetTest.java @@ -17,8 +17,8 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.config.bootstrap.DubboBootstrap; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.legacy.service.DemoService; import org.apache.dubbo.qos.legacy.service.DemoServiceImpl; import org.apache.dubbo.remoting.RemotingException; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LiveTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LiveTest.java index a54d81e4d1..60da31680a 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LiveTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LiveTest.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.AfterEach; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java index 335a7a4b05..6cb56e4259 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java @@ -20,7 +20,7 @@ import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.qos.DemoService; import org.apache.dubbo.qos.DemoServiceImpl; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.AsyncMethodInfo; import org.apache.dubbo.rpc.model.ConsumerModel; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java index 2c665abfe5..7196e36e38 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java @@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.qos.DemoService; import org.apache.dubbo.qos.DemoServiceImpl; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.registry.RegistryService; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleServiceRepository; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java index f5c4cf0d20..ef13b34b1d 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java @@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.qos.DemoService; import org.apache.dubbo.qos.DemoServiceImpl; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.registry.RegistryService; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleServiceRepository; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PortTelnetTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PortTelnetTest.java index 2088c340c7..72bd1f71e5 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PortTelnetTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PortTelnetTest.java @@ -18,8 +18,8 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.NetUtils; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.legacy.service.DemoService; import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.exchange.ExchangeClient; @@ -108,4 +108,4 @@ class PortTelnetTest { String result = port.execute(mockCommandContext, new String[]{"-l", "20880"}); assertEquals("No such port 20880", result); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PublishMetadataTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PublishMetadataTest.java index 0b3f02bfe4..ebd54524df 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PublishMetadataTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PublishMetadataTest.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PwdTelnetTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PwdTelnetTest.java index f3dfc521c0..21ca70c9f2 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PwdTelnetTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/PwdTelnetTest.java @@ -16,8 +16,8 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.rpc.model.FrameworkModel; @@ -74,4 +74,4 @@ class PwdTelnetTest { String result = pwdTelnet.execute(mockCommandContext, new String[]{"test"}); assertEquals("Unsupported parameter [test] for pwd.", result); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/QuitTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/QuitTest.java index ba12a8b2a5..9a99502d66 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/QuitTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/QuitTest.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.common.QosConstants; import org.junit.jupiter.api.Test; @@ -32,4 +32,4 @@ class QuitTest { String output = quit.execute(Mockito.mock(CommandContext.class), null); assertThat(output, equalTo(QosConstants.CLOSE)); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ReadyTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ReadyTest.java index 07a6bb9f82..01152d9ef3 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ReadyTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ReadyTest.java @@ -22,7 +22,7 @@ import org.apache.dubbo.common.deploy.ModuleDeployer; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.context.ConfigManager; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.probe.ReadinessProbe; import org.apache.dubbo.qos.probe.impl.DeployerReadinessProbe; import org.apache.dubbo.qos.probe.impl.ProviderReadinessProbe; @@ -89,4 +89,4 @@ class ReadyTest { Assertions.assertEquals("false", result); Assertions.assertEquals(commandContext.getHttpCode(), 503); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SelectTelnetTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SelectTelnetTest.java index 4fc5f7d649..b18b6ebfd7 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SelectTelnetTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SelectTelnetTest.java @@ -17,8 +17,8 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.config.bootstrap.DubboBootstrap; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.legacy.service.DemoService; import org.apache.dubbo.qos.legacy.service.DemoServiceImpl; import org.apache.dubbo.remoting.RemotingException; @@ -144,4 +144,4 @@ class SelectTelnetTest { null ); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatusTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatusTest.java index f7ee1d69d1..162c7a8040 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatusTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeCheckStatusTest.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.SerializeSecurityManager; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.Assertions; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClassesTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClassesTest.java index d772e75713..91b88a5113 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClassesTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/SerializeWarnedClassesTest.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.common.utils.SerializeSecurityManager; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.Assertions; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ShutdownTelnetTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ShutdownTelnetTest.java index dcaf89fb6b..7d93525da2 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ShutdownTelnetTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/ShutdownTelnetTest.java @@ -16,8 +16,8 @@ */ package org.apache.dubbo.qos.command.impl; -import org.apache.dubbo.qos.command.BaseCommand; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.BaseCommand; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.rpc.model.FrameworkModel; @@ -66,4 +66,4 @@ class ShutdownTelnetTest { assertTrue(result.contains("Application has shutdown successfully"), result); assertTrue((end - start) >= sleepTime, "sleepTime: " + sleepTime + ", execTime: " + (end - start)); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/StartupTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/StartupTest.java index 845f95e5fc..0676e0ab19 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/StartupTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/StartupTest.java @@ -22,7 +22,7 @@ import org.apache.dubbo.common.deploy.ModuleDeployer; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.context.ConfigManager; -import org.apache.dubbo.qos.command.CommandContext; +import org.apache.dubbo.qos.api.CommandContext; import org.apache.dubbo.qos.probe.StartupProbe; import org.apache.dubbo.qos.probe.impl.DeployerStartupProbe; import org.apache.dubbo.rpc.model.ApplicationModel; @@ -80,4 +80,4 @@ class StartupTest { Assertions.assertEquals("false", result); Assertions.assertEquals(commandContext.getHttpCode(), 503); } -} \ No newline at end of file +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java index bb6c80caec..11f466ca39 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java @@ -16,17 +16,17 @@ */ package org.apache.dubbo.qos.permission; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; - -import org.apache.dubbo.qos.command.CommandContext; -import org.apache.dubbo.qos.common.QosConfiguration; +import io.netty.channel.Channel; +import org.apache.dubbo.qos.api.CommandContext; +import org.apache.dubbo.qos.api.PermissionLevel; +import org.apache.dubbo.qos.api.QosConfiguration; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import io.netty.channel.Channel; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; class DefaultAnonymousAccessPermissionCheckerTest { @Test diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/protocol/QosProtocolWrapperTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/protocol/QosProtocolWrapperTest.java index da6f5c4663..f3b0def49c 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/protocol/QosProtocolWrapperTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/protocol/QosProtocolWrapperTest.java @@ -18,7 +18,7 @@ package org.apache.dubbo.qos.protocol; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.constants.CommonConstants; -import org.apache.dubbo.qos.command.BaseCommand; +import org.apache.dubbo.qos.api.BaseCommand; import org.apache.dubbo.qos.server.Server; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java index 91bd5f9092..574d1171d1 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java @@ -22,8 +22,8 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.permission.PermissionLevel; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.PermissionLevel; +import org.apache.dubbo.qos.api.QosConfiguration; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/HttpProcessHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/HttpProcessHandlerTest.java index 820b09c850..7afb2becab 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/HttpProcessHandlerTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/HttpProcessHandlerTest.java @@ -16,8 +16,8 @@ */ package org.apache.dubbo.qos.server.handler; -import org.apache.dubbo.qos.common.QosConfiguration; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.QosConfiguration; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.channel.ChannelFuture; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java index dbac3e68b1..487496e019 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java @@ -17,7 +17,7 @@ package org.apache.dubbo.qos.server.handler; import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.qos.common.QosConfiguration; +import org.apache.dubbo.qos.api.QosConfiguration; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.buffer.ByteBuf; diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandlerTest.java index 2a526931ce..045bcd3942 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandlerTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/TelnetProcessHandlerTest.java @@ -16,8 +16,8 @@ */ package org.apache.dubbo.qos.server.handler; -import org.apache.dubbo.qos.common.QosConfiguration; -import org.apache.dubbo.qos.permission.PermissionLevel; +import org.apache.dubbo.qos.api.QosConfiguration; +import org.apache.dubbo.qos.api.PermissionLevel; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.channel.ChannelFuture; diff --git a/dubbo-plugin/dubbo-qos/src/test/resources/META-INF/services/org.apache.dubbo.qos.command.BaseCommand b/dubbo-plugin/dubbo-qos/src/test/resources/META-INF/services/org.apache.dubbo.qos.api.BaseCommand similarity index 100% rename from dubbo-plugin/dubbo-qos/src/test/resources/META-INF/services/org.apache.dubbo.qos.command.BaseCommand rename to dubbo-plugin/dubbo-qos/src/test/resources/META-INF/services/org.apache.dubbo.qos.api.BaseCommand diff --git a/dubbo-plugin/pom.xml b/dubbo-plugin/pom.xml index 1266f7e313..afc7e65b76 100644 --- a/dubbo-plugin/pom.xml +++ b/dubbo-plugin/pom.xml @@ -34,6 +34,7 @@ dubbo-reactive dubbo-security dubbo-spring-security + dubbo-qos-api false diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index 4494617120..e085b0bd8c 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -198,6 +198,10 @@ org.apache.dubbo dubbo-security + + org.apache.dubbo + dubbo-qos-api + org.apache.dubbo dubbo-qos From 2f4944e85385978e24486338cb41b4620ab00339 Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Fri, 17 Mar 2023 13:46:04 +0800 Subject: [PATCH 138/144] Interface level registry metrics (#11786) * fix * remove unuse * add serviceKey subscribe * fix method refact * remove unuse * remove unuse * fix npe * fix npe * fix npe * add event validate * fix testcase --------- Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../cluster/directory/AbstractDirectory.java | 10 +-- .../dubbo/rpc/model/ApplicationModel.java | 5 ++ .../apache/dubbo/config/ServiceConfig.java | 29 +++++- .../deploy/DefaultApplicationDeployer.java | 6 +- .../ApplicationMetricsCollector.java | 2 +- .../event/SimpleMetricsEventMulticaster.java | 13 ++- .../metrics/model/ApplicationMetric.java | 8 ++ .../dubbo/metrics/model/MetricsKey.java | 10 +++ .../collector/MetadataMetricsCollector.java | 2 +- .../metadata/event/MetricsPushListener.java | 4 +- .../event/MetricsSubscribeListener.java | 4 +- .../collector/RegistryMetricsCollector.java | 26 ++++-- .../collector/stat/RegistryStatComposite.java | 90 +++++++++++++------ .../registry/event/MetricsNotifyListener.java | 6 +- .../event/MetricsRegisterListener.java | 20 ++--- .../event/MetricsServiceRegisterListener.java | 51 +++++++++++ .../MetricsServiceSubscribeListener.java | 52 +++++++++++ .../event/MetricsSubscribeListener.java | 10 +-- .../metrics/registry/event/RegistryEvent.java | 89 +++++++++++++++--- .../RegistryMetricsEventMulticaster.java | 2 + .../RegistryMetricsCollectorTest.java | 8 +- .../collector/RegistryMetricsSampleTest.java | 6 +- .../collector/RegistryStatCompositeTest.java | 18 ++-- .../client/ServiceDiscoveryRegistry.java | 18 +++- 24 files changed, 392 insertions(+), 97 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java create mode 100644 dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceSubscribeListener.java diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java index 9d3dc1e827..9109286382 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java @@ -396,7 +396,7 @@ public abstract class AbstractDirectory implements Directory { @Override public void addDisabledInvoker(Invoker invoker) { - publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_DISABLE)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_DISABLE)); if (invokers.contains(invoker)) { disabledInvokers.add(invoker); removeValidInvoker(invoker); @@ -406,7 +406,7 @@ public abstract class AbstractDirectory implements Directory { @Override public void recoverDisabledInvoker(Invoker invoker) { - publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_RECOVER_DISABLE)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_RECOVER_DISABLE)); if (disabledInvokers.remove(invoker)) { try { addValidInvoker(invoker); @@ -470,7 +470,7 @@ public abstract class AbstractDirectory implements Directory { this.invokers = invokers; refreshInvokerInternal(); this.invokersInitialized = true; - publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_CURRENT, invokers.size())); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_CURRENT, invokers.size())); } protected void destroyInvokers() { @@ -481,14 +481,14 @@ public abstract class AbstractDirectory implements Directory { } private boolean addValidInvoker(Invoker invoker) { - publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_VALID)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_VALID)); synchronized (this.validInvokers) { return this.validInvokers.add(invoker); } } private boolean removeValidInvoker(Invoker invoker) { - publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.Type.D_UN_VALID)); + publishMetricsEvent(new RegistryEvent.MetricsDirectoryEvent(applicationModel, RegistryEvent.ApplicationType.D_UN_VALID)); synchronized (this.validInvokers) { return this.validInvokers.remove(invoker); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java index 5f7800346a..c0f1e3cf10 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java @@ -84,6 +84,7 @@ public class ApplicationModel extends ScopeModel { * During destroying the default FrameworkModel, the FrameworkModel.defaultModel() or ApplicationModel.defaultModel() * will return a broken model, maybe cause unpredictable problem. * Recommendation: Avoid using the default model as much as possible. + * * @return the global default ApplicationModel */ public static ApplicationModel defaultModel() { @@ -224,6 +225,10 @@ public class ApplicationModel extends ScopeModel { return ExecutorRepository.getInstance(this); } + public boolean NotExistApplicationConfig() { + return !getApplicationConfigManager().getApplication().isPresent(); + } + public ApplicationConfig getCurrentConfig() { return getApplicationConfigManager().getApplicationOrElseThrow(); } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java index 204d09777d..940da27c35 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java @@ -36,13 +36,18 @@ import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker; import org.apache.dubbo.config.support.Parameter; import org.apache.dubbo.config.utils.ConfigValidationUtils; import org.apache.dubbo.metadata.ServiceNameMapping; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.registry.client.metadata.MetadataUtils; import org.apache.dubbo.rpc.Exporter; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.ProxyFactory; +import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.ServerService; import org.apache.dubbo.rpc.cluster.ConfiguratorFactory; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.model.ModuleServiceRepository; import org.apache.dubbo.rpc.model.ProviderModel; @@ -421,6 +426,17 @@ public class ServiceConfig extends ServiceConfigBase { List registryURLs = ConfigValidationUtils.loadRegistries(this, true); + TimePair timePair = TimePair.start(); + ApplicationModel applicationModel = module.getApplicationModel(); + try { + applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); + } catch (Throwable t) { + applicationModel = ApplicationModel.defaultModel(); + } + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); + int size = protocols.size() * registryURLs.size(); + eventMulticaster.publishEvent(new RegistryEvent.MetricsServiceRegisterEvent(applicationModel, timePair, getUniqueServiceName(), size)); + for (ProtocolConfig protocolConfig : protocols) { String pathKey = URL.buildKey(getContextPath(protocolConfig) .map(p -> p + "/" + path) @@ -430,9 +446,14 @@ public class ServiceConfig extends ServiceConfigBase { // In case user specified path, register service one more time to map it to path. repository.registerService(pathKey, interfaceClass); } - doExportUrlsFor1Protocol(protocolConfig, registryURLs); + try { + doExportUrlsFor1Protocol(protocolConfig, registryURLs); + } catch (RpcException e) { + eventMulticaster.publishErrorEvent(new RegistryEvent.MetricsServiceRegisterEvent(applicationModel, timePair, getUniqueServiceName(), registryURLs.size())); + throw e; + } } - + eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsServiceRegisterEvent(applicationModel, timePair, getUniqueServiceName(), size)); providerModel.setServiceUrls(urls); } @@ -665,8 +686,8 @@ public class ServiceConfig extends ServiceConfigBase { protocols.addAll(Arrays.asList(extProtocols)); } // export extra protocols - for(String protocol : protocols) { - if(StringUtils.isNotBlank(protocol)){ + for (String protocol : protocols) { + if (StringUtils.isNotBlank(protocol)) { URL localUrl = URLBuilder.from(url). setProtocol(protocol). build(); diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index 3e4221737a..12d29ff2e5 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -831,13 +831,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer extends void increment(String applicationName, T type); - void addRT(String applicationName, String registryOpType, Long responseTime); + void addApplicationRT(String applicationName, String registryOpType, Long responseTime); } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java index c3f187c82e..64e393cc53 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/event/SimpleMetricsEventMulticaster.java @@ -19,6 +19,7 @@ package org.apache.dubbo.metrics.event; import org.apache.dubbo.metrics.listener.MetricsLifeListener; import org.apache.dubbo.metrics.listener.MetricsListener; +import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.ArrayList; import java.util.Collections; @@ -26,7 +27,7 @@ import java.util.List; import java.util.function.Consumer; /** - * A simple event publisher that defines lifecycle events and supports rt events + * A simple event publisher that defines lifecycle events and supports rt events */ public class SimpleMetricsEventMulticaster implements MetricsEventMulticaster { private final List> listeners = Collections.synchronizedList(new ArrayList<>()); @@ -52,6 +53,7 @@ public class SimpleMetricsEventMulticaster implements MetricsEventMulticaster { if (event instanceof EmptyEvent) { return; } + if (validateIfSourceInstanceOfApplicationModel(event)) return; for (MetricsListener listener : listeners) { if (listener.isSupport(event)) { listener.onEvent(event); @@ -59,6 +61,14 @@ public class SimpleMetricsEventMulticaster implements MetricsEventMulticaster { } } + private boolean validateIfSourceInstanceOfApplicationModel(MetricsEvent event) { + if (event.getSource() instanceof ApplicationModel) { + // Check if exist application config + return ((ApplicationModel) event.getSource()).NotExistApplicationConfig(); + } + return false; + } + @Override @SuppressWarnings({"unchecked"}) public void publishFinishEvent(MetricsEvent event) { @@ -73,6 +83,7 @@ public class SimpleMetricsEventMulticaster implements MetricsEventMulticaster { @SuppressWarnings({"rawtypes"}) private void publishTimeEvent(MetricsEvent event, Consumer consumer) { + if (validateIfSourceInstanceOfApplicationModel(event)) return; if (event instanceof EmptyEvent) { return; } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java index b0e583806f..cc1b4abba6 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/ApplicationMetric.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Map; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME; +import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME; import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_VERSION_KEY; @@ -60,4 +61,11 @@ public class ApplicationMetric implements Metric { tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId); return tags; } + + public static Map getServiceTags(String appAndServiceName) { + String[] keys = appAndServiceName.split("_"); + Map tags = getTagsByName(keys[0]); + tags.put(TAG_INTERFACE_KEY, keys[1]); + return tags; + } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java index 8fe6d1a96e..a931adcb19 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/MetricsKey.java @@ -91,6 +91,16 @@ public enum MetricsKey { METADATA_SUBSCRIBE_METRIC_NUM("dubbo.metadata.subscribe.num.total", "Total Metadata Subscribe Num"), METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.metadata.subscribe.num.succeed.total", "Succeed Metadata Subscribe Num"), METADATA_SUBSCRIBE_METRIC_NUM_FAILED("dubbo.metadata.subscribe.num.failed.total", "Failed Metadata Subscribe Num"), + + // register service metrics key + SERVICE_REGISTER_METRIC_REQUESTS("dubbo.registry.register.service.total", "Total Service-Level Register Requests"), + SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED("dubbo.registry.register.service.succeed.total", "Succeed Service-Level Register Requests"), + SERVICE_REGISTER_METRIC_REQUESTS_FAILED("dubbo.registry.register.service.failed.total", "Failed Service-Level Register Requests"), + + // subscribe metrics key + SERVICE_SUBSCRIBE_METRIC_NUM("dubbo.registry.subscribe.service.num.total", "Total Service-Level Subscribe Num"), + SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.registry.subscribe.service.num.succeed.total", "Succeed Service-Level Num"), + SERVICE_SUBSCRIBE_METRIC_NUM_FAILED("dubbo.registry.subscribe.service.num.failed.total", "Failed Service-Level Num"), METADATA_GIT_COMMITID_METRIC("git.commit.id","Git Commit Id Metrics"); // consumer metrics key ; diff --git a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java index c9140a288c..405abe7390 100644 --- a/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-metadata/src/main/java/org/apache/dubbo/metrics/metadata/collector/MetadataMetricsCollector.java @@ -72,7 +72,7 @@ public class MetadataMetricsCollector implements ApplicationMetricsCollector { +public class RegistryMetricsCollector implements ApplicationMetricsCollector { private Boolean collectEnabled = null; private final RegistryStatComposite stats; @@ -67,31 +67,43 @@ public class RegistryMetricsCollector implements ApplicationMetricsCollector lastNumMap) { + public void setNum(RegistryEvent.ServiceType registryType, String applicationName, Map lastNumMap) { lastNumMap.forEach((serviceKey, num) -> this.stats.setServiceKey(registryType, applicationName, serviceKey, num)); } - public void setNum(RegistryEvent.Type registryType, String applicationName, Integer num) { + public void setNum(RegistryEvent.ApplicationType registryType, String applicationName, Integer num) { this.stats.setApplicationKey(registryType, applicationName, num); } @Override - public void increment(String applicationName, RegistryEvent.Type registryType) { + public void increment(String applicationName, RegistryEvent.ApplicationType registryType) { this.stats.increment(registryType, applicationName); } + public void increment(String applicationName, RegistryEvent.ApplicationType registryType, int size) { + this.stats.incrementSize(registryType, applicationName, size); + } + + public void incrementServiceKey(String applicationName, String serviceKey, RegistryEvent.ServiceType registryType, int size) { + this.stats.incrementServiceKey(registryType, applicationName, serviceKey, size); + } + @Override - public void addRT(String applicationName, String registryOpType, Long responseTime) { - stats.calcRt(applicationName, registryOpType, responseTime); + public void addApplicationRT(String applicationName, String registryOpType, Long responseTime) { + stats.calcApplicationRt(applicationName, registryOpType, responseTime); + } + + public void addServiceKeyRT(String applicationName, String serviceKey, String registryOpType, Long responseTime) { + stats.calcServiceKeyRt(applicationName, serviceKey, registryOpType, responseTime); } @Override public List collect() { List list = new ArrayList<>(); if (!isCollectEnabled()) { - return list; + return list; } list.addAll(stats.exportNumMetrics()); list.addAll(stats.exportRtMetrics()); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java index 9bfa2532e5..864499bbc3 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/collector/stat/RegistryStatComposite.java @@ -36,6 +36,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAccumulator; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -46,21 +47,35 @@ import java.util.stream.Collectors; public class RegistryStatComposite implements MetricsExport { - public Map> numStats = new ConcurrentHashMap<>(); - public Map> skStats = new ConcurrentHashMap<>(); - public List> rtStats = new ArrayList<>(); + public Map> applicationNumStats = new ConcurrentHashMap<>(); + public Map> serviceNumStats = new ConcurrentHashMap<>(); + public Map> skStats = new ConcurrentHashMap<>(); + public List> appRtStats = new ArrayList<>(); + public List> serviceRtStats = new ArrayList<>(); public static String OP_TYPE_REGISTER = "register"; public static String OP_TYPE_SUBSCRIBE = "subscribe"; public static String OP_TYPE_NOTIFY = "notify"; + public static String OP_TYPE_REGISTER_SERVICE = "register.service"; + public static String OP_TYPE_SUBSCRIBE_SERVICE = "subscribe.service"; public RegistryStatComposite() { - for (RegistryEvent.Type type : RegistryEvent.Type.values()) { - numStats.put(type, new ConcurrentHashMap<>()); + for (RegistryEvent.ApplicationType type : RegistryEvent.ApplicationType.values()) { + // Application key and increment val + applicationNumStats.put(type, new ConcurrentHashMap<>()); } - rtStats.addAll(initStats(OP_TYPE_REGISTER)); - rtStats.addAll(initStats(OP_TYPE_SUBSCRIBE)); - rtStats.addAll(initStats(OP_TYPE_NOTIFY)); + for (RegistryEvent.ServiceType type : RegistryEvent.ServiceType.values()) { + // Service key + skStats.put(type, new ConcurrentHashMap<>()); + } + + + appRtStats.addAll(initStats(OP_TYPE_REGISTER)); + appRtStats.addAll(initStats(OP_TYPE_SUBSCRIBE)); + appRtStats.addAll(initStats(OP_TYPE_NOTIFY)); + + serviceRtStats.addAll(initStats(OP_TYPE_REGISTER_SERVICE)); + serviceRtStats.addAll(initStats(OP_TYPE_SUBSCRIBE_SERVICE)); } private List> initStats(String registryOpType) { @@ -72,7 +87,7 @@ public class RegistryStatComposite implements MetricsExport { // AvgContainer is a special counter that stores the number of times but outputs function of sum/times AtomicLongContainer avgContainer = new AtomicLongContainer(new MetricsKeyWrapper(registryOpType, MetricsKey.METRIC_RT_AVG), (k, v) -> v.incrementAndGet()); avgContainer.setValueSupplier(applicationName -> { - LongContainer totalContainer = rtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.METRIC_RT_SUM, registryOpType)).findFirst().get(); + LongContainer totalContainer = appRtStats.stream().filter(longContainer -> longContainer.isKeyWrapper(MetricsKey.METRIC_RT_SUM, registryOpType)).findFirst().get(); AtomicLong totalRtTimes = avgContainer.get(applicationName); AtomicLong totalRtSum = (AtomicLong) totalContainer.get(applicationName); return totalRtSum.get() / totalRtTimes.get(); @@ -81,41 +96,60 @@ public class RegistryStatComposite implements MetricsExport { return singleRtStats; } - public void setApplicationKey(RegistryEvent.Type type, String applicationName, int num) { - if (!numStats.containsKey(type)) { + public void setApplicationKey(RegistryEvent.ApplicationType type, String applicationName, int num) { + if (!applicationNumStats.containsKey(type)) { return; } - numStats.get(type).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).set(num); + applicationNumStats.get(type).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).set(num); } - public void setServiceKey(RegistryEvent.Type type, String applicationName, String serviceKey, int num) { + public void setServiceKey(RegistryEvent.ServiceType type, String applicationName, String serviceKey, int num) { if (!skStats.containsKey(type)) { return; } skStats.get(type).computeIfAbsent(new ServiceKeyMetric(applicationName, serviceKey), k -> new AtomicLong(0L)).set(num); } - public void increment(RegistryEvent.Type type, String applicationName) { - if (!numStats.containsKey(type)) { + public void increment(RegistryEvent.ApplicationType type, String applicationName) { + incrementSize(type, applicationName, 1); + } + + public void incrementServiceKey(RegistryEvent.ServiceType type, String applicationName, String serviceKey, int size) { + if (!skStats.containsKey(type)) { return; } - numStats.get(type).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).incrementAndGet(); + skStats.get(type).computeIfAbsent(new ServiceKeyMetric(applicationName, serviceKey), k -> new AtomicLong(0L)).getAndAdd(size); + } + + public void incrementSize(RegistryEvent.ApplicationType type, String applicationName, int size) { + if (!applicationNumStats.containsKey(type)) { + return; + } + applicationNumStats.get(type).computeIfAbsent(applicationName, k -> new AtomicLong(0L)).getAndAdd(size); } @SuppressWarnings({"rawtypes", "unchecked"}) - public void calcRt(String applicationName, String registryOpType, Long responseTime) { - for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { + public void calcApplicationRt(String applicationName, String registryOpType, Long responseTime) { + for (LongContainer container : appRtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, applicationName, container.getInitFunc()); container.getConsumerFunc().accept(responseTime, current); } } + @SuppressWarnings({"rawtypes", "unchecked"}) + public void calcServiceKeyRt(String applicationName, String serviceKey, String registryOpType, Long responseTime) { + for (LongContainer container : serviceRtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { + Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, applicationName + "_" + serviceKey, container.getInitFunc()); + container.getConsumerFunc().accept(responseTime, current); + } + } + @Override @SuppressWarnings({"rawtypes"}) public List exportNumMetrics() { List list = new ArrayList<>(); - for (RegistryEvent.Type type : numStats.keySet()) { - Map stringAtomicLongMap = numStats.get(type); + for (RegistryEvent.ApplicationType type : applicationNumStats.keySet()) { + Map stringAtomicLongMap = applicationNumStats.get(type); for (String applicationName : stringAtomicLongMap.keySet()) { list.add(convertToSample(applicationName, type, MetricsCategory.REGISTRY, stringAtomicLongMap.get(applicationName))); } @@ -126,20 +160,26 @@ public class RegistryStatComposite implements MetricsExport { @Override @SuppressWarnings({"rawtypes"}) public List exportRtMetrics() { - List list = new ArrayList<>(); + List result = new ArrayList<>(); + doExportRt(result, appRtStats, ApplicationMetric::getTagsByName); + doExportRt(result, serviceRtStats, ApplicationMetric::getServiceTags); + return result; + } + + @SuppressWarnings({"rawtypes"}) + private void doExportRt(List list, List> rtStats, Function> tagNameFunc) { for (LongContainer rtContainer : rtStats) { MetricsKeyWrapper metricsKeyWrapper = rtContainer.getMetricsKeyWrapper(); for (Map.Entry entry : rtContainer.entrySet()) { - list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), ApplicationMetric.getTagsByName(entry.getKey()), MetricsCategory.RT, entry.getKey().intern(), value -> rtContainer.getValueSupplier().apply(value.intern()))); + list.add(new GaugeMetricSample<>(metricsKeyWrapper.targetKey(), metricsKeyWrapper.targetDesc(), tagNameFunc.apply(entry.getKey()), MetricsCategory.RT, entry.getKey().intern(), value -> rtContainer.getValueSupplier().apply(value.intern()))); } } - return list; } @SuppressWarnings({"rawtypes"}) public List exportSkMetrics() { List list = new ArrayList<>(); - for (RegistryEvent.Type type : skStats.keySet()) { + for (RegistryEvent.ServiceType type : skStats.keySet()) { Map stringAtomicLongMap = skStats.get(type); for (ServiceKeyMetric serviceKeyMetric : stringAtomicLongMap.keySet()) { list.add(new GaugeMetricSample<>(type.getMetricsKey(), serviceKeyMetric.getTags(), MetricsCategory.REGISTRY, stringAtomicLongMap, value -> value.get(serviceKeyMetric).get())); @@ -149,7 +189,7 @@ public class RegistryStatComposite implements MetricsExport { } @SuppressWarnings({"rawtypes"}) - public GaugeMetricSample convertToSample(String applicationName, RegistryEvent.Type type, MetricsCategory category, AtomicLong targetNumber) { + public GaugeMetricSample convertToSample(String applicationName, RegistryEvent.ApplicationType type, MetricsCategory category, AtomicLong targetNumber) { return new GaugeMetricSample<>(type.getMetricsKey(), ApplicationMetric.getTagsByName(applicationName), category, targetNumber, AtomicLong::get); } } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java index 3b5561cb1f..6dd7828faf 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsNotifyListener.java @@ -38,13 +38,13 @@ public class MetricsNotifyListener implements MetricsLifeListener { +public class MetricsRegisterListener implements MetricsLifeListener { @Override public boolean isSupport(MetricsEvent event) { - return event instanceof RegistryEvent.MetricsRegisterEvent; + return event instanceof RegistryEvent.MetricsApplicationRegisterEvent; } @Override - public void onEvent(RegistryEvent.MetricsRegisterEvent event) { + public void onEvent(RegistryEvent.MetricsApplicationRegisterEvent event) { if (!event.isAvailable()) { return; } - event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.R_TOTAL); + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.ApplicationType.R_TOTAL); } @Override - public void onEventFinish(RegistryEvent.MetricsRegisterEvent event) { - event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.R_SUCCEED); - event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_REGISTER, event.getTimePair().calc()); + public void onEventFinish(RegistryEvent.MetricsApplicationRegisterEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.ApplicationType.R_SUCCEED); + event.getCollector().addApplicationRT(event.getSource().getApplicationName(), OP_TYPE_REGISTER, event.getTimePair().calc()); } @Override - public void onEventError(RegistryEvent.MetricsRegisterEvent event) { - event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.Type.R_FAILED); - event.getCollector().addRT(event.getSource().getApplicationName(), OP_TYPE_REGISTER, event.getTimePair().calc()); + public void onEventError(RegistryEvent.MetricsApplicationRegisterEvent event) { + event.getCollector().increment(event.getSource().getApplicationName(), RegistryEvent.ApplicationType.R_FAILED); + event.getCollector().addApplicationRT(event.getSource().getApplicationName(), OP_TYPE_REGISTER, event.getTimePair().calc()); } } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java new file mode 100644 index 0000000000..e99ce7a75d --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceRegisterListener.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.metrics.registry.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; + +import static org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_REGISTER_SERVICE; + +public class MetricsServiceRegisterListener implements MetricsLifeListener { + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof RegistryEvent.MetricsServiceRegisterEvent; + } + + @Override + public void onEvent(RegistryEvent.MetricsServiceRegisterEvent event) { + if (!event.isAvailable()) { + return; + } + event.getCollector().incrementServiceKey(event.getSource().getApplicationName(), event.getServiceKey(), RegistryEvent.ServiceType.R_SERVICE_TOTAL, event.getSize()); + } + + @Override + public void onEventFinish(RegistryEvent.MetricsServiceRegisterEvent event) { + event.getCollector().incrementServiceKey(event.getSource().getApplicationName(), event.getServiceKey(), RegistryEvent.ServiceType.R_SERVICE_SUCCEED, event.getSize()); + event.getCollector().addServiceKeyRT(event.getSource().getApplicationName(), event.getServiceKey(), OP_TYPE_REGISTER_SERVICE, event.getTimePair().calc()); + } + + @Override + public void onEventError(RegistryEvent.MetricsServiceRegisterEvent event) { + event.getCollector().incrementServiceKey(event.getSource().getApplicationName(), event.getServiceKey(), RegistryEvent.ServiceType.R_SERVICE_FAILED, event.getSize()); + event.getCollector().addApplicationRT(event.getSource().getApplicationName(), OP_TYPE_REGISTER_SERVICE, event.getTimePair().calc()); + } +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceSubscribeListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceSubscribeListener.java new file mode 100644 index 0000000000..02062016dd --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsServiceSubscribeListener.java @@ -0,0 +1,52 @@ +/* + * 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.metrics.registry.event; + +import org.apache.dubbo.metrics.event.MetricsEvent; +import org.apache.dubbo.metrics.listener.MetricsLifeListener; + +import static org.apache.dubbo.metrics.registry.collector.stat.RegistryStatComposite.OP_TYPE_SUBSCRIBE_SERVICE; + +public class MetricsServiceSubscribeListener implements MetricsLifeListener { + + @Override + public boolean isSupport(MetricsEvent event) { + return event instanceof RegistryEvent.MetricsServiceSubscribeEvent; + } + + @Override + public void onEvent(RegistryEvent.MetricsServiceSubscribeEvent event) { + if (!event.isAvailable()) { + return; + } + event.getCollector().incrementServiceKey(event.getSource().getApplicationName(), event.getUniqueServiceName(), RegistryEvent.ServiceType.S_SERVICE_TOTAL, 1); + } + + @Override + public void onEventFinish(RegistryEvent.MetricsServiceSubscribeEvent event) { + event.getCollector().incrementServiceKey(event.getSource().getApplicationName(), event.getUniqueServiceName(), RegistryEvent.ServiceType.S_SERVICE_SUCCEED, 1); + event.getCollector().addApplicationRT(event.getSource().getApplicationName(), OP_TYPE_SUBSCRIBE_SERVICE, event.getTimePair().calc()); + } + + @Override + public void onEventError(RegistryEvent.MetricsServiceSubscribeEvent event) { + event.getCollector().incrementServiceKey(event.getSource().getApplicationName(), event.getUniqueServiceName(), RegistryEvent.ServiceType.S_SERVICE_FAILED, 1); + event.getCollector().addApplicationRT(event.getSource().getApplicationName(), OP_TYPE_SUBSCRIBE_SERVICE, event.getTimePair().calc()); + } + +} diff --git a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java index abfc5a0624..1caf41c489 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/main/java/org/apache/dubbo/metrics/registry/event/MetricsSubscribeListener.java @@ -34,19 +34,19 @@ public class MetricsSubscribeListener implements MetricsLifeListener metricSamples = collector.collect(); // push success +1 Assertions.assertEquals(1, metricSamples.size()); Assertions.assertTrue(metricSamples.get(0) instanceof GaugeMetricSample); - eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, timePair)); + eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsApplicationRegisterEvent(applicationModel, timePair)); // push finish rt +1 metricSamples = collector.collect(); //num(total+success) + rt(5) = 7 Assertions.assertEquals(7, metricSamples.size()); long c1 = timePair.calc(); TimePair lastTimePair = TimePair.start(); - eventMulticaster.publishEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, lastTimePair)); + eventMulticaster.publishEvent(new RegistryEvent.MetricsApplicationRegisterEvent(applicationModel, lastTimePair)); Thread.sleep(50); // push error rt +1 - eventMulticaster.publishErrorEvent(new RegistryEvent.MetricsRegisterEvent(applicationModel, lastTimePair)); + eventMulticaster.publishErrorEvent(new RegistryEvent.MetricsApplicationRegisterEvent(applicationModel, lastTimePair)); long c2 = lastTimePair.calc(); metricSamples = collector.collect(); diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java index 759b4dae31..27b7a4f736 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryMetricsSampleTest.java @@ -65,8 +65,8 @@ class RegistryMetricsSampleTest { RegistryMetricsCollector collector = new RegistryMetricsCollector(applicationModel); collector.setCollectEnabled(true); String applicationName = applicationModel.getApplicationName(); - collector.addRT(applicationName, RegistryStatComposite.OP_TYPE_REGISTER, 10L); - collector.addRT(applicationName, RegistryStatComposite.OP_TYPE_REGISTER, 0L); + collector.addApplicationRT(applicationName, RegistryStatComposite.OP_TYPE_REGISTER, 10L); + collector.addApplicationRT(applicationName, RegistryStatComposite.OP_TYPE_REGISTER, 0L); List samples = collector.collect(); for (MetricSample sample : samples) { @@ -89,7 +89,7 @@ class RegistryMetricsSampleTest { RegistryMetricsCollector collector = new RegistryMetricsCollector(applicationModel); collector.setCollectEnabled(true); String applicationName = applicationModel.getApplicationName(); - collector.increment(applicationName,RegistryEvent.Type.R_TOTAL); + collector.increment(applicationName, RegistryEvent.ApplicationType.R_TOTAL); } } diff --git a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java index 9829809243..7d4753aa1b 100644 --- a/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java +++ b/dubbo-metrics/dubbo-metrics-registry/src/test/java/org/apache/dubbo/metrics/registry/metrics/collector/RegistryStatCompositeTest.java @@ -36,12 +36,12 @@ public class RegistryStatCompositeTest { @Test void testInit() { RegistryStatComposite statComposite = new RegistryStatComposite(); - Assertions.assertEquals(statComposite.numStats.size(), RegistryEvent.Type.values().length); + Assertions.assertEquals(statComposite.applicationNumStats.size(), RegistryEvent.ApplicationType.values().length); //(rt)5 * (register,subscribe,notify)3 - Assertions.assertEquals(5 * 3, statComposite.rtStats.size()); - statComposite.numStats.values().forEach((v -> + Assertions.assertEquals(5 * 3, statComposite.appRtStats.size()); + statComposite.applicationNumStats.values().forEach((v -> Assertions.assertEquals(v, new ConcurrentHashMap<>()))); - statComposite.rtStats.forEach(rtContainer -> + statComposite.appRtStats.forEach(rtContainer -> { for (Map.Entry entry : rtContainer.entrySet()) { Assertions.assertEquals(0L, rtContainer.getValueSupplier().apply(entry.getKey())); @@ -52,16 +52,16 @@ public class RegistryStatCompositeTest { @Test void testIncrement() { RegistryStatComposite statComposite = new RegistryStatComposite(); - statComposite.increment(RegistryEvent.Type.R_TOTAL, applicationName); - Assertions.assertEquals(1L, statComposite.numStats.get(RegistryEvent.Type.R_TOTAL).get(applicationName).get()); + statComposite.increment(RegistryEvent.ApplicationType.R_TOTAL, applicationName); + Assertions.assertEquals(1L, statComposite.applicationNumStats.get(RegistryEvent.ApplicationType.R_TOTAL).get(applicationName).get()); } @Test void testCalcRt() { RegistryStatComposite statComposite = new RegistryStatComposite(); - statComposite.calcRt(applicationName, OP_TYPE_NOTIFY, 10L); - Assertions.assertTrue(statComposite.rtStats.stream().anyMatch(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY))); - Optional> subContainer = statComposite.rtStats.stream().filter(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY)).findFirst(); + statComposite.calcApplicationRt(applicationName, OP_TYPE_NOTIFY, 10L); + Assertions.assertTrue(statComposite.appRtStats.stream().anyMatch(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY))); + Optional> subContainer = statComposite.appRtStats.stream().filter(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY)).findFirst(); subContainer.ifPresent(v -> Assertions.assertEquals(10L, v.get(applicationName).longValue())); } } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java index 5cb52f08dd..0714987b38 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java @@ -25,6 +25,9 @@ import org.apache.dubbo.metadata.AbstractServiceNameMapping; import org.apache.dubbo.metadata.MappingChangedEvent; import org.apache.dubbo.metadata.MappingListener; import org.apache.dubbo.metadata.ServiceNameMapping; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.metrics.model.TimePair; +import org.apache.dubbo.metrics.registry.event.RegistryEvent; import org.apache.dubbo.registry.NotifyListener; import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent; import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; @@ -33,6 +36,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -322,13 +326,25 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { serviceListeners.put(serviceNamesKey, serviceInstancesChangedListener); } + ApplicationModel applicationModel = Optional.ofNullable(url.getApplicationModel()).orElse(ApplicationModel.defaultModel()) ; + GlobalMetricsEventMulticaster eventMulticaster = applicationModel.getBeanFactory().getBean(GlobalMetricsEventMulticaster.class); + TimePair timePair = TimePair.start(); + + eventMulticaster.publishEvent(new RegistryEvent.MetricsServiceSubscribeEvent(applicationModel, timePair, serviceKey)); if (!serviceInstancesChangedListener.isDestroyed()) { listener.addServiceListener(serviceInstancesChangedListener); serviceInstancesChangedListener.addListenerAndNotify(url, listener); - serviceDiscovery.addServiceInstancesChangedListener(serviceInstancesChangedListener); + try { + serviceDiscovery.addServiceInstancesChangedListener(serviceInstancesChangedListener); + } catch (Throwable t) { + eventMulticaster.publishErrorEvent(new RegistryEvent.MetricsServiceSubscribeEvent(applicationModel, timePair, serviceKey)); + throw t; + } + eventMulticaster.publishFinishEvent(new RegistryEvent.MetricsServiceSubscribeEvent(applicationModel, timePair, serviceKey)); } else { logger.info(String.format("Listener of %s has been destroyed by another thread.", serviceNamesKey)); serviceListeners.remove(serviceNamesKey); + eventMulticaster.publishErrorEvent(new RegistryEvent.MetricsSubscribeEvent(applicationModel, timePair)); } } finally { appSubscriptionLock.unlock(); From d574ab01f97033679d709e3e6c34b7de7be101bf Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Fri, 17 Mar 2023 14:07:24 +0800 Subject: [PATCH 139/144] Fix issue 11844 (#11851) --- .../main/java/org/apache/dubbo/config/RegistryConfig.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/RegistryConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/RegistryConfig.java index 4aadeb9c50..91bc4b826e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/RegistryConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/RegistryConfig.java @@ -553,4 +553,10 @@ public class RegistryConfig extends AbstractConfig { // empty protocol will default to 'dubbo' return !StringUtils.isEmpty(address) || !StringUtils.isEmpty(protocol); } + + @Override + @Parameter(excluded = true) + public Boolean isDefault() { + return isDefault; + } } From 0862819991cb03141d93f8bebc84541ca39de847 Mon Sep 17 00:00:00 2001 From: Mengyang Tang Date: Fri, 17 Mar 2023 22:26:35 +0800 Subject: [PATCH 140/144] Fix SlidingWindow test case bug (#11858) * Fix SlidingWindow test case bug * Fix test case * Fix test case --- .../dubbo/metrics/aggregate/SlidingWindow.java | 9 ++++----- .../metrics/aggregate/TimeWindowCounterTest.java | 12 ++++++------ .../metrics/aggregate/TimeWindowQuantileTest.java | 4 +--- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java index de1fd09583..b8208bf3ee 100755 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java @@ -18,7 +18,6 @@ package org.apache.dubbo.metrics.aggregate; import org.apache.dubbo.common.utils.Assert; -import org.apache.dubbo.common.utils.TimeUtils; import java.util.ArrayList; import java.util.List; @@ -77,7 +76,7 @@ public abstract class SlidingWindow { * @return the pane at current timestamp. */ public Pane currentPane() { - return currentPane(TimeUtils.currentTimeMillis()); + return currentPane(System.currentTimeMillis()); } /** @@ -197,7 +196,7 @@ public abstract class SlidingWindow { * @return true if the pane is deprecated; otherwise false. */ public boolean isPaneDeprecated(final Pane pane) { - return isPaneDeprecated(TimeUtils.currentTimeMillis(), pane); + return isPaneDeprecated(System.currentTimeMillis(), pane); } /** @@ -219,7 +218,7 @@ public abstract class SlidingWindow { * @return valid pane list for entire sliding window. */ public List> list() { - return list(TimeUtils.currentTimeMillis()); + return list(System.currentTimeMillis()); } /** @@ -254,7 +253,7 @@ public abstract class SlidingWindow { * @return aggregated value list for entire sliding window. */ public List values() { - return values(TimeUtils.currentTimeMillis()); + return values(System.currentTimeMillis()); } /** diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java index 6cac0d60d8..c1b6897944 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowCounterTest.java @@ -23,15 +23,15 @@ import org.junit.jupiter.api.Test; class TimeWindowCounterTest { @Test - void test() throws Exception { + void test() { TimeWindowCounter counter = new TimeWindowCounter(10, 1); counter.increment(); - Assertions.assertEquals(counter.get(), 1); + Assertions.assertEquals(1, counter.get()); counter.decrement(); - Assertions.assertEquals(counter.get(), 0); + Assertions.assertEquals(0, counter.get()); counter.increment(); - Thread.sleep(1000); - Assertions.assertEquals(counter.get(), 0); - Assertions.assertTrue(counter.bucketLivedSeconds() < 1); + counter.increment(); + Assertions.assertEquals(2, counter.get()); + Assertions.assertTrue(counter.bucketLivedSeconds() <= 1); } } diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java index 36ee690b01..99bf3905aa 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowQuantileTest.java @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test; class TimeWindowQuantileTest { @Test - void test() throws Exception { + void test() { TimeWindowQuantile quantile = new TimeWindowQuantile(100, 10, 1); for (int i = 1; i <= 100; i++) { quantile.add(i); @@ -31,7 +31,5 @@ class TimeWindowQuantileTest { Assertions.assertEquals(quantile.quantile(0.01), 2); Assertions.assertEquals(quantile.quantile(0.99), 100); - Thread.sleep(1000); - Assertions.assertEquals(quantile.quantile(0.99), Double.NaN); } } From 9a5726499fa740df1376c84e84ea8d338b54a7d3 Mon Sep 17 00:00:00 2001 From: liaozan <378024053@qq.com> Date: Tue, 21 Mar 2023 16:30:03 +0800 Subject: [PATCH 141/144] Make json framework optional (#11856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make fastjson、gson optional * Update pom.xml * Make fastjson2 as default json framework --- dubbo-common/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-common/pom.xml b/dubbo-common/pom.xml index 335eee3002..e05a2634bd 100644 --- a/dubbo-common/pom.xml +++ b/dubbo-common/pom.xml @@ -65,12 +65,12 @@ com.alibaba fastjson - provided + true com.google.code.gson gson - provided + true com.fasterxml.jackson.core From 6296c4401d6be323de53dc310dffeba556836d50 Mon Sep 17 00:00:00 2001 From: SeasonPan <244014926@qq.com> Date: Tue, 21 Mar 2023 16:54:32 +0800 Subject: [PATCH 142/144] add classes of java.util.x into serialize.allowlist file to avoid compatibility issues in the future (#11872) --- dubbo-common/src/main/resources/security/serialize.allowlist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dubbo-common/src/main/resources/security/serialize.allowlist b/dubbo-common/src/main/resources/security/serialize.allowlist index f2eef79665..ebaf7fc9fb 100644 --- a/dubbo-common/src/main/resources/security/serialize.allowlist +++ b/dubbo-common/src/main/resources/security/serialize.allowlist @@ -82,6 +82,7 @@ java.util.Calendar java.util.Collections$EmptyList java.util.Collections$EmptyMap java.util.Collections$SingletonSet +java.util.Collections$SingletonList java.util.Collections$UnmodifiableCollection java.util.Collections$UnmodifiableList java.util.Collections$UnmodifiableMap @@ -107,6 +108,8 @@ java.util.concurrent.TimeUnit java.util.Currency java.util.Date java.util.EnumSet +java.util.RegularEnumSet +java.util.JumboEnumSet java.util.HashMap java.util.HashSet java.util.Hashtable From 46aff44c2fe62d7670d3f524d0c881a53d5e6adf Mon Sep 17 00:00:00 2001 From: MieAh <100568933+MieAh@users.noreply.github.com> Date: Tue, 21 Mar 2023 17:01:33 +0800 Subject: [PATCH 143/144] Support choose local invoke in runtime instead of startup (#11531) --- dubbo-cluster/pom.xml | 6 + .../support/wrapper/ScopeClusterInvoker.java | 225 ++++++++++++++ .../support/wrapper/ScopeClusterWrapper.java | 46 +++ .../org.apache.dubbo.rpc.cluster.Cluster | 3 +- .../router/file/FileRouterEngineTest.java | 3 + .../wrapper/ScopeClusterInvokerTest.java | 282 ++++++++++++++++++ .../apache/dubbo/config/ReferenceConfig.java | 59 ++-- .../apache/dubbo/config/ServiceConfig.java | 2 + .../dubbo/config/ReferenceConfigTest.java | 98 ++---- .../integration/RegistryProtocolTest.java | 11 +- .../apache/dubbo/rpc/RpcServiceContext.java | 11 + .../rpc/listener/ExporterChangeListener.java | 27 ++ .../ExporterScopeModelInitializer.java | 41 +++ .../rpc/listener/InjvmExporterListener.java | 79 +++++ .../rpc/protocol/ProtocolListenerWrapper.java | 10 +- ...ache.dubbo.rpc.model.ScopeModelInitializer | 1 + dubbo-rpc/dubbo-rpc-injvm/pom.xml | 5 - .../rpc/protocol/injvm/InjvmProtocol.java | 3 +- .../rpc/protocol/injvm/InjvmProtocolTest.java | 18 +- .../rpc/protocol/injvm/ProtocolTest.java | 3 +- 20 files changed, 798 insertions(+), 135 deletions(-) create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterWrapper.java create mode 100644 dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterChangeListener.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterScopeModelInitializer.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/InjvmExporterListener.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer diff --git a/dubbo-cluster/pom.xml b/dubbo-cluster/pom.xml index 744d0f9f11..8beed95576 100644 --- a/dubbo-cluster/pom.xml +++ b/dubbo-cluster/pom.xml @@ -40,6 +40,12 @@ org.yaml snakeyaml + + org.apache.dubbo + dubbo-rpc-injvm + ${project.parent.version} + test + org.apache.curator curator-framework diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java new file mode 100644 index 0000000000..02a96e810b --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvoker.java @@ -0,0 +1,225 @@ +/* + * 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.wrapper; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.url.component.ServiceConfigURL; +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Protocol; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.cluster.Cluster; +import org.apache.dubbo.rpc.cluster.ClusterInvoker; +import org.apache.dubbo.rpc.cluster.Directory; +import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; +import org.apache.dubbo.rpc.listener.ExporterChangeListener; +import org.apache.dubbo.rpc.listener.InjvmExporterListener; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; +import static org.apache.dubbo.rpc.Constants.LOCAL_KEY; +import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL; +import static org.apache.dubbo.rpc.Constants.SCOPE_KEY; +import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE; +import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL; +import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY; + +/** + * A ClusterInvoker that selects between local and remote invokers at runtime. + */ +public class ScopeClusterInvoker implements ClusterInvoker, ExporterChangeListener { + + private Protocol protocolSPI; + private final Directory directory; + private final Invoker invoker; + private final AtomicBoolean isExported; + private volatile Invoker injvmInvoker; + private volatile InjvmExporterListener injvmExporterListener; + + private boolean peerFlag; + + private boolean injvmFlag; + + private final Object createLock = new Object(); + + + public ScopeClusterInvoker(Directory directory, Invoker invoker) { + this.directory = directory; + this.invoker = invoker; + this.isExported = new AtomicBoolean(false); + init(); + } + + private void init() { + Boolean peer = (Boolean) getUrl().getAttribute(PEER_KEY); + String isInjvm = getUrl().getParameter(LOCAL_PROTOCOL); + if (peer != null && peer) { + peerFlag = true; + return; + } + if (injvmInvoker == null && LOCAL_PROTOCOL.equalsIgnoreCase(getRegistryUrl().getProtocol())) { + injvmInvoker = invoker; + isExported.compareAndSet(false, true); + injvmFlag = true; + return; + } + if (Boolean.TRUE.toString().equalsIgnoreCase(isInjvm) || LOCAL_KEY.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY))) { + injvmFlag = true; + } else if (isInjvm == null) { + injvmFlag = isNotRemoteOrGeneric(); + } + + protocolSPI = getUrl().getApplicationModel().getExtensionLoader(Protocol.class).getAdaptiveExtension(); + injvmExporterListener = getUrl().getOrDefaultFrameworkModel().getBeanFactory().getBean(InjvmExporterListener.class); + injvmExporterListener.addExporterChangeListener(this, getUrl().getServiceKey()); + } + + @Override + public URL getUrl() { + return directory.getConsumerUrl(); + } + + @Override + public URL getRegistryUrl() { + return directory.getUrl(); + } + + @Override + public Directory getDirectory() { + return directory; + } + + @Override + public boolean isDestroyed() { + return directory.isDestroyed(); + } + + @Override + public boolean isAvailable() { + return isExported.get() || directory.isAvailable(); + } + + @Override + public void destroy() { + if (injvmExporterListener != null) { + injvmExporterListener.removeExporterChangeListener(this, getUrl().getServiceKey()); + } + destroyInjvmInvoker(); + this.invoker.destroy(); + } + + @Override + public Class getInterface() { + return directory.getInterface(); + } + + @Override + public Result invoke(Invocation invocation) throws RpcException { + if (peerFlag) { + return invoker.invoke(invocation); + } + if (isInjvmExported()) { + return injvmInvoker.invoke(invocation); + } + return invoker.invoke(invocation); + } + + private boolean isNotRemoteOrGeneric() { + return !SCOPE_REMOTE.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) && + !getUrl().getParameter(GENERIC_KEY, false); + } + + private boolean isInjvmExported() { + Boolean localInvoke = RpcContext.getServiceContext().getLocalInvoke(); + boolean isExportedValue = isExported.get(); + boolean local = (localInvoke != null && localInvoke); + // Determine whether this call is local + if (isExportedValue && local) { + return true; + } + + // Determine whether this call is remote + if (localInvoke != null && !localInvoke) { + return false; + } + + // When calling locally, determine whether it does not meet the requirements + if (!isExportedValue && (SCOPE_LOCAL.equalsIgnoreCase(getUrl().getParameter(SCOPE_KEY)) || + Boolean.TRUE.toString().equalsIgnoreCase(getUrl().getParameter(LOCAL_PROTOCOL))|| local)) { + throw new RpcException("Local service has not been exposed yet!"); + } + + return isExportedValue && injvmFlag; + } + + + private void createInjvmInvoker() { + if (injvmInvoker == null) { + synchronized (createLock) { + if (injvmInvoker == null) { + URL url = new ServiceConfigURL(LOCAL_PROTOCOL, NetUtils.getLocalHost(), getUrl().getPort(), getInterface().getName(), getUrl().getParameters()); + url = url.setScopeModel(getUrl().getScopeModel()); + url = url.setServiceModel(getUrl().getServiceModel()); + Invoker invoker = protocolSPI.refer(getInterface(), url); + List> invokers = new ArrayList<>(); + invokers.add(invoker); + injvmInvoker = Cluster.getCluster(url.getScopeModel(), Cluster.DEFAULT, false).join(new StaticDirectory(url, invokers), true); + } + } + } + } + + @Override + public void onExporterChangeExport(Exporter exporter) { + if (isExported.get()) { + return; + } + if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey()) + && exporter.getInvoker().getUrl().getProtocol().equalsIgnoreCase(LOCAL_PROTOCOL)) { + createInjvmInvoker(); + isExported.compareAndSet(false, true); + } + } + + @Override + public void onExporterChangeUnExport(Exporter exporter) { + if (getUrl().getServiceKey().equals(exporter.getInvoker().getUrl().getServiceKey()) + && exporter.getInvoker().getUrl().getProtocol().equalsIgnoreCase(LOCAL_PROTOCOL)) { + destroyInjvmInvoker(); + isExported.compareAndSet(true, false); + } + } + + private void destroyInjvmInvoker() { + if (injvmInvoker != null) { + injvmInvoker.destroy(); + injvmInvoker = null; + } + } + + public Invoker getInvoker() { + return invoker; + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterWrapper.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterWrapper.java new file mode 100644 index 0000000000..f76b8710c6 --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterWrapper.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.rpc.cluster.support.wrapper; + +import org.apache.dubbo.common.extension.Wrapper; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.cluster.Cluster; +import org.apache.dubbo.rpc.cluster.Directory; + +/** + * Introducing ScopeClusterInvoker section through Dubbo SPI mechanism + */ +@Wrapper(order = -1) +public class ScopeClusterWrapper implements Cluster { + private final Cluster cluster; + + public ScopeClusterWrapper(Cluster cluster) { + this.cluster = cluster; + } + + @Override + public Invoker join(Directory directory, boolean buildFilterChain) throws RpcException { + return new ScopeClusterInvoker<>(directory, + this.cluster.join(directory, buildFilterChain)); + } + + public Cluster getCluster() { + return cluster; + } +} diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster index f9e2570702..5ff23dc553 100644 --- a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster +++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster @@ -1,4 +1,5 @@ mock=org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper +scope=org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterWrapper failover=org.apache.dubbo.rpc.cluster.support.FailoverCluster failfast=org.apache.dubbo.rpc.cluster.support.FailfastCluster failsafe=org.apache.dubbo.rpc.cluster.support.FailsafeCluster @@ -7,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 \ No newline at end of file +zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java index ec56f58707..57b3162695 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java @@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.router.file; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -30,6 +31,7 @@ import org.apache.dubbo.rpc.cluster.LoadBalance; import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory; import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -59,6 +61,7 @@ class FileRouterEngineTest { @BeforeAll public static void setUpBeforeClass() throws Exception { + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); System.setProperty(ENABLE_CONNECTIVITY_VALIDATION, "false"); } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java new file mode 100644 index 0000000000..889b3ab7d7 --- /dev/null +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/ScopeClusterInvokerTest.java @@ -0,0 +1,282 @@ +/* + * 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.wrapper; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.ExtensionLoader; + +import org.apache.dubbo.metrics.event.GlobalMetricsEventMulticaster; +import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Protocol; +import org.apache.dubbo.rpc.ProxyFactory; +import org.apache.dubbo.rpc.Result; +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.cluster.support.AbstractClusterInvoker; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE; +import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; +import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL; +import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL; +import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY; +import static org.apache.dubbo.rpc.cluster.Constants.SCOPE_KEY; + +class ScopeClusterInvokerTest { + + private final List> invokers = new ArrayList<>(); + + private final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); + private final ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); + + private final List> exporters = new ArrayList<>(); + + @BeforeEach + void beforeMonth() { + ApplicationModel.defaultModel().getBeanFactory().registerBean(GlobalMetricsEventMulticaster.class); + } + + @AfterEach + void after() throws Exception { + for (Exporter exporter : exporters) { + exporter.unexport(); + } + exporters.clear(); + for (Invoker invoker : invokers) { + invoker.destroy(); + } + invokers.clear(); + } + + @Test + void testScopeNull_RemoteInvoke() { + URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName()); + url = url.addParameter(REFER_KEY, + URL.encode(PATH_KEY + "=" + DemoService.class.getName())); + url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + + Invoker cluster = getClusterInvoker(url); + invokers.add(cluster); + + //Configured with mock + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("doSomething1"); + Result ret = cluster.invoke(invocation); + Assertions.assertEquals("doSomething1", ret.getValue()); + } + + @Test + void testScopeNull_LocalInvoke() { + URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName()); + url = url.addParameter(REFER_KEY, + URL.encode(PATH_KEY + "=" + DemoService.class.getName())); + url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + + URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()) ; + Exporter exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl)); + exporters.add(exporter); + + + Invoker cluster = getClusterInvoker(url); + invokers.add(cluster); + + //Configured with mock + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("doSomething2"); + invocation.setParameterTypes(new Class[]{}); + Result ret = cluster.invoke(invocation); + Assertions.assertEquals("doSomething2", ret.getValue()); + } + + @Test + void testScopeRemoteInvoke() { + URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName()); + url = url.addParameter(REFER_KEY, + URL.encode(PATH_KEY + "=" + DemoService.class.getName())); + url = url.addParameter(SCOPE_KEY, "remote"); + url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + + URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + Exporter exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl)); + exporters.add(exporter); + + Invoker cluster = getClusterInvoker(url); + invokers.add(cluster); + + //Configured with mock + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("doSomething3"); + invocation.setParameterTypes(new Class[]{}); + Result ret = cluster.invoke(invocation); + Assertions.assertEquals("doSomething3", ret.getValue()); + } + + @Test + void testScopeLocalInvoke() { + URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName()); + url = url.addParameter(REFER_KEY, + URL.encode(PATH_KEY + "=" + DemoService.class.getName())); + url = url.addParameter(SCOPE_KEY, SCOPE_LOCAL); + url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + + URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()); + injvmUrl = injvmUrl.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + Exporter exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl)); + exporters.add(exporter); + + Invoker cluster = getClusterInvoker(url); + invokers.add(cluster); + + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("doSomething4"); + invocation.setParameterTypes(new Class[]{}); + Assertions.assertTrue(cluster.isAvailable(), ""); + Result ret = cluster.invoke(invocation); + Assertions.assertEquals("doSomething4", ret.getValue()); + } + + @Test + void testInjvmRefer() { + URL url = new URL(LOCAL_PROTOCOL, LOCALHOST_VALUE, 0, DemoService.class.getName()); + url = url.addParameter(REFER_KEY, + URL.encode(PATH_KEY + "=" + DemoService.class.getName())); + url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + + URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + Exporter exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl)); + exporters.add(exporter); + + Invoker cluster = getClusterInvoker(url); + invokers.add(cluster); + + //Configured with mock + RpcInvocation invocation = new RpcInvocation(); + invocation.setMethodName("doSomething4"); + invocation.setParameterTypes(new Class[]{}); + Assertions.assertTrue(cluster.isAvailable(), ""); + Result ret = cluster.invoke(invocation); + Assertions.assertEquals("doSomething4", ret.getValue()); + } + + @Test + void testListenUnExport() throws NoSuchFieldException, IllegalAccessException { + URL url = URL.valueOf("remote://1.2.3.4/" + DemoService.class.getName()); + url = url.addParameter(REFER_KEY, + URL.encode(PATH_KEY + "=" + DemoService.class.getName())); + url = url.addParameter(SCOPE_KEY, "local"); + url = url.setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + + URL injvmUrl = URL.valueOf("injvm://127.0.0.1/TestService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + Exporter exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, injvmUrl)); + + Invoker cluster = getClusterInvoker(url); + invokers.add(cluster); + + exporter.unexport(); + + Assertions.assertTrue(cluster instanceof ScopeClusterInvoker); + + Field injvmInvoker = cluster.getClass().getDeclaredField("injvmInvoker"); + injvmInvoker.setAccessible(true); + Assertions.assertNull(injvmInvoker.get(cluster)); + + Field isExported = cluster.getClass().getDeclaredField("isExported"); + isExported.setAccessible(true); + Assertions.assertFalse(((AtomicBoolean) isExported.get(cluster)).get()); + } + + private Invoker getClusterInvoker(URL url) { + final URL durl = url.addParameter("proxy", "jdk"); + invokers.clear(); + ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension("jdk"); + Invoker invoker1 = proxy.getInvoker(new DemoServiceImpl(), DemoService.class, durl); + invokers.add(invoker1); + + StaticDirectory dic = new StaticDirectory<>(durl, invokers, null); + dic.buildRouterChain(); + AbstractClusterInvoker cluster = new AbstractClusterInvoker(dic) { + @Override + protected Result doInvoke(Invocation invocation, List invokers, LoadBalance loadbalance) + throws RpcException { + if (durl.getParameter("invoke_return_error", false)) { + throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "test rpc exception"); + } else { + return ((Invoker) invokers.get(0)).invoke(invocation); + } + } + }; + return new ScopeClusterInvoker<>(dic, cluster); + } + + public static interface DemoService { + String doSomething1(); + + String doSomething2(); + + String doSomething3(); + + String doSomething4(); + } + + public static class DemoServiceImpl implements DemoService { + + @Override + public String doSomething1() { + return "doSomething1"; + } + + @Override + public String doSomething2() { + return "doSomething2"; + + } + + @Override + public String doSomething3() { + return "doSomething3"; + } + + @Override + public String doSomething4() { + return "doSomething4"; + } + } +} + + diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java index ad47b82261..fb34d5110c 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java @@ -418,24 +418,18 @@ public class ReferenceConfig extends ReferenceConfigBase { @SuppressWarnings({"unchecked"}) private T createProxy(Map referenceParameters) { - if (shouldJvmRefer(referenceParameters)) { - createInvokerForLocal(referenceParameters); + urls.clear(); + + meshModeHandleUrl(referenceParameters); + + if (StringUtils.isNotEmpty(url)) { + // user specified URL, could be peer-to-peer address, or register center's address. + parseUrl(referenceParameters); } else { - urls.clear(); - - meshModeHandleUrl(referenceParameters); - - if (StringUtils.isNotEmpty(url)) { - // user specified URL, could be peer-to-peer address, or register center's address. - parseUrl(referenceParameters); - } else { - // if protocols not in jvm checkRegistry - if (!LOCAL_PROTOCOL.equalsIgnoreCase(getProtocol())) { - aggregateUrlFromRegistry(referenceParameters); - } - } - createInvokerForRemote(); + // if protocols not in jvm checkRegistry + aggregateUrlFromRegistry(referenceParameters); } + createInvoker(); if (logger.isInfoEnabled()) { logger.info("Referred dubbo service: [" + referenceParameters.get(INTERFACE_KEY) + "]." + @@ -522,26 +516,6 @@ public class ReferenceConfig extends ReferenceConfigBase { return true; } - /** - * Make a local reference, create a local invoker. - * - * @param referenceParameters - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - private void createInvokerForLocal(Map referenceParameters) { - URL url = new ServiceConfigURL(LOCAL_PROTOCOL, LOCALHOST_VALUE, 0, interfaceClass.getName(), referenceParameters); - url = url.setScopeModel(getScopeModel()); - url = url.setServiceModel(consumerModel); - Invoker withFilter = protocolSPI.refer(interfaceClass, url); - // Local Invoke ( Support Cluster Filter / Filter ) - List> invokers = new ArrayList<>(); - invokers.add(withFilter); - invoker = Cluster.getCluster(url.getScopeModel(), Cluster.DEFAULT).join(new StaticDirectory(url, invokers), true); - - if (logger.isInfoEnabled()) { - logger.info("Using in jvm service " + interfaceClass.getName()); - } - } /** * Parse the directly configured url. @@ -581,9 +555,18 @@ public class ReferenceConfig extends ReferenceConfigBase { } u = u.setScopeModel(getScopeModel()); u = u.setServiceModel(consumerModel); + if (isInjvm() != null && isInjvm()) { + u = u.addParameter(LOCAL_PROTOCOL, true); + } urls.add(u.putAttribute(REFER_KEY, referenceParameters)); } } + if (urls.isEmpty() && shouldJvmRefer(referenceParameters)) { + URL injvmUrl = new URL(LOCAL_PROTOCOL,LOCALHOST_VALUE,0,interfaceClass.getName()).addParameters(referenceParameters); + injvmUrl = injvmUrl.setScopeModel(getScopeModel()); + injvmUrl = injvmUrl.setServiceModel(consumerModel); + urls.add(injvmUrl.putAttribute(REFER_KEY, referenceParameters)); + } if (urls.isEmpty()) { throw new IllegalStateException( "No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + @@ -594,10 +577,10 @@ public class ReferenceConfig extends ReferenceConfigBase { /** - * Make a remote reference, create a remote reference invoker + * \create a reference invoker */ @SuppressWarnings({"unchecked", "rawtypes"}) - private void createInvokerForRemote() { + private void createInvoker() { if (urls.size() == 1) { URL curUrl = urls.get(0); invoker = protocolSPI.refer(interfaceClass, curUrl); diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java index 940da27c35..f628f803c8 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java @@ -74,6 +74,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND; import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_ISOLATION; +import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY; import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE; import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY; import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY; @@ -773,6 +774,7 @@ public class ServiceConfig extends ServiceConfigBase { .build(); local = local.setScopeModel(getScopeModel()) .setServiceModel(providerModel); + local = local.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL); doExportUrl(local, false); logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry url : " + local); } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java index 745110dcdc..cfbc745a3b 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java @@ -32,12 +32,13 @@ import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.config.context.ModuleConfigManager; import org.apache.dubbo.config.provider.impl.DemoServiceImpl; import org.apache.dubbo.registry.client.migration.MigrationInvoker; -import org.apache.dubbo.rpc.Exporter; import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.ProxyFactory; import org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder; import org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareClusterInvoker; import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker; +import org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterInvoker; import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; @@ -86,13 +87,11 @@ import java.util.stream.Collectors; import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.BROADCAST_CLUSTER; -import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY; import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.DUMP_DIRECTORY; -import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY; @@ -119,8 +118,6 @@ import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY; import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT; import static org.apache.dubbo.rpc.Constants.LOCAL_KEY; import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL; -import static org.apache.dubbo.rpc.Constants.SCOPE_KEY; -import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL; import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE; import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY; @@ -395,68 +392,6 @@ class ReferenceConfigTest { dubboBootstrap.stop(); } - @Test - void testShouldJvmRefer() { - - Map parameters = new HashMap<>(); - - ReferenceConfig referenceConfig = new ReferenceConfig<>(); - - // verify that if injvm is configured as true, local references should be made - referenceConfig.setInjvm(true); - Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters)); - - // verify that if injvm is configured as false, local references should not be made - referenceConfig.setInjvm(false); - Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters)); - - // verify that if url is configured, local reference should not be made - referenceConfig.setInjvm(null); - referenceConfig.setUrl("dubbo://127.0.0.1:20880/DemoService"); - parameters.put(INTERFACE_KEY, DemoService.class.getName()); - Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters)); - parameters.clear(); - - // verify that if scope is configured as local, local references should be made - referenceConfig.setInjvm(null); - referenceConfig.setUrl(null); - parameters.put(SCOPE_KEY, SCOPE_LOCAL); - Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters)); - parameters.clear(); - - // verify that if url protocol is configured as injvm, local references should be made - referenceConfig.setInjvm(null); - referenceConfig.setUrl(null); - parameters.put(LOCAL_PROTOCOL, "true"); - Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters)); - parameters.clear(); - - // verify that if generic is configured as true, local references should not be made - referenceConfig.setInjvm(null); - referenceConfig.setUrl(null); - parameters.put(GENERIC_KEY, "true"); - Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters)); - parameters.clear(); - - // verify that if the service has been exposed, and the cluster is not configured with broadcast, local reference should be made - referenceConfig.setInjvm(null); - referenceConfig.setUrl(null); - ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - DemoService service = new DemoServiceImpl(); - URL url = URL.valueOf("dubbo://127.0.0.1/DemoService") - .addParameter(INTERFACE_KEY, DemoService.class.getName()); - parameters.put(INTERFACE_KEY, DemoService.class.getName()); - Exporter exporter = InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).export(proxy.getInvoker(service, DemoService.class, url)); - InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).getExporterMap().put(DemoService.class.getName(), exporter); - Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters)); - - // verify that if the service has been exposed, and the cluster is configured with broadcast, local reference should not be made - parameters.put(CLUSTER_KEY, BROADCAST_CLUSTER); - Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters)); - parameters.clear(); - InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).destroy(); - } - @Test void testCreateInvokerForLocalRefer() { @@ -480,14 +415,18 @@ class ReferenceConfigTest { .initialize(); referenceConfig.init(); - Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker); - Invoker withCount = ((MockClusterInvoker) referenceConfig.getInvoker()).getDirectory().getAllInvokers().get(0); + Assertions.assertTrue(referenceConfig.getInvoker() instanceof ScopeClusterInvoker); + ScopeClusterInvoker scopeClusterInvoker = (ScopeClusterInvoker) referenceConfig.getInvoker(); + Invoker mockInvoker = scopeClusterInvoker.getInvoker(); + Assertions.assertTrue(mockInvoker instanceof MockClusterInvoker); + Invoker withCount = ((MockClusterInvoker) mockInvoker).getDirectory().getAllInvokers().get(0); + Assertions.assertTrue(withCount instanceof ReferenceCountInvokerWrapper); Invoker withFilter = ((ReferenceCountInvokerWrapper) withCount).getInvoker(); Assertions.assertTrue(withFilter instanceof ListenerInvokerWrapper || withFilter instanceof FilterChainBuilder.CallbackRegistrationInvoker); if (withFilter instanceof ListenerInvokerWrapper) { - Assertions.assertTrue(((ListenerInvokerWrapper)(((ReferenceCountInvokerWrapper) withCount).getInvoker())).getInvoker() instanceof InjvmInvoker); + Assertions.assertTrue(((ListenerInvokerWrapper) (((ReferenceCountInvokerWrapper) withCount).getInvoker())).getInvoker() instanceof InjvmInvoker); } if (withFilter instanceof FilterChainBuilder.CallbackRegistrationInvoker) { Invoker filterInvoker = ((FilterChainBuilder.CallbackRegistrationInvoker) withFilter).getFilterInvoker(); @@ -584,8 +523,10 @@ class ReferenceConfigTest { .initialize(); referenceConfig.init(); - Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker); - Assertions.assertEquals(Boolean.TRUE, referenceConfig.getInvoker().getUrl().getAttribute(PEER_KEY)); + Assertions.assertTrue(referenceConfig.getInvoker() instanceof ScopeClusterInvoker); + Invoker scopeClusterInvoker = referenceConfig.getInvoker(); + Assertions.assertTrue(((ScopeClusterInvoker) scopeClusterInvoker).getInvoker() instanceof MockClusterInvoker); + Assertions.assertEquals(Boolean.TRUE, ((ScopeClusterInvoker) scopeClusterInvoker).getInvoker().getUrl().getAttribute(PEER_KEY)); dubboBootstrap.destroy(); } @@ -756,9 +697,11 @@ class ReferenceConfigTest { System.setProperty("java.net.preferIPv4Stack", "true"); ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); DemoService service = new DemoServiceImpl(); - URL url = URL.valueOf("dubbo://127.0.0.1/DemoService") - .addParameter(INTERFACE_KEY, DemoService.class.getName()); - InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).export(proxy.getInvoker(service, DemoService.class, url)); + URL url = URL.valueOf("injvm://127.0.0.1/DemoService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + url = url.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL); + Protocol protocolSPI = ApplicationModel.defaultModel().getExtensionLoader(Protocol.class).getAdaptiveExtension(); + protocolSPI.export(proxy.getInvoker(service, DemoService.class, url)); demoService = rc.get(); success = true; } catch (Exception e) { @@ -1124,7 +1067,8 @@ class ReferenceConfigTest { applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("Test")); ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader(); - ClassLoader classLoader = new ClassLoader(originClassLoader) {}; + ClassLoader classLoader = new ClassLoader(originClassLoader) { + }; Thread.currentThread().setContextClassLoader(classLoader); ServiceConfig serviceConfig = new ServiceConfig<>(applicationModel.newModule()); diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/RegistryProtocolTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/RegistryProtocolTest.java index a4669373d9..6974215509 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/RegistryProtocolTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/integration/RegistryProtocolTest.java @@ -32,6 +32,7 @@ import org.apache.dubbo.rpc.cluster.Cluster; import org.apache.dubbo.rpc.cluster.support.FailoverCluster; import org.apache.dubbo.rpc.cluster.support.MergeableCluster; import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper; +import org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterWrapper; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ModuleModel; @@ -264,9 +265,10 @@ class RegistryProtocolTest { Invoker invoker = registryProtocol.refer(DemoService.class, url); Assertions.assertTrue(invoker instanceof MigrationInvoker); - Assertions.assertTrue(((MigrationInvoker) invoker).getCluster() instanceof MockClusterWrapper); + Assertions.assertTrue(((MigrationInvoker) invoker).getCluster() instanceof ScopeClusterWrapper); + Assertions.assertTrue(((ScopeClusterWrapper) ((MigrationInvoker) invoker).getCluster()).getCluster() instanceof MockClusterWrapper); Assertions.assertTrue( - ((MockClusterWrapper) ((MigrationInvoker) invoker).getCluster()).getCluster() instanceof FailoverCluster); + ((MockClusterWrapper) ((ScopeClusterWrapper) ((MigrationInvoker) invoker).getCluster()).getCluster()).getCluster() instanceof FailoverCluster); } /** @@ -327,10 +329,11 @@ class RegistryProtocolTest { Assertions.assertTrue(invoker instanceof MigrationInvoker); - Assertions.assertTrue(((MigrationInvoker) invoker).getCluster() instanceof MockClusterWrapper); + Assertions.assertTrue(((MigrationInvoker) invoker).getCluster() instanceof ScopeClusterWrapper); + Assertions.assertTrue(((ScopeClusterWrapper) ((MigrationInvoker) invoker).getCluster()).getCluster() instanceof MockClusterWrapper); Assertions.assertTrue( - ((MockClusterWrapper) ((MigrationInvoker) invoker).getCluster()).getCluster() instanceof MergeableCluster); + ((MockClusterWrapper) ((ScopeClusterWrapper) ((MigrationInvoker) invoker).getCluster()).getCluster()).getCluster() instanceof MergeableCluster); } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java index 1d5486e173..c0f11894fd 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java @@ -58,6 +58,8 @@ public class RpcServiceContext extends RpcContext { private String remoteApplicationName; + private Boolean localInvoke; + @Deprecated private List> invokers; @Deprecated @@ -618,6 +620,15 @@ public class RpcServiceContext extends RpcContext { this.needPrintRouterSnapshot = needPrintRouterSnapshot; } + public RpcServiceContext setLocalInvoke(boolean localInvoke) { + this.localInvoke = localInvoke; + return this; + } + + public Boolean getLocalInvoke() { + return this.localInvoke; + } + /** * Only part of the properties are copied, the others are either not used currently or can be got from invocation. * Also see {@link RpcContextAttachment#copyOf(boolean)} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterChangeListener.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterChangeListener.java new file mode 100644 index 0000000000..669b70eb0f --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterChangeListener.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.listener; + +import org.apache.dubbo.rpc.Exporter; + + +public interface ExporterChangeListener { + + void onExporterChangeExport(Exporter exporter); + + void onExporterChangeUnExport(Exporter exporter); +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterScopeModelInitializer.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterScopeModelInitializer.java new file mode 100644 index 0000000000..87092be949 --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ExporterScopeModelInitializer.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.listener; + +import org.apache.dubbo.common.beans.factory.ScopeBeanFactory; +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 ExporterScopeModelInitializer implements ScopeModelInitializer { + @Override + public void initializeFrameworkModel(FrameworkModel frameworkModel) { + ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory(); + beanFactory.registerBean(InjvmExporterListener.class); + } + + @Override + public void initializeApplicationModel(ApplicationModel applicationModel) { + + } + + @Override + public void initializeModuleModel(ModuleModel moduleModel) { + + } +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/InjvmExporterListener.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/InjvmExporterListener.java new file mode 100644 index 0000000000..8b22bb0f5b --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/InjvmExporterListener.java @@ -0,0 +1,79 @@ +/* + * 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.listener; + +import org.apache.dubbo.common.utils.CollectionUtils; +import org.apache.dubbo.common.utils.ConcurrentHashSet; +import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.RpcException; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class InjvmExporterListener extends ExporterListenerAdapter { + + private final Map> exporterChangeListeners = new ConcurrentHashMap<>(); + + private final Map> exporters = new ConcurrentHashMap<>(); + + @Override + public void exported(Exporter exporter) throws RpcException { + String serviceKey = exporter.getInvoker().getUrl().getServiceKey(); + exporters.putIfAbsent(serviceKey, exporter); + Set listeners = exporterChangeListeners.get(serviceKey); + if (!CollectionUtils.isEmpty(listeners)) { + for (ExporterChangeListener listener : listeners) { + listener.onExporterChangeExport(exporter); + } + } + super.exported(exporter); + } + + @Override + public void unexported(Exporter exporter) throws RpcException { + String serviceKey = exporter.getInvoker().getUrl().getServiceKey(); + exporters.remove(serviceKey, exporter); + Set listeners = exporterChangeListeners.get(serviceKey); + if (!CollectionUtils.isEmpty(listeners)) { + for (ExporterChangeListener listener : listeners) { + listener.onExporterChangeUnExport(exporter); + } + } + + super.unexported(exporter); + } + + public synchronized void addExporterChangeListener(ExporterChangeListener listener, String serviceKey) { + exporterChangeListeners.putIfAbsent(serviceKey, new ConcurrentHashSet<>()); + exporterChangeListeners.get(serviceKey).add(listener); + if (exporters.get(serviceKey) != null) { + Exporter exporter = exporters.get(serviceKey); + listener.onExporterChangeExport(exporter); + } + } + + public synchronized void removeExporterChangeListener(ExporterChangeListener listener, String listenerKey) { + Set listeners = exporterChangeListeners.get(listenerKey); + listeners.remove(listener); + if (CollectionUtils.isEmpty(listeners)) { + exporterChangeListeners.remove(listenerKey); + } + } + + +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java index f60ddd902c..0071fa66ce 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapper.java @@ -27,6 +27,7 @@ import org.apache.dubbo.rpc.InvokerListener; import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.ProtocolServer; import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.listener.InjvmExporterListener; import org.apache.dubbo.rpc.listener.ListenerExporterWrapper; import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper; import org.apache.dubbo.rpc.model.ScopeModelUtil; @@ -37,6 +38,7 @@ import java.util.List; import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY; import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_TYPE_KEY; +import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL; /** * ListenerProtocol @@ -63,9 +65,13 @@ public class ProtocolListenerWrapper implements Protocol { if (UrlUtils.isRegistry(invoker.getUrl())) { return protocol.export(invoker); } + List exporterListeners = ScopeModelUtil.getExtensionLoader(ExporterListener.class, invoker.getUrl().getScopeModel()) + .getActivateExtension(invoker.getUrl(), EXPORTER_LISTENER_KEY); + if (LOCAL_PROTOCOL.equals(invoker.getUrl().getProtocol())) { + exporterListeners.add(invoker.getUrl().getOrDefaultFrameworkModel().getBeanFactory().getBean(InjvmExporterListener.class)); + } return new ListenerExporterWrapper(protocol.export(invoker), - Collections.unmodifiableList(ScopeModelUtil.getExtensionLoader(ExporterListener.class, invoker.getUrl().getScopeModel()) - .getActivateExtension(invoker.getUrl(), EXPORTER_LISTENER_KEY))); + Collections.unmodifiableList(exporterListeners)); } @Override diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer b/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer new file mode 100644 index 0000000000..4d3c435bef --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer @@ -0,0 +1 @@ +injvm=org.apache.dubbo.rpc.listener.ExporterScopeModelInitializer diff --git a/dubbo-rpc/dubbo-rpc-injvm/pom.xml b/dubbo-rpc/dubbo-rpc-injvm/pom.xml index 4f5f9ad38d..a74078d832 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/pom.xml +++ b/dubbo-rpc/dubbo-rpc-injvm/pom.xml @@ -35,11 +35,6 @@ dubbo-rpc-api ${project.parent.version} - - org.apache.dubbo - dubbo-cluster - ${project.parent.version} - org.apache.dubbo dubbo-serialization-hessian2 diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java index 75a51f37be..46fc957e66 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java @@ -69,7 +69,7 @@ public class InjvmProtocol extends AbstractProtocol { if (result == null) { return null; } else if (ProtocolUtils.isGeneric( - result.getInvoker().getUrl().getParameter(GENERIC_KEY))) { + result.getInvoker().getUrl().getParameter(GENERIC_KEY))) { return null; } else { return result; @@ -91,6 +91,7 @@ public class InjvmProtocol extends AbstractProtocol { return new InjvmInvoker(serviceType, url, url.getServiceKey(), exporterMap); } + public boolean isInjvmRefer(URL url) { String scope = url.getParameter(SCOPE_KEY); // Since injvm protocol is configured explicitly, we don't need to set any extra flag, use normal refer process. diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java index ee949d13ce..5d4103a840 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java @@ -23,6 +23,7 @@ import org.apache.dubbo.rpc.Exporter; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.ProxyFactory; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.AfterEach; @@ -68,11 +69,13 @@ class InjvmProtocolTest { @Test void testLocalProtocol() throws Exception { DemoService service = new DemoServiceImpl(); - Invoker invoker = proxy.getInvoker(service, DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName())); + Invoker invoker = proxy.getInvoker(service, DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()) + .setScopeModel(ApplicationModel.defaultModel().getDefaultModule())); assertTrue(invoker.isAvailable()); Exporter exporter = protocol.export(invoker); exporters.add(exporter); - service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()))); + service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()) + .setScopeModel(ApplicationModel.defaultModel().getDefaultModule()))); assertEquals(service.getSize(new String[]{"", "", ""}), 3); service.invoke("injvm://127.0.0.1/TestService", "invoke"); @@ -84,11 +87,13 @@ class InjvmProtocolTest { @Test void testLocalProtocolWithToken() { DemoService service = new DemoServiceImpl(); - Invoker invoker = proxy.getInvoker(service, DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService?token=abc").addParameter(INTERFACE_KEY, DemoService.class.getName())); + Invoker invoker = proxy.getInvoker(service, DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService?token=abc").addParameter(INTERFACE_KEY, DemoService.class.getName()) + .setScopeModel(ApplicationModel.defaultModel().getDefaultModule())); assertTrue(invoker.isAvailable()); Exporter exporter = protocol.export(invoker); exporters.add(exporter); - service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()))); + service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()) + .setScopeModel(ApplicationModel.defaultModel().getDefaultModule()))); assertEquals(service.getSize(new String[]{"", "", ""}), 3); } @@ -96,7 +101,7 @@ class InjvmProtocolTest { void testIsInjvmRefer() { DemoService service = new DemoServiceImpl(); URL url = URL.valueOf("injvm://127.0.0.1/TestService") - .addParameter(INTERFACE_KEY, DemoService.class.getName()); + .addParameter(INTERFACE_KEY, DemoService.class.getName()).setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); Exporter exporter = protocol.export(proxy.getInvoker(service, DemoService.class, url)); exporters.add(exporter); @@ -128,7 +133,8 @@ class InjvmProtocolTest { DemoService service = new DemoServiceImpl(); URL url = URL.valueOf("injvm://127.0.0.1/TestService") .addParameter(ASYNC_KEY, true) - .addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer"); + .addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer") + .setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); Invoker invoker = proxy.getInvoker(service, DemoService.class, url); assertTrue(invoker.isAvailable()); Exporter exporter = protocol.export(invoker); diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/ProtocolTest.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/ProtocolTest.java index 3713d6473e..a2d578fac1 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/ProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/ProtocolTest.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.ProxyFactory; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.junit.jupiter.api.Test; @@ -43,7 +44,7 @@ class ProtocolTest { ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension("javassist"); - URL url = URL.valueOf("injvm://localhost:0/org.apache.dubbo.rpc.support.IEcho?interface=org.apache.dubbo.rpc.support.IEcho"); + URL url = URL.valueOf("injvm://localhost:0/org.apache.dubbo.rpc.support.IEcho?interface=org.apache.dubbo.rpc.support.IEcho").setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); Invoker invoker = proxyFactory.getInvoker(echo, IEcho.class, url); From 7bc8de4de936f6602c43192414c83d5d4425963c Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Tue, 21 Mar 2023 17:44:10 +0800 Subject: [PATCH 144/144] add nop for prometheus metrics (#11806) --- .../NopPrometheusMetricsReporter.java | 42 +++++++++++++++++++ .../PrometheusMetricsReporterFactory.java | 33 ++++++++++++++- .../client/ServiceDiscoveryRegistryTest.java | 1 + 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/NopPrometheusMetricsReporter.java diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/NopPrometheusMetricsReporter.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/NopPrometheusMetricsReporter.java new file mode 100644 index 0000000000..1d1a82d3a7 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/NopPrometheusMetricsReporter.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.metrics.prometheus; + +import org.apache.dubbo.metrics.report.MetricsReporter; + +/** + * NopMetricsReporter is a trivial implementation of MetricsReporter + * which do nothing when micro-meter package is not exist. + */ +public class NopPrometheusMetricsReporter implements MetricsReporter { + + @Override + public void init() { + + } + + @Override + public void refreshData() { + + } + + @Override + public String getResponse() { + return ""; + } +} diff --git a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java index 61aed6dee8..c549d6688b 100644 --- a/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java +++ b/dubbo-metrics/dubbo-metrics-prometheus/src/main/java/org/apache/dubbo/metrics/prometheus/PrometheusMetricsReporterFactory.java @@ -18,21 +18,50 @@ package org.apache.dubbo.metrics.prometheus; import org.apache.dubbo.common.URL; -import org.apache.dubbo.metrics.report.MetricsReporter; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.metrics.report.AbstractMetricsReporterFactory; +import org.apache.dubbo.metrics.report.MetricsReporter; import org.apache.dubbo.rpc.model.ApplicationModel; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR; + /** * MetricsReporterFactory to create PrometheusMetricsReporter. */ public class PrometheusMetricsReporterFactory extends AbstractMetricsReporterFactory { + private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(PrometheusMetricsReporterFactory.class); + public PrometheusMetricsReporterFactory(ApplicationModel applicationModel) { super(applicationModel); } @Override public MetricsReporter createMetricsReporter(URL url) { - return new PrometheusMetricsReporter(url, getApplicationModel()); + try { + return new PrometheusMetricsReporter(url, getApplicationModel()); + } catch (NoClassDefFoundError ncde) { + String msg = ncde.getMessage(); + if (dependenciesNotFound(msg)) { + logger.error(INTERNAL_ERROR, "", "", "Failed to load class \"org.apache.dubbo.metrics.prometheus.PrometheusMetricsReporter\".", ncde); + logger.error(INTERNAL_ERROR, "", "", "Defaulting to no-operation (NOP) metricsReporter implementation", ncde); + logger.error(INTERNAL_ERROR, "", "", "Introduce the micrometer-core package to use the ability of metrics", ncde); + return new NopPrometheusMetricsReporter(); + } else { + logger.error(INTERNAL_ERROR, "", "", "Failed to instantiate PrometheusMetricsReporter", ncde); + throw ncde; + } + } + } + + private static boolean dependenciesNotFound(String msg) { + if (msg == null) { + return false; + } + if (msg.contains("io/micrometer/core/instrument/composite/CompositeMeterRegistry")) { + return true; + } + return msg.contains("io.micrometer.core.instrument.composite.CompositeMeterRegistry"); } } diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryTest.java index 92a24d35e3..72bb09cbd5 100644 --- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryTest.java +++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistryTest.java @@ -138,6 +138,7 @@ class ServiceDiscoveryRegistryTest { } // // when check = true URL checkURL = url.addParameter(CHECK_KEY, true); + checkURL.setScopeModel(url.getApplicationModel()); // Exception exceptionShouldHappen = null; // try { // serviceDiscoveryRegistry.doSubscribe(checkURL, testServiceListener);