Compare commits

..

2 Commits

Author SHA1 Message Date
Albumen Kevin e12ed6a0f3
Merge branch '3.2' into dependabot/maven/fabric8_kubernetes_version-6.7.0 2023-06-06 17:37:48 +08:00
dependabot[bot] c6146f8426
Bump fabric8_kubernetes_version from 6.6.2 to 6.7.0
Bumps `fabric8_kubernetes_version` from 6.6.2 to 6.7.0.

Updates `kubernetes-client` from 6.6.2 to 6.7.0
- [Release notes](https://github.com/fabric8io/kubernetes-client/releases)
- [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md)
- [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.6.2...v6.7.0)

Updates `kubernetes-server-mock` from 6.6.2 to 6.7.0

---
updated-dependencies:
- dependency-name: io.fabric8:kubernetes-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: io.fabric8:kubernetes-server-mock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 08:01:52 +00:00
3424 changed files with 59711 additions and 75274 deletions

View File

@ -109,9 +109,5 @@ dubbo-spring-boot-tracing-otel-zipkin-starter
dubbo-spring-boot-tracing-otel-otlp-starter
dubbo-spring-boot-observability-starter
dubbo-spring-boot-starter
dubbo-spring-boot-starters
dubbo-nacos-spring-boot-starter
dubbo-zookeeper-spring-boot-starter
dubbo-zookeeper-curator5-spring-boot-starter
dubbo-spring-security
dubbo-xds

View File

@ -25,7 +25,6 @@ notifications:
github:
homepage: https://dubbo.apache.org/
description: "The java implementation of Apache Dubbo. An RPC and microservice framework."
features:
# Enable wiki for documentation
wiki: true
@ -45,15 +44,9 @@ github:
foo: bar
labels:
- java
- rpc
- microservices
- framework
- restful
- distributed-systems
- rpc
- dubbo
- service-mesh
- http
- grpc
- web
collaborators:
- oxsean

View File

@ -19,55 +19,13 @@
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
tab_width = 4
max_line_length = 120
insert_final_newline = true
trim_trailing_whitespace = true
[*.java]
ij_java_continuation_indent_size = 8
ij_java_keep_control_statement_in_one_line = false
ij_java_for_brace_force = always
ij_java_if_brace_force = always
ij_java_keep_first_column_comment = false
ij_java_keep_line_breaks = false
ij_java_keep_simple_blocks_in_one_line = true
ij_java_keep_simple_classes_in_one_line = true
ij_java_keep_simple_lambdas_in_one_line = true
ij_java_keep_simple_methods_in_one_line = true
ij_java_keep_blank_lines_in_code = 1
ij_java_keep_blank_lines_in_declarations = 1
ij_java_class_count_to_use_import_on_demand = 999
ij_java_names_count_to_use_import_on_demand = 999
ij_java_imports_layout = org.apache.dubbo.**, |, javax.**, |, java.**, |, *, |, $*
ij_java_insert_inner_class_imports = true
ij_java_space_before_array_initializer_left_brace = true
ij_java_method_parameters_new_line_after_left_paren = true
ij_java_wrap_comments = true
ij_java_wrap_long_lines = true
ij_java_enum_constants_wrap = split_into_lines
ij_java_method_call_chain_wrap = split_into_lines
ij_java_method_parameters_wrap = on_every_item
ij_java_extends_list_wrap = on_every_item
ij_java_extends_keyword_wrap = normal
ij_java_binary_operation_wrap = normal
ij_java_binary_operation_sign_on_next_line = true
[*.json]
tab_width = 2
[*.{yml,yaml}]
indent_size = 2
[*.xml]
ij_xml_attribute_wrap = off
ij_xml_text_wrap = off
ij_xml_keep_blank_lines = 1
[pom.xml]
indent_size = 2
# 4 space indentation
[*.{java,xml}]
indent_style = space
indent_size = 4

View File

@ -1,88 +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.
#
title: "[General][Java SDK (Component)] xxx"
body:
- type: markdown
attributes:
value: |
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
Thank you for finding the time to share your idea! We really appreciate the community efforts to improve Dubbo.
If you need to report a security issue, please visit [our security policy](https://github.com/apache/dubbo/security/policy).
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
Remember that non-English idea is quite not friendly for everyone, and might unable to get the response!
- type: checkboxes
attributes:
label: Pre-check
options:
- label: >
I am sure that all the content I provide is in English.
required: true
- type: dropdown
attributes:
label: Apache Dubbo Component
description: |
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
to choose the component that you want to ask questions about.
multiple: false
options:
- "Java SDK (apache/dubbo)"
- "Java Samples (apache/dubbo-samples)"
- "Java Integration Cases (apache/dubbo-integration-cases)"
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
- "Java Benchmark (apache/dubbo-benchmark)"
- "Go SDK (apache/dubbo-go)"
- "Go Samples (apache/dubbo-go-samples)"
- "Rust SDK (apache/dubbo-rust)"
- "Node.js SDK (apache/dubbo-js)"
- "Python SDK (apache/dubbo-python)"
- "Kubernetes Integration (apache/dubbo-kubernetes)"
- "Pixiu Gateway (apache/dubbo-go-pixiu)"
- "Pixiu Gateway Samples (apache/dubbo-go-pixiu-samples)"
- "Admin (apache/dubbo-admin)"
- "Website (apache/dubbo-website)"
- "Awesome (apache/dubbo-awesome)"
- "Initializer (apache/dubbo-intializer)"
- "Others (apache/dubbo-xxx)"
validations:
required: true
- type: textarea
attributes:
label: Details
description: Anything you want to ask?
validations:
required: true
- type: checkboxes
attributes:
label: Code of Conduct
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
options:
- label: >
I agree to follow this project's
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
required: true
- type: markdown
attributes:
value: "Thanks for completing our form!"

View File

@ -1,88 +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.
#
title: "[Q/A][Java SDK (Component)] xxx"
body:
- type: markdown
attributes:
value: |
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
Thank you for finding the time to report the question! We really appreciate the community efforts to improve Dubbo.
If you need to report a security issue, please visit [our security policy](https://github.com/apache/dubbo/security/policy).
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
Remember that non-English question is quite not friendly for everyone, and might unable to get the response!
- type: checkboxes
attributes:
label: Pre-check
options:
- label: >
I am sure that all the content I provide is in English.
required: true
- type: dropdown
attributes:
label: Apache Dubbo Component
description: |
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
to choose the component that you want to ask questions about.
multiple: false
options:
- "Java SDK (apache/dubbo)"
- "Java Samples (apache/dubbo-samples)"
- "Java Integration Cases (apache/dubbo-integration-cases)"
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
- "Java Benchmark (apache/dubbo-benchmark)"
- "Go SDK (apache/dubbo-go)"
- "Go Samples (apache/dubbo-go-samples)"
- "Rust SDK (apache/dubbo-rust)"
- "Node.js SDK (apache/dubbo-js)"
- "Python SDK (apache/dubbo-python)"
- "Kubernetes Integration (apache/dubbo-kubernetes)"
- "Pixiu Gateway (apache/dubbo-go-pixiu)"
- "Pixiu Gateway Samples (apache/dubbo-go-pixiu-samples)"
- "Admin (apache/dubbo-admin)"
- "Website (apache/dubbo-website)"
- "Awesome (apache/dubbo-awesome)"
- "Initializer (apache/dubbo-intializer)"
- "Others (apache/dubbo-xxx)"
validations:
required: true
- type: textarea
attributes:
label: Details
description: Anything you want to know?
validations:
required: true
- type: checkboxes
attributes:
label: Code of Conduct
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
options:
- label: >
I agree to follow this project's
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
required: true
- type: markdown
attributes:
value: "Thanks for completing our form!"

View File

@ -1,142 +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.
#
name: Bug Report
description: File a bug report
title: "[Bug] "
labels: ["type/need-triage", "component/need-triage"]
projects: ["apache/337"]
body:
- type: markdown
attributes:
value: |
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
Thank you for finding the time to report the problem! We really appreciate the community efforts to improve Dubbo.
Please make sure what you are reporting is indeed a bug with reproducible steps, if you want to ask questions
or share ideas, please [subscribe to our mailing list](mailto:dev-subscribe@dubbo.apache.org) and sent
emails to [our mailing list](mailto:dev@dubbo.apache.org), you can also head to our
[Discussion](https://github.com/apache/dubbo/discussions) tab.
If you need to report a security issue, please visit [our security policy](https://github.com/apache/dubbo/security/policy).
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
Remember that non-English issues is quite not friendly for everyone, and might unable to get the response!
- type: checkboxes
attributes:
label: Pre-check
options:
- label: >
I am sure that all the content I provide is in English.
required: true
- type: checkboxes
attributes:
label: Search before asking
description: >
Please make sure to search in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) first to see
whether the same issue was reported already.
options:
- label: >
I had searched in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no similar
issues.
required: true
- type: dropdown
attributes:
label: Apache Dubbo Component
description: |
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
to choose the component that you want to ask questions about.
multiple: false
options:
- "Java SDK (apache/dubbo)"
- "Java Samples (apache/dubbo-samples)"
- "Java Integration Cases (apache/dubbo-integration-cases)"
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
- "Java Benchmark (apache/dubbo-benchmark)"
validations:
required: true
- type: textarea
attributes:
label: Dubbo Version
description: "Which Dubbo version, JDK version and operating system did you use?"
placeholder: "Example: Dubbo Java 3.2.12, OpenJDK 1.8, Ubuntu 20.04"
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce this issue
description: >
Describe how to reproduce this issue.If you are not able to provide a reproducible case,
please open a [Discussion](https://github.com/apache/dubbo/discussions) instead.
placeholder: >
Please provide the context in which the problem occurred and explain what happened.
A [GitHub address] would be helpful for maintainers to reproduce the problem.
validations:
required: true
- type: textarea
attributes:
label: What you expected to happen
description: What do you think went wrong?
placeholder: >
Please explain why you think the behaviour is erroneous. It is extremely helpful if you copy and paste
the fragment of logs showing the exact error messages or wrong behaviour and screenshots for
UI problems. You can include files by dragging and dropping them here.
**NOTE**: please copy and paste texts instead of taking screenshots of them for easy future search.
validations:
required: true
- type: textarea
attributes:
label: Anything else
description: Anything else we need to know?
placeholder: >
How often does this problem occur? (Once? Every time? Only when certain conditions are met?)
Any relevant logs to include? Put them here inside fenced
``` ``` blocks or inside a collapsable details tag if it's too long:
<details><summary>x.log</summary> lots of stuff </details>
- type: checkboxes
attributes:
label: Are you willing to submit a pull request to fix on your own?
description: >
This is absolutely not required, but we are happy to guide you in the contribution process
especially if you already have a good understanding of how to implement the fix.
Dubbo is a totally community-driven project and we love to bring new contributors in.
options:
- label: Yes I am willing to submit a pull request on my own!
- type: checkboxes
attributes:
label: Code of Conduct
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
options:
- label: >
I agree to follow this project's
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
required: true
- type: markdown
attributes:
value: "Thanks for completing our form!"

View File

@ -1,106 +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.
#
name: Feature Request
description: Create a Feature Request for Dubbo
title: "[Feature] "
labels: ["type/need-triage", "component/need-triage"]
projects: ["apache/337"]
body:
- type: markdown
attributes:
value: |
<img src="https://dubbo.apache.org/imgs/nav_logo2.png" alt="Dubbo logo" height="90px" align="right" />
Thank you for finding the time to propose new feature!
We really appreciate the community efforts to improve Dubbo.
**Dubbo is open for world wide collaboration, please make sure that all the content you provide is in English.**
Remember that non-English issues is quite not friendly for everyone, and might unable to get the response!
- type: checkboxes
attributes:
label: Pre-check
options:
- label: >
I am sure that all the content I provide is in English.
required: true
- type: checkboxes
attributes:
label: Search before asking
description: >
Please make sure to search in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) first to see
whether the same feature was requested already.
options:
- label: >
I had searched in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no similar
feature requirement.
required: true
- type: dropdown
attributes:
label: Apache Dubbo Component
description: |
What Apache Dubbo component are you using? Apache Dubbo has many subprojects, please make sure
to choose the component that you want to ask questions about.
multiple: false
options:
- "Java SDK (apache/dubbo)"
- "Java Samples (apache/dubbo-samples)"
- "Java Integration Cases (apache/dubbo-integration-cases)"
- "Java SPI Extensions (apache/dubbo-spi-extensions)"
- "Java Benchmark (apache/dubbo-benchmark)"
validations:
required: true
- type: textarea
attributes:
label: Descriptions
description: A short description of your feature
validations:
required: true
- type: textarea
attributes:
label: Related issues
description: Is there currently another issue associated with this?
- type: checkboxes
attributes:
label: Are you willing to submit a pull request to fix on your own?
description: >
This is absolutely not required, but we are happy to guide you in the contribution process
especially if you already have a good understanding of how to implement the feature.
Dubbo is a totally community-driven project and we love to bring new contributors in.
options:
- label: Yes I am willing to submit a pull request on my own!
- type: checkboxes
attributes:
label: Code of Conduct
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
options:
- label: >
I agree to follow this project's
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
required: true
- type: markdown
attributes:
value: "Thanks for completing our form!"

39
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,39 @@
---
name: Bug Report
about: Report a bug in Dubbo
title: ''
labels: type/bug
assignees: ''
---
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
### Environment
* Dubbo version: xxx
* Operating System version: xxx
* Java version: xxx
### Steps to reproduce this issue
1. xxx
2. xxx
3. xxx
Pls. provide [GitHub address] to reproduce this issue.
### Expected Behavior
<!-- What do you expect from the above steps-->
### Actual Behavior
<!-- What actually happens? -->
If there is an exception, please attach the exception trace:
```
Just put your stack trace here!
```

View File

@ -1,22 +1,8 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
blank_issues_enabled: false
blank_issues_enabled: true
contact_links:
- name: Question & FAQ & Proposal
url: https://github.com/apache/dubbo/discussions/
about: Ask a question, request support or submit a proposal for Apache Dubbo.
- name: Dubbo Community Repo
url: https://github.com/apache/dubbo-website
about: Please see our community docs here.
- name: Report a security issue
url: https://github.com/apache/dubbo/security/policy
about: Please report security vulnerabilities using these instructions.

11
.github/ISSUE_TEMPLATE/discussion.md vendored Normal file
View File

@ -0,0 +1,11 @@
---
name: Discussion
about: Start a discussion for Dubbo
title: ''
labels: type/discussion
assignees: ''
---
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
<!-- For all design discussions please continue. -->

View File

@ -0,0 +1,16 @@
---
name: Feature Request
about: Create a Feature Request for Dubbo
title: ''
labels: type/feature
assignees: ''
---
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
- [ ] I have searched the [release notes](https://github.com/apache/dubbo/releases) of this repository and believe that this is not a duplicate.
## Describe the feature
<!-- Please also discuss possible business value -->

15
.github/ISSUE_TEMPLATE/proposal.md vendored Normal file
View File

@ -0,0 +1,15 @@
---
name: Proposal
about: Create a technical proposal for Dubbo
title: ''
labels: type/proposal
assignees: ''
---
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
## Describe the proposal
<!-- Please use this for a concrete design proposal for functionality. -->
<!-- If you just want to request a new feature and discuss the possible business value, create a Feature Request. -->

13
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,13 @@
---
name: Question
about: Ask a question about Dubbo
title: ''
labels: type/question
assignees: ''
---
<!-- If you need to report a security issue please visit https://github.com/apache/dubbo/security/policy -->
- [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) of this repository and believe that this is not a duplicate.
## Ask your question here

View File

@ -13,54 +13,13 @@ env:
VERSIONS_LIMIT: 4
JACOCO_ENABLE: true
CANDIDATE_VERSIONS: '
spring.version:5.3.24;
spring-boot.version:2.7.6;
spring.version:4.3.30.RELEASE;
spring-boot.version:1.5.22.RELEASE;
spring-boot.version:2.4.1;
'
jobs:
check-format:
name: Check if code needs formatting
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Maven
uses: actions/setup-java@v4
with:
java-version: 21
distribution: zulu
- name: Check if code aligns with code style
id: check
run: mvn --log-file mvn.log spotless:check
continue-on-error: true
- name: Upload checkstyle result
uses: actions/upload-artifact@v4
with:
name: checkstyle-result
path: mvn.log
- name: Generate Summary for successful run
if: ${{ steps.check.outcome == 'success' }}
run: |
echo ":ballot_box_with_check: Kudos! No formatting issues found!" >> $GITHUB_STEP_SUMMARY
- name: Generate Summary for failed run
if: ${{ steps.check.outcome == 'failure' }}
run: |
echo "## :negative_squared_cross_mark: Formatting issues found!" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
cat mvn.log | grep "ERROR" | sed 's/Check if code needs formatting Check if code aligns with code style [0-9A-Z:.-]\+//' | sed 's/\[ERROR] //' | head -n -11 >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "Please run \`mvn spotless:apply\` to fix the formatting issues." >> $GITHUB_STEP_SUMMARY
- name: Fail if code needs formatting
if: ${{ steps.check.outcome == 'failure' }}
uses: actions/github-script@v7.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
core.setFailed("Formatting issues found!")
license:
name: "Check License"
needs: check-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@ -68,11 +27,11 @@ jobs:
uses: apache/skywalking-eyes@e1a02359b239bd28de3f6d35fdc870250fa513d5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Set up JDK 21"
- name: "Set up JDK 17"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 21
java-version: 17
- name: "Compile Dubbo (Linux)"
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
@ -85,8 +44,6 @@ jobs:
mode: check
build-source:
name: "Build Dubbo"
needs: check-format
runs-on: ubuntu-latest
outputs:
version: ${{ steps.dubbo-version.outputs.version }}
@ -142,7 +99,6 @@ jobs:
unit-test-prepare:
name: "Preparation for Unit Test"
needs: check-format
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -191,7 +147,7 @@ jobs:
echo "--- End Print Rsa Public Key"
unit-test:
needs: [check-format, build-source, unit-test-prepare]
needs: [build-source, unit-test-prepare]
name: "Unit Test On ubuntu-latest"
runs-on: ubuntu-latest
strategy:
@ -208,7 +164,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 21
java-version: 17
- uses: actions/cache@v3
name: "Cache local Maven repository"
with:
@ -256,120 +212,15 @@ jobs:
name: coverage-result
path: "**/target/site/**/jacoco.xml"
samples-test-prepare:
needs: check-format
runs-on: ubuntu-latest
env:
JOB_COUNT: 3
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: samples-test-list
path: test/jobs
samples-test-job:
needs: [check-format, build-source, samples-test-prepare]
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
JAVA_VER: 8
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
strategy:
fail-fast: false
matrix:
job_id: [1, 2, 3]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Restore Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
${{ runner.os }}-dubbo-snapshot-
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: samples-test-list
path: test/jobs/
- name: "Set up JDK 8"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 8
- name: "Init Candidate Versions"
run: |
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
- name: "Build test image"
run: |
cd test && bash ./build-test-image.sh
- name: "Run tests"
run: cd test && bash ./run-tests.sh
- name: "merge jacoco resule"
run: |
cd test/dubbo-test-jacoco-merger && mvn clean compile exec:java -Dexec.mainClass="org.apache.dubbo.test.JacocoMerge" -Dexec.args="${{github.workspace}}"
- name: "Upload jacoco"
uses: actions/upload-artifact@v3
with:
name: samples-jacoco-result
path: target/jacoco*.exec
- name: "Upload test result"
if: always()
uses: actions/upload-artifact@v3
with:
name: samples-test-result
path: test/jobs/*-result*
samples-test-result:
needs: [check-format, samples-test-job]
if: always()
runs-on: ubuntu-latest
env:
JAVA_VER: 8
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: samples-test-result
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
integration-test-prepare:
needs: check-format
runs-on: ubuntu-latest
env:
JOB_COUNT: 3
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
@ -378,8 +229,9 @@ jobs:
with:
name: test-list
path: test/jobs
integration-test-job:
needs: [check-format, build-source, integration-test-prepare]
needs: [build-source, integration-test-prepare]
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
runs-on: ubuntu-latest
timeout-minutes: 90
@ -393,8 +245,8 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
@ -445,8 +297,9 @@ jobs:
with:
name: test-result
path: test/jobs/*-result*
integration-test-result:
needs: [check-format, integration-test-job]
needs: [integration-test-job]
if: always()
runs-on: ubuntu-latest
env:
@ -454,8 +307,8 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
@ -466,7 +319,7 @@ jobs:
jacoco-result-merge:
runs-on: ubuntu-latest
needs: [check-format, integration-test-result, samples-test-result, unit-test]
needs: [integration-test-result, unit-test]
steps:
- uses: actions/checkout@v3
with:
@ -475,15 +328,11 @@ jobs:
with:
repository: 'apache/dubbo-samples'
path: "./dubbo-samples"
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
path: "./dubbo-integration-cases"
- name: "Set up JDK 21"
- name: "Set up JDK 17"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 21
java-version: 17
- name: "Restore class result"
uses: actions/download-artifact@v3
with:
@ -494,23 +343,14 @@ jobs:
cd ${{ github.workspace }}/dubbo
unzip -o ${{ github.workspace }}/class.zip
- name: "Restore jacoco exec"
uses: actions/download-artifact@v3
with:
name: samples-jacoco-result
path: dubbo-samples/target/
- name: "Restore integration jacoco exec"
uses: actions/download-artifact@v3
with:
name: jacoco-result
path: dubbo-integration-cases/target/
path: dubbo-samples/target/
- name: "Merge jacoco result"
run: |
cd ${{ github.workspace }}/dubbo-samples/test/dubbo-test-jacoco-merger
mvn clean compile exec:java -Dexec.mainClass="org.apache.dubbo.test.JacocoReport" -Dexec.args="${{github.workspace}}/dubbo-samples ${{github.workspace}}/dubbo"
- name: "Merge samples jacoco result"
run: |
cd ${{ github.workspace }}/dubbo-integration-cases/test/dubbo-test-jacoco-merger
mvn clean compile exec:java -Dexec.mainClass="org.apache.dubbo.test.JacocoReport" -Dexec.args="${{github.workspace}}/dubbo-integration-cases ${{github.workspace}}/dubbo"
- name: "Restore coverage result"
uses: actions/download-artifact@v3
with:
@ -518,11 +358,8 @@ jobs:
path: dubbo/
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
with:
verbose: true
error-code-inspecting:
needs: check-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@ -535,11 +372,11 @@ jobs:
ref: main
path: "./dubbo-test-tools"
- name: "Set up JDK 21"
- name: "Set up JDK 17"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 21
java-version: 17
- name: "Compile Dubbo (Linux)"
run: |
@ -561,7 +398,6 @@ jobs:
path: ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector/error-inspection-result.txt
native-image-inspecting:
needs: check-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@ -579,10 +415,10 @@ jobs:
- name: "Setup Zookeeper environment"
run: |
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
- name: "Check environment"
run: |

View File

@ -0,0 +1,251 @@
name: Build and Test Scheduled On 3.0
on:
schedule:
- cron: '0 0/6 * * *'
workflow_dispatch:
permissions:
contents: read
env:
FORK_COUNT: 2
FAIL_FAST: 0
SHOW_ERROR_DETAIL: 1
#multi-version size limit
VERSIONS_LIMIT: 4
CANDIDATE_VERSIONS: '
spring.version:4.3.30.RELEASE;
spring-boot.version:1.5.22.RELEASE;
spring-boot.version:2.4.1;
'
jobs:
build-source:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.dubbo-version.outputs.version }}
steps:
- uses: actions/checkout@v3
with:
ref: "3.0"
path: dubbo
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 8
- uses: actions/cache@v3
name: "Cache local Maven repository"
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
- 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,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
- name: "Upload checkstyle file if failure"
if: failure()
uses: actions/upload-artifact@v3
with:
name: "checkstyle-file"
path: ${{ github.workspace }}/checkstyle.zip
- name: "Calculate Dubbo Version"
id: dubbo-version
run: |
REVISION=`awk '/<revision>[^<]+<\/revision>/{gsub(/<revision>|<\/revision>/,"",$1);print $1;exit;}' ./dubbo/pom.xml`
echo "version=$REVISION" >> $GITHUB_OUTPUT
echo "dubbo version: $REVISION"
unit-test-prepare:
name: " Preparation for Unit Test On ${{ matrix.os }}"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
env:
ZOOKEEPER_VERSION: 3.6.3
steps:
- uses: actions/cache@v3
name: "Cache zookeeper binary archive"
id: "cache-zookeeper"
with:
path: ${{ github.workspace }}/.tmp/zookeeper
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
- name: "Set up msys2 if necessary"
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
uses: msys2/setup-msys2@v2
with:
release: false # support cache, see https://github.com/msys2/setup-msys2#context
- name: "Download zookeeper binary archive in Linux OS"
if: ${{ startsWith( matrix.os, 'ubuntu') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
run: |
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
echo "list the downloaded zookeeper binary archive"
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
- name: "Download zookeeper binary archive in Windows OS"
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
shell: msys2 {0}
run: |
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
echo "list the downloaded zookeeper binary archive"
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
unit-test:
needs: [build-source, unit-test-prepare]
name: "Unit Test On ${{ matrix.os }} (JDK: ${{ matrix.jdk }})"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
steps:
- uses: actions/checkout@v3
with:
ref: "3.0"
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
- uses: actions/cache@v3
name: "Cache local Maven repository"
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Test with Maven with Integration Tests"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
integration-test-prepare:
runs-on: ubuntu-latest
env:
JOB_COUNT: 3
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: test-list
path: test/jobs
integration-test-job:
needs: [build-source, integration-test-prepare]
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
runs-on: ubuntu-latest
timeout-minutes: 30
env:
JAVA_VER: 8
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
strategy:
fail-fast: false
matrix:
job_id: [1, 2, 3]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Restore Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
${{ runner.os }}-dubbo-snapshot-
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: test-list
path: test/jobs/
- name: "Set up JDK 8"
uses: actions/setup-java@v1
with:
java-version: 8
- name: "Init Candidate Versions"
run: |
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
- name: "Build test image"
run: |
cd test && bash ./build-test-image.sh
- name: "Run tests"
run: cd test && bash ./run-tests.sh
- name: "Upload test result"
if: always()
uses: actions/upload-artifact@v3
with:
name: test-result
path: test/jobs/*-result*
integration-test-result:
needs: [integration-test-job]
if: always()
runs-on: ubuntu-latest
env:
JAVA_VER: 8
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: test-result
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh

View File

@ -134,7 +134,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
steps:
@ -169,6 +169,8 @@ jobs:
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
unit-test-fastjson2:
needs: [build-source, unit-test-prepare]
@ -178,17 +180,18 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
DUBBO_DEFAULT_SERIALIZATION: fastjson2
MAVEN_SUREFIRE_ADD_OPENS: true
steps:
- uses: actions/checkout@v3
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
ref: "3.1"
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
- uses: actions/cache@v3
name: "Cache local Maven repository"
@ -206,120 +209,16 @@ jobs:
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-
- name: "Test with Maven with Integration Tests on JDK 8"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests on JDK 8"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Test with Maven with Integration Tests"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
if: ${{ startsWith( matrix.os, 'ubuntu') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
samples-test-prepare:
runs-on: ubuntu-latest
env:
JOB_COUNT: 5
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: samples-test-list
path: test/jobs
samples-test-job:
needs: [build-source, samples-test-prepare]
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
JAVA_VER: ${{matrix.jdk}}
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
strategy:
fail-fast: false
matrix:
jdk: [ 8, 11 ]
job_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Restore Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
${{ runner.os }}-dubbo-snapshot-
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: samples-test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
with:
java-version: ${{matrix.jdk}}
- name: "Init Candidate Versions"
run: |
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
- name: "Build test image"
run: |
cd test && bash ./build-test-image.sh
- name: "Run tests"
run: cd test && bash ./run-tests.sh
- name: "Upload test result"
if: always()
uses: actions/upload-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/*-result*
samples-test-result:
needs: [samples-test-job]
if: always()
runs-on: ubuntu-latest
env:
JAVA_VER: ${{matrix.jdk}}
strategy:
matrix:
jdk: [ 8, 11 ]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
integration-test-prepare:
runs-on: ubuntu-latest
@ -328,19 +227,20 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: integration-test-list
name: test-list
path: test/jobs
integration-test-job:
needs: [build-source, integration-test-prepare]
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
@ -354,8 +254,8 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
@ -375,7 +275,7 @@ jobs:
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: integration-test-list
name: test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
@ -395,8 +295,9 @@ jobs:
if: always()
uses: actions/upload-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
name: test-result-${{matrix.jdk}}
path: test/jobs/*-result*
integration-test-result:
needs: [integration-test-job]
if: always()
@ -409,12 +310,12 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
name: test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
@ -433,11 +334,10 @@ jobs:
ref: main
path: "./dubbo-test-tools"
- name: "Set up JDK 21"
uses: actions/setup-java@v3
- name: "Set up JDK 17"
uses: actions/setup-java@v1
with:
distribution: 'zulu'
java-version: 21
java-version: 17
- name: "Compile Dubbo (Linux)"
run: |
@ -477,10 +377,10 @@ jobs:
- name: "Setup Zookeeper environment"
run: |
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
- name: "Check environment"
run: |
@ -496,7 +396,7 @@ jobs:
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 native:compile
nohup ./target/dubbo-demo-native-provider &
nohup ./target/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 native:compile
./target/dubbo-demo-native-consumer
./target/demo-native-consumer

View File

@ -134,7 +134,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
steps:
@ -169,6 +169,8 @@ jobs:
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
unit-test-fastjson2:
needs: [build-source, unit-test-prepare]
@ -178,17 +180,18 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
DUBBO_DEFAULT_SERIALIZATION: fastjson2
MAVEN_SUREFIRE_ADD_OPENS: true
steps:
- uses: actions/checkout@v3
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
ref: "3.2"
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
- uses: actions/cache@v3
name: "Cache local Maven repository"
@ -206,120 +209,16 @@ jobs:
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-
- name: "Test with Maven with Integration Tests on JDK 8"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests on JDK 8"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Test with Maven with Integration Tests"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
if: ${{ startsWith( matrix.os, 'ubuntu') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
samples-test-prepare:
runs-on: ubuntu-latest
env:
JOB_COUNT: 5
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: samples-test-list
path: test/jobs
samples-test-job:
needs: [build-source, samples-test-prepare]
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
JAVA_VER: ${{matrix.jdk}}
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
strategy:
fail-fast: false
matrix:
jdk: [ 8, 11, 17, 21 ]
job_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Restore Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
${{ runner.os }}-dubbo-snapshot-
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: samples-test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
with:
java-version: ${{matrix.jdk}}
- name: "Init Candidate Versions"
run: |
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
- name: "Build test image"
run: |
cd test && bash ./build-test-image.sh
- name: "Run tests"
run: cd test && bash ./run-tests.sh
- name: "Upload test result"
if: always()
uses: actions/upload-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/*-result*
samples-test-result:
needs: [samples-test-job]
if: always()
runs-on: ubuntu-latest
env:
JAVA_VER: ${{matrix.jdk}}
strategy:
matrix:
jdk: [ 8, 11, 17, 21 ]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
integration-test-prepare:
runs-on: ubuntu-latest
@ -328,19 +227,20 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: integration-test-list
name: test-list
path: test/jobs
integration-test-job:
needs: [build-source, integration-test-prepare]
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
@ -349,13 +249,13 @@ jobs:
strategy:
fail-fast: false
matrix:
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
job_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
@ -375,7 +275,7 @@ jobs:
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: integration-test-list
name: test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
@ -395,8 +295,9 @@ jobs:
if: always()
uses: actions/upload-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
name: test-result-${{matrix.jdk}}
path: test/jobs/*-result*
integration-test-result:
needs: [integration-test-job]
if: always()
@ -405,16 +306,16 @@ jobs:
JAVA_VER: ${{matrix.jdk}}
strategy:
matrix:
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
name: test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
@ -433,11 +334,10 @@ jobs:
ref: main
path: "./dubbo-test-tools"
- name: "Set up JDK 21"
uses: actions/setup-java@v3
- name: "Set up JDK 17"
uses: actions/setup-java@v1
with:
distribution: 'zulu'
java-version: 21
java-version: 17
- name: "Compile Dubbo (Linux)"
run: |
@ -477,10 +377,10 @@ jobs:
- name: "Setup Zookeeper environment"
run: |
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
- name: "Check environment"
run: |

View File

@ -1,502 +0,0 @@
name: Build and Test Scheduled On 3.3
on:
schedule:
- cron: '0 0/6 * * *'
workflow_dispatch:
permissions:
contents: read
env:
FORK_COUNT: 2
FAIL_FAST: 0
SHOW_ERROR_DETAIL: 1
#multi-version size limit
VERSIONS_LIMIT: 4
ALL_REMOTE_VERSION: true
CANDIDATE_VERSIONS: '
spring.version:5.3.24;
spring-boot.version:2.7.6;
'
jobs:
license:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: "3.3"
- name: Check License
uses: apache/skywalking-eyes@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-source:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.dubbo-version.outputs.version }}
steps:
- uses: actions/checkout@v3
with:
ref: "3.3"
path: dubbo
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 21
- uses: actions/cache@v3
name: "Cache local Maven repository"
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
- 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,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
- name: "Upload checkstyle file if failure"
if: failure()
uses: actions/upload-artifact@v3
with:
name: "checkstyle-file"
path: ${{ github.workspace }}/checkstyle.zip
- name: "Calculate Dubbo Version"
id: dubbo-version
run: |
REVISION=`awk '/<revision>[^<]+<\/revision>/{gsub(/<revision>|<\/revision>/,"",$1);print $1;exit;}' ./dubbo/pom.xml`
echo "version=$REVISION" >> $GITHUB_OUTPUT
echo "dubbo version: $REVISION"
unit-test-prepare:
name: " Preparation for Unit Test On ${{ matrix.os }}"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
env:
ZOOKEEPER_VERSION: 3.6.3
steps:
- uses: actions/cache@v3
name: "Cache zookeeper binary archive"
id: "cache-zookeeper"
with:
path: ${{ github.workspace }}/.tmp/zookeeper
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
- name: "Set up msys2 if necessary"
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
uses: msys2/setup-msys2@v2
with:
release: false # support cache, see https://github.com/msys2/setup-msys2#context
- name: "Download zookeeper binary archive in Linux OS"
if: ${{ startsWith( matrix.os, 'ubuntu') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
run: |
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
echo "list the downloaded zookeeper binary archive"
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
- name: "Download zookeeper binary archive in Windows OS"
if: ${{ startsWith( matrix.os, 'windows') && steps.cache-zookeeper.outputs.cache-hit != 'true' }}
shell: msys2 {0}
run: |
mkdir -p ${{ github.workspace }}/.tmp/zookeeper
wget -c https://archive.apache.org/dist/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c https://apache.website-solution.net/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.stu.edu.tw/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://ftp.jaist.ac.jp/pub/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz ||
wget -c http://mirror.apache-kr.org/apache/zookeeper/zookeeper-${{ env.ZOOKEEPER_VERSION }}/apache-zookeeper-${{ env.ZOOKEEPER_VERSION }}-bin.tar.gz -O ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
echo "list the downloaded zookeeper binary archive"
ls -al ${{ github.workspace }}/.tmp/zookeeper/apache-zookeeper-bin.tar.gz
unit-test:
needs: [build-source, unit-test-prepare]
name: "Unit Test On ${{ matrix.os }} (JDK: ${{ matrix.jdk }})"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
steps:
- uses: actions/checkout@v3
with:
ref: "3.3"
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
- uses: actions/cache@v3
name: "Cache local Maven repository"
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- uses: actions/cache@v3
name: "Cache zookeeper binary archive"
id: "cache-zookeeper"
with:
path: ${{ github.workspace }}/.tmp/zookeeper
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-
- name: "Test with Maven with Integration Tests"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
unit-test-fastjson2:
needs: [build-source, unit-test-prepare]
name: "Unit Test On ${{ matrix.os }} (JDK: ${{ matrix.jdk }}, Serialization: fastjson2)"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
DUBBO_DEFAULT_SERIALIZATION: fastjson2
MAVEN_SUREFIRE_ADD_OPENS: true
steps:
- uses: actions/checkout@v3
- name: "Set up JDK ${{ matrix.jdk }}"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: ${{ matrix.jdk }}
- uses: actions/cache@v3
name: "Cache local Maven repository"
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- uses: actions/cache@v3
name: "Cache zookeeper binary archive"
id: "cache-zookeeper"
with:
path: ${{ github.workspace }}/.tmp/zookeeper
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-
- name: "Test with Maven with Integration Tests on JDK 8"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests on JDK 8"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Test with Maven with Integration Tests"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
samples-test-prepare:
runs-on: ubuntu-latest
env:
JOB_COUNT: 5
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: samples-test-list
path: test/jobs
samples-test-job:
needs: [build-source, samples-test-prepare]
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
JAVA_VER: ${{matrix.jdk}}
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
strategy:
fail-fast: false
matrix:
jdk: [ 8, 11, 17, 21 ]
job_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Restore Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
${{ runner.os }}-dubbo-snapshot-
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: samples-test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
with:
java-version: ${{matrix.jdk}}
- name: "Init Candidate Versions"
run: |
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
- name: "Build test image"
run: |
cd test && bash ./build-test-image.sh
- name: "Run tests"
run: cd test && bash ./run-tests.sh
- name: "Upload test result"
if: always()
uses: actions/upload-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/*-result*
samples-test-result:
needs: [samples-test-job]
if: always()
runs-on: ubuntu-latest
env:
JAVA_VER: ${{matrix.jdk}}
strategy:
matrix:
jdk: [ 8, 11, 17, 21 ]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
integration-test-prepare:
runs-on: ubuntu-latest
env:
JOB_COUNT: 5
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: integration-test-list
path: test/jobs
integration-test-job:
needs: [build-source, integration-test-prepare]
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
JAVA_VER: ${{matrix.jdk}}
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
strategy:
fail-fast: false
matrix:
jdk: [ 8, 11, 17, 21 ]
job_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Restore Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
${{ runner.os }}-dubbo-snapshot-
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: integration-test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
with:
java-version: ${{matrix.jdk}}
- name: "Init Candidate Versions"
run: |
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
- name: "Build test image"
run: |
cd test && bash ./build-test-image.sh
- name: "Run tests"
run: cd test && bash ./run-tests.sh
- name: "Upload test result"
if: always()
uses: actions/upload-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
path: test/jobs/*-result*
integration-test-result:
needs: [integration-test-job]
if: always()
runs-on: ubuntu-latest
env:
JAVA_VER: ${{matrix.jdk}}
strategy:
matrix:
jdk: [ 8, 11, 17, 21 ]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
error-code-inspecting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: "3.3"
path: "./dubbo"
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-test-tools'
ref: main
path: "./dubbo-test-tools"
- name: "Set up JDK 21"
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 21
- name: "Compile Dubbo (Linux)"
run: |
cd ${{ github.workspace }}/dubbo
./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: "Run Error Code Inspecting"
env:
DUBBO_ECI_REPORT_AS_ERROR: true
run: |
cd ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector
../mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast -T 2C package exec:java -Ddubbo.eci.report-as-error=${DUBBO_ECI_REPORT_AS_ERROR} -Dmaven.test.skip=true -Dmaven.test.skip.exec=true -Ddubbo.eci.path=${{ github.workspace }}/dubbo
- name: "Upload error code inspection result"
# always() should not be used here, since we don't need to handle the 'canceled' situation.
if: ${{ success() || failure() }}
uses: actions/upload-artifact@v3
with:
name: "error-inspection-result"
path: ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector/error-inspection-result.txt
native-image-inspecting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: "3.3"
path: "./dubbo"
- name: "Setup GraalVM environment"
uses: graalvm/setup-graalvm@v1
with:
version: '22.3.0'
java-version: '17'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
native-image-job-reports: 'true'
- name: "Setup Zookeeper environment"
run: |
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
- name: "Check environment"
run: |
java --version
native-image --version
- name: "Compile Dubbo (Linux)"
run: |
cd ${{ github.workspace }}/dubbo
./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: "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 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 native:compile
./target/dubbo-demo-native-consumer

View File

@ -64,7 +64,7 @@ jobs:
run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r
- name: "Upload checkstyle file if failure"
if: failure()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v2
with:
name: "checkstyle-file"
path: ${{ github.workspace }}/checkstyle.zip
@ -132,7 +132,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
steps:
@ -150,14 +150,6 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- uses: actions/cache@v3
name: "Cache zookeeper binary archive"
id: "cache-zookeeper"
with:
path: ${{ github.workspace }}/.tmp/zookeeper
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-
- name: "Test with Maven with Integration Tests"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') }}
@ -166,6 +158,8 @@ jobs:
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
unit-test-fastjson2:
needs: [build-source, unit-test-prepare]
@ -175,7 +169,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest ]
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
DUBBO_DEFAULT_SERIALIZATION: fastjson2
@ -195,128 +189,16 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- uses: actions/cache@v3
name: "Cache zookeeper binary archive"
id: "cache-zookeeper"
with:
path: ${{ github.workspace }}/.tmp/zookeeper
key: zookeeper-${{ runner.os }}-${{ env.ZOOKEEPER_VERSION }}
restore-keys: |
zookeeper-${{ runner.os }}-
- name: "Test with Maven with Integration Tests on JDK 8"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests on JDK 8"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk == '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Test with Maven with Integration Tests"
timeout-minutes: 70
if: ${{ startsWith( matrix.os, 'ubuntu') && matrix.jdk != '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco,jdk15ge-simple,'!jdk15ge' -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
if: ${{ startsWith( matrix.os, 'ubuntu') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
- name: "Test with Maven without Integration Tests"
timeout-minutes: 90
if: ${{ startsWith( matrix.os, 'windows') && matrix.jdk != '8' }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -P"jacoco,jdk15ge-simple,'!jdk15ge'" -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
samples-test-prepare:
runs-on: ubuntu-latest
env:
JOB_COUNT: 5
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: samples-test-list
path: test/jobs
samples-test-job:
needs: [build-source, samples-test-prepare]
name: "Samples Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
JAVA_VER: ${{matrix.jdk}}
TEST_CASE_FILE: jobs/testjob_${{matrix.job_id}}.txt
strategy:
fail-fast: false
matrix:
jdk: [ 8, 11, 17, 21 ]
job_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-
- name: "Restore Dubbo cache"
uses: actions/cache@v3
with:
path: ~/.m2/repository/org/apache/dubbo
key: ${{ runner.os }}-dubbo-snapshot-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-dubbo-snapshot-${{ github.sha }}
${{ runner.os }}-dubbo-snapshot-
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: samples-test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
with:
java-version: ${{matrix.jdk}}
- name: "Init Candidate Versions"
run: |
DUBBO_VERSION="${{needs.build-source.outputs.version}}"
CANDIDATE_VERSIONS="dubbo.version:$DUBBO_VERSION;compiler.version:$DUBBO_VERSION;$CANDIDATE_VERSIONS;dubbo.compiler.version:$DUBBO_VERSION"
echo "CANDIDATE_VERSIONS=$CANDIDATE_VERSIONS" >> $GITHUB_ENV
- name: "Build test image"
run: |
cd test && bash ./build-test-image.sh
- name: "Run tests"
run: cd test && bash ./run-tests.sh
- name: "Upload test result"
if: always()
uses: actions/upload-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/*-result*
samples-test-result:
needs: [samples-test-job]
if: always()
runs-on: ubuntu-latest
env:
JAVA_VER: ${{matrix.jdk}}
strategy:
matrix:
jdk: [ 8, 11, 17, 21 ]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: samples-test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
if: ${{ startsWith( matrix.os, 'windows') }}
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true" -D"embeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper"
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
integration-test-prepare:
runs-on: ubuntu-latest
@ -325,19 +207,20 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Prepare test list"
run: |
bash ./test/scripts/prepare-test.sh
- name: "Upload test list"
uses: actions/upload-artifact@v3
with:
name: integration-test-list
name: test-list
path: test/jobs
integration-test-job:
needs: [build-source, integration-test-prepare]
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}} JavaVer: ${{matrix.jdk}})"
name: "Integration Test on ubuntu-latest (JobId: ${{matrix.job_id}})"
runs-on: ubuntu-latest
timeout-minutes: 90
env:
@ -346,13 +229,13 @@ jobs:
strategy:
fail-fast: false
matrix:
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
job_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Cache local Maven repository"
uses: actions/cache@v3
with:
@ -372,7 +255,7 @@ jobs:
- name: "Download test list"
uses: actions/download-artifact@v3
with:
name: integration-test-list
name: test-list
path: test/jobs/
- name: "Set up JDK ${{matrix.jdk}}"
uses: actions/setup-java@v1
@ -392,8 +275,9 @@ jobs:
if: always()
uses: actions/upload-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
name: test-result-${{matrix.jdk}}
path: test/jobs/*-result*
integration-test-result:
needs: [integration-test-job]
if: always()
@ -402,16 +286,16 @@ jobs:
JAVA_VER: ${{matrix.jdk}}
strategy:
matrix:
jdk: [ 8, 11, 17, 21 ]
jdk: [ 8, 11, 17, 19 ]
steps:
- uses: actions/checkout@v3
with:
repository: 'apache/dubbo-integration-cases'
ref: main
repository: 'apache/dubbo-samples'
ref: master
- name: "Download test result"
uses: actions/download-artifact@v3
with:
name: integration-test-result-${{matrix.jdk}}
name: test-result-${{matrix.jdk}}
path: test/jobs/
- name: "Merge test result"
run: ./test/scripts/merge-test-results.sh
@ -429,10 +313,10 @@ jobs:
ref: main
path: "./dubbo-test-tools"
- name: "Set up JDK 21"
- name: "Set up JDK 17"
uses: actions/setup-java@v3
with:
java-version: 21
java-version: 17
distribution: 'zulu'
- name: "Compile Dubbo (Linux)"
@ -449,7 +333,7 @@ jobs:
- name: "Upload error code inspection result"
# always() should not be used here, since we don't need to handle the 'canceled' situation.
if: ${{ success() || failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v2
with:
name: "error-inspection-result"
path: ${{ github.workspace }}/dubbo-test-tools/dubbo-error-code-inspector/error-inspection-result.txt
@ -472,10 +356,10 @@ jobs:
- name: "Setup Zookeeper environment"
run: |
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
mv apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.4-bin/conf/zoo.cfg
apache-zookeeper-3.8.4-bin/bin/zkServer.sh start
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz
mv apache-zookeeper-3.7.1-bin/conf/zoo_sample.cfg apache-zookeeper-3.7.1-bin/conf/zoo.cfg
apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
- name: "Check environment"
run: |

5
.gitignore vendored
View File

@ -11,8 +11,6 @@ target/
.settings/
.project
.classpath
.externalToolBuilders
maven-eclipse.xml
# idea ignore
.idea/
@ -52,6 +50,3 @@ dubbo-demo/dubbo-demo-triple/build/*
.git.exec.error
# log files generated by testcase.
dubbo-rpc/dubbo-rpc-api/custom-access.log*

View File

@ -38,6 +38,7 @@ header:
- '**/*.fc'
- '**/*.javascript'
- '**/*.properties'
- '**/*.thrift'
- '**/*.sh'
- '**/*.bat'
- '**/*.md'

View File

@ -101,7 +101,7 @@ check 2.7.5 milestone for details.
* In consumer side the app cannot catch the exception from provider that is configured serialization="kryo". #4238
* fix StringUtils#isBlank #4725
* when the interfaceName of the Reference annotation has duplicated,the exception is puzzled #4160
* when anonymity bean is defined in spring contextdubbo throw npe #
* when anonymity bean is defined in spirng contextdubbo throw npe #
* add Thread ContextClassLoader #4712
* Fix judgment ipv4 address #4729
* The compilation of static methods should be excluded when generating the proxy. #4647
@ -184,7 +184,7 @@ check 2.7.5 milestone for details.
- Add a script to check dependencies license. [#3840](https://github.com/apache/dubbo/issues/3840)
- Change DynamicConfiguration definition to better adapt to Apollo's namespace storage model.[#3266](https://github.com/apache/dubbo/issues/3266)
- use equal explicit class to replace anonymous class [#4027](https://github.com/apache/dubbo/issues/4027)
- Separate Constants.java into some SubConstants Class [#3137](https://github.com/apache/dubbo/issues/3137)
- Seperate Constants.java into some SubConstants Class [#3137](https://github.com/apache/dubbo/issues/3137)
- Need to enhance DecodeableRpcResult error message [#3994](https://github.com/apache/dubbo/issues/3994)
- Provide more meaningful binary releases. [#2491](https://github.com/apache/dubbo/issues/2491)
- remove useless module-dubbo-test-integration [#3573](https://github.com/apache/dubbo/issues/3573)
@ -211,7 +211,7 @@ check 2.7.5 milestone for details.
- Fix consumer will generate wrong stackTrace. [#4137](https://github.com/apache/dubbo/issues/4137)
- nacos registry serviceName may conflict. [#4111](https://github.com/apache/dubbo/issues/4111)
- The client loses the listener when the network is reconnected. [#4115](https://github.com/apache/dubbo/issues/4115)
- fix registry urls increase forever when recreate reference proxy. [#4109](https://github.com/apache/dubbo/issues/4109)
- fix registery urls increase forever when recreate reference proxy. [#4109](https://github.com/apache/dubbo/issues/4109)
- In dubbo 2.7.1the watcher processor of zookeeper client throw Nullpointexception. [#3866](https://github.com/apache/dubbo/issues/3866)
- ReferenceConfig initialized not changed to false once subscribe throws exception [#4068](https://github.com/apache/dubbo/issues/4068)
- dubbo registry extension compatibility with dubbo 2.6.x. [#3882](https://github.com/apache/dubbo/issues/3882)
@ -400,7 +400,7 @@ Enhancement / New feature
* tag route. #3065
* Use Netty4 as default Netty version. #3029
* upporting Java 8 Date/Time type when serializing with Kryo #3519
* support config telnet #3511
* supoort config telnet #3511
* add annotation driven in MethodConfig and ArgumentConfig #2603
* add nacos-registry module #3296
* add `protocol` attribute in `@Rerefence` #3555
@ -416,7 +416,7 @@ BugFix
* SPI entires dup by 3 times #3315
* fix Consumer throws RpcException after RegistryDirectory notify in high QPS #2016
* fix NPE in @Reference when using Junit to test dubbo service #3429
* fix consumer always catch java.lang.reflect.UndeclaredThrowableException for any exception throws in provider #3386
* fix consuer always catch java.lang.reflect.UndeclaredThrowableException for any exception throws in provider #3386
* fix the priority of `DubboConfigConfigurationSelector ` #2897
* fix `@Rerefence#parameters()` not work #2301

2
NOTICE
View File

@ -1,5 +1,5 @@
Apache Dubbo
Copyright 2018-2024 The Apache Software Foundation
Copyright 2018-2023 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

107
README.md
View File

@ -6,10 +6,13 @@
![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")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/apache/dubbo.svg)](http://isitmaintained.com/project/apache/dubbo "Percentage of issues still open")
[![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Apache%20Dubbo%20is%20a%20high-performance%2C%20java%20based%2C%20open%20source%20RPC%20framework.&url=http://dubbo.apache.org/&via=ApacheDubbo&hashtags=rpc,java,dubbo,micro-service)
[![Twitter Follow](https://img.shields.io/twitter/follow/ApacheDubbo.svg?label=Follow&style=social&logoWidth=0)](https://twitter.com/intent/follow?screen_name=ApacheDubbo)
[![Gitter](https://badges.gitter.im/alibaba/dubbo.svg)](https://gitter.im/alibaba/dubbo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Apache Dubbo is a high-performance, Java-based open-source RPC framework. Please visit the [official site](http://dubbo.apache.org) for the quick start guide and documentation, as well as the [wiki](https://github.com/apache/dubbo/wiki) for news, FAQ, and release notes.
We are now collecting Dubbo user info to help us to improve Dubbo further. Kindly support us by providing your usage information on [Wanted: who's using dubbo](https://github.com/apache/dubbo/discussions/13842), thanks :)
We are now collecting Dubbo user info to help us to improve Dubbo further. Kindly support us by providing your usage information on [issue#9436: Wanted: who's using dubbo](https://github.com/apache/dubbo/issues/9436), thanks :)
## Architecture
@ -30,16 +33,16 @@ The following code snippet comes from [Dubbo Samples](https://github.com/apache/
```bash
git clone https://github.com/apache/dubbo-samples.git
cd dubbo-samples/1-basic/dubbo-samples-api
cd dubbo-samples/dubbo-samples-api
```
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
### Maven dependency
```xml
<properties>
<dubbo.version>3.2.13-SNAPSHOT</dubbo.version>
<dubbo.version>3.0.10</dubbo.version>
</properties>
<dependencies>
@ -180,88 +183,58 @@ If you want to try out the cutting-edge features, you can build with the followi
## Recommended Test Environment
To avoid intermittent test failures (i.e., flaky tests), it is recommended to have a machine or virtual machine with the following specifications:
* Minimum of 2CPUs.
* Minumum of 2CPUs.
* Minimum of 2Gb of RAM.
### How does the Dubbo Community collaborate?
The Dubbo Community primarily communicates on GitHub through issues, discussions, and pull requests.
- Issues: We use issues to track bugs and tasks. Any **work-related** item is associated with an issue.
- Discussions: We use discussions for questions, early proposals, and announcements. Any **idea-related** item is associated with a discussion.
- Pull Requests: We use pull requests to merge a set of changes from contributors into Dubbo.
We have also implemented [a project board](https://github.com/orgs/apache/projects/337) to monitor all the items.
Any essential changes should be discussed on the mailing list before they happen.
### Seeking for help
If you have questions such as:
- What is Dubbo?
- How do I use Dubbo?
- Why did an unexpected result occur?
Please start a discussion at https://github.com/apache/dubbo/discussions.
However, if you encounter the following situations:
- You're certain there's a bug that Dubbo needs to fix,
- You believe a feature could be enhanced,
- You have a detailed proposal for improving Dubbo,
Please open an issue at https://github.com/apache/dubbo/issues.
To ask effective questions, we recommend reading **[How To Ask Questions The Smart Way](https://github.com/selfteaching/How-To-Ask-Questions-The-Smart-Way/blob/master/How-To-Ask-Questions-The-Smart-Way.md)** first.
### Contribution
- Browse the "help wanted" tasks in the [Dubbo project board](https://github.com/orgs/apache/projects/337).
- Participate in discussions on the mailing list. See the subscription [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide).
- Respond to queries in the [discussions](https://github.com/apache/dubbo/issues).
- Resolve bugs reported in [issues](https://github.com/apache/dubbo/issues) and send us a pull request.
- Review existing [pull requests](https://github.com/apache/dubbo/pulls).
- Enhance the [website](https://github.com/apache/dubbo-website). We typically need:
- Blog posts
- Translations for documentation
- Use cases showcasing Dubbo integration in enterprise systems.
- Improve the [dubbo-admin](https://github.com/apache/dubbo-admin).
- Contribute to the projects listed in the [ecosystem](https://github.com/apache/?q=dubbo&type=all&language=&sort=).
- Any other forms of contribution not listed above are also welcome.
- If you're interested in contributing, please send an email to [dev@dubbo.apache.org](mailto:dev@dubbo.apache.org) to let us know!
For further details, please refer our [guide](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) about how to contribute Dubbo.
## Reporting bugs
Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
## Reporting a security vulnerability
Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org) privately.
## Contact
* Mailing list:
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
* Bugs: [Issues](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md)
* Gitter: [Gitter channel](https://gitter.im/alibaba/dubbo)
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
## Contributing
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
### How can I contribute?
* Take a look at issues with tags marked [`Good first issue`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or [`Help wanted`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).
* Join the discussion on the mailing list, subscription [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide).
* Answer questions on [issues](https://github.com/apache/dubbo/issues).
* Fix bugs reported on [issues](https://github.com/apache/dubbo/issues), and send us a pull request.
* Review the existing [pull request](https://github.com/apache/dubbo/pulls).
* Improve the [website](https://github.com/apache/dubbo-website), typically we need
* blog post
* translation on documentation
* use cases around the integration of Dubbo in enterprise systems.
* Improve the [dubbo-admin/dubbo-monitor](https://github.com/apache/dubbo-admin).
* Contribute to the projects listed in [ecosystem](https://github.com/dubbo).
* Other forms of contribution not explicitly enumerated above.
* If you would like to contribute, please send an email to dev@dubbo.apache.org to let us know!
## Reporting bugs
Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
## Reporting a security vulnerability
Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org) privately.
## Dubbo ecosystem
* [Dubbo Ecosystem Entry](https://github.com/apache?utf8=%E2%9C%93&q=dubbo&type=&language=) - A GitHub group `dubbo` to gather all Dubbo relevant projects not appropriate in [apache](https://github.com/apache) group yet
* [Dubbo Website](https://github.com/apache/dubbo-website) - Apache Dubbo official website
* [Dubbo Samples](https://github.com/apache/dubbo-samples) - samples for Apache Dubbo
* [Dubbo Spring Boot](https://github.com/apache/dubbo-spring-boot-project) - Spring Boot Project for Dubbo
* [Dubbo Admin](https://github.com/apache/dubbo-admin) - The reference implementation for Dubbo admin
* [Dubbo Awesome](https://github.com/apache/dubbo-awesome) - Dubbo's slides and video links in Meetup
#### Language
* [Go](https://github.com/apache/dubbo-go) (recommended)
* [Rust](https://github.com/apache/dubbo-rust)
* [Go](https://github.com/dubbo/dubbo-go) (recommended)
* [Node.js](https://github.com/apache/dubbo-js)
* [Python](https://github.com/dubbo/py-client-for-apache-dubbo)
* [PHP](https://github.com/apache/dubbo-php-framework)
@ -269,4 +242,4 @@ Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org)
## License
Apache Dubbo software is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
Apache Dubbo software is licenced under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.

View File

@ -5,15 +5,13 @@
Below is a table that shows versions that we accept security fixes.
| Version | Supported |
|---------| ------------------ |
| 3.3.x | :white_check_mark: |
| 3.2.x | :white_check_mark: |
| 3.1.x | :white_check_mark: |
| 3.0.x | :x: |
| 2.7.x | :x: |
| 2.6.x | :x: |
| ------- | ------------------ |
| 3.0.x | :white_check_mark: |
| 2.7.x | :white_check_mark: |
| 2.6.x | :white_check_mark: |
| 2.5.x | :x: |
## Reporting a Vulnerability
The Apache Software Foundation takes a rigorous standpoint in annihilating the security issues in its software projects. Apache Dubbo is highly sensitive and forthcoming to issues pertaining to its features and functionality.

View File

@ -32,3 +32,4 @@ ignore:
- "**/dubbo-native-plugin/**"
- "**/dubbo-common/src/main/java/org/apache/dubbo/common/json/*.java" # internal JSON impl is deprecate, ignore test coverage for them
- "**/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java" # Deprecated
- "**/dubbo-rpc/dubbo-rpc-thrift/**"

View File

@ -13,77 +13,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-build-tools</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-build-tools</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<spotless-maven-plugin.version>2.43.0</spotless-maven-plugin.version>
<spotless.action>check</spotless.action>
<dubbo-shared-resources.version>1.0.0</dubbo-shared-resources.version>
<palantirJavaFormat.version>2.38.0</palantirJavaFormat.version>
</properties>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<profiles>
<profile>
<id>java11+</id>
<activation>
<jdk>[11,)</jdk>
</activation>
<build>
<!--- newer versions of plugins requires JDK 11 -->
<plugins>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless-maven-plugin.version}</version>
<configuration>
<java>
<palantirJavaFormat>
<version>${palantirJavaFormat.version}</version>
</palantirJavaFormat>
<removeUnusedImports />
<importOrder>
<file>dubbo-importorder.txt</file>
</importOrder>
<licenseHeader>
<file>checkstyle-header.txt</file>
</licenseHeader>
</java>
<pom>
<sortPom>
<expandEmptyElements>false</expandEmptyElements>
<spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement>
</sortPom>
</pom>
<upToDateChecking>
<enabled>true</enabled>
</upToDateChecking>
</configuration>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-shared-resources</artifactId>
<version>${dubbo-shared-resources.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>${spotless.action}</goal>
</goals>
<phase>process-sources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
</project>

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -15,104 +14,82 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-cluster</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The cluster module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
<nashorn-core.version>15.4</nashorn-core.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-injvm</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-fastjson2</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-check</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-registry</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-default</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<!--
https://github.com/openjdk/nashorn
Nashorn used to be part of the JDK until Java 14.
This project provides a standalone version of Nashorn suitable for use with Java 11 and later.
-->
<profile>
<id>nashorn-jdk11</id>
<activation>
<jdk>[11,)</jdk>
</activation>
<dependencies>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-cluster</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The cluster module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>${nashorn-core.version}</version>
<scope>test</scope>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-injvm</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-fastjson2</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-check</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-registry</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-default</artifactId>
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -35,5 +35,8 @@ public interface AddressListener {
*/
List<URL> notify(List<URL> addresses, URL consumerUrl, Directory registryDirectory);
default void destroy(URL consumerUrl, Directory registryDirectory) {}
default void destroy(URL consumerUrl, Directory registryDirectory) {
}
}

View File

@ -55,8 +55,6 @@ public interface Cluster {
if (StringUtils.isEmpty(name)) {
name = Cluster.DEFAULT;
}
return ScopeModelUtil.getApplicationModel(scopeModel)
.getExtensionLoader(Cluster.class)
.getExtension(name, wrap);
return ScopeModelUtil.getApplicationModel(scopeModel).getExtensionLoader(Cluster.class).getExtension(name, wrap);
}
}

View File

@ -51,6 +51,7 @@ public interface Configurator extends Comparable<Configurator> {
*/
URL configure(URL url);
/**
* Convert override urls to map for use when re-refer. Send all rules every time, the urls will be reassembled and
* calculated
@ -72,9 +73,7 @@ public interface Configurator extends Comparable<Configurator> {
return Optional.empty();
}
ConfiguratorFactory configuratorFactory = urls.get(0)
.getOrDefaultApplicationModel()
.getExtensionLoader(ConfiguratorFactory.class)
ConfiguratorFactory configuratorFactory = urls.get(0).getOrDefaultApplicationModel().getExtensionLoader(ConfiguratorFactory.class)
.getAdaptiveExtension();
List<Configurator> configurators = new ArrayList<>(urls.size());
@ -84,8 +83,7 @@ public interface Configurator extends Comparable<Configurator> {
break;
}
Map<String, String> override = new HashMap<>(url.getParameters());
// The anyhost parameter of override may be added automatically, it can't change the judgement of changing
// url
//The anyhost parameter of override may be added automatically, it can't change the judgement of changing url
override.remove(ANYHOST_KEY);
if (CollectionUtils.isEmptyMap(override)) {
continue;

View File

@ -36,4 +36,5 @@ public interface ConfiguratorFactory {
*/
@Adaptive(CommonConstants.PROTOCOL_KEY)
Configurator getConfigurator(URL url);
}

View File

@ -100,6 +100,7 @@ public interface Constants {
String OVERRIDE_PROVIDERS_KEY = "providerAddresses";
/**
* key for router type, for e.g., "script"/"file", corresponding to ScriptRouterFactory.NAME, FileRouterFactory.NAME
*/

View File

@ -46,4 +46,5 @@ public interface LoadBalance {
*/
@Adaptive("loadbalance")
<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;
}

View File

@ -22,4 +22,5 @@ import org.apache.dubbo.common.extension.SPI;
public interface Merger<T> {
T merge(T... items);
}

View File

@ -33,9 +33,7 @@ public interface ProviderURLMergeProcessor {
*/
URL mergeUrl(URL remoteUrl, Map<String, String> localParametersMap);
default Map<String, String> mergeLocalParams(Map<String, String> localMap) {
return localMap;
}
default Map<String, String> mergeLocalParams(Map<String, String> localMap) { return localMap; }
default boolean accept(URL providerUrl, Map<String, String> localParametersMap) {
return true;

View File

@ -68,8 +68,8 @@ public interface Router extends Comparable<Router> {
* @return state with route result
* @throws RpcException
*/
default <T> RouterResult<Invoker<T>> route(
List<Invoker<T>> invokers, URL url, Invocation invocation, boolean needToPrintMessage) throws RpcException {
default <T> RouterResult<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation,
boolean needToPrintMessage) throws RpcException {
return new RouterResult<>(route(invokers, url, invocation));
}
@ -80,7 +80,9 @@ public interface Router extends Comparable<Router> {
* @param invokers invoker list
* @param <T> invoker's type
*/
default <T> void notify(List<Invoker<T>> invokers) {}
default <T> void notify(List<Invoker<T>> invokers) {
}
/**
* To decide whether this router need to execute every time an RPC comes or should only execute when addresses or
@ -107,7 +109,7 @@ public interface Router extends Comparable<Router> {
int getPriority();
default void stop() {
// do nothing by default
//do nothing by default
}
@Override

View File

@ -16,6 +16,12 @@
*/
package org.apache.dubbo.rpc.cluster;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.LoggerCodeConstants;
@ -30,12 +36,6 @@ import org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
/**
@ -52,30 +52,31 @@ public class RouterChain<T> {
public static <T> RouterChain<T> buildChain(Class<T> interfaceClass, URL url) {
SingleRouterChain<T> chain1 = buildSingleChain(interfaceClass, url);
SingleRouterChain<T> chain2 = buildSingleChain(interfaceClass, url);
return new RouterChain<>(new SingleRouterChain[] {chain1, chain2});
return new RouterChain<>(new SingleRouterChain[]{chain1, chain2});
}
public static <T> SingleRouterChain<T> buildSingleChain(Class<T> interfaceClass, URL url) {
ModuleModel moduleModel = url.getOrDefaultModuleModel();
List<RouterFactory> extensionFactories =
moduleModel.getExtensionLoader(RouterFactory.class).getActivateExtension(url, ROUTER_KEY);
List<RouterFactory> extensionFactories = moduleModel.getExtensionLoader(RouterFactory.class)
.getActivateExtension(url, ROUTER_KEY);
List<Router> routers = extensionFactories.stream()
.map(factory -> factory.getRouter(url))
.sorted(Router::compareTo)
.collect(Collectors.toList());
.map(factory -> factory.getRouter(url))
.sorted(Router::compareTo)
.collect(Collectors.toList());
List<StateRouter<T>> stateRouters =
moduleModel.getExtensionLoader(StateRouterFactory.class).getActivateExtension(url, ROUTER_KEY).stream()
.map(factory -> factory.getRouter(interfaceClass, url))
.collect(Collectors.toList());
List<StateRouter<T>> stateRouters = moduleModel
.getExtensionLoader(StateRouterFactory.class)
.getActivateExtension(url, ROUTER_KEY)
.stream()
.map(factory -> factory.getRouter(interfaceClass, url))
.collect(Collectors.toList());
boolean shouldFailFast = Boolean.parseBoolean(
ConfigurationUtils.getProperty(moduleModel, Constants.SHOULD_FAIL_FAST_KEY, "true"));
RouterSnapshotSwitcher routerSnapshotSwitcher =
ScopeModelUtil.getFrameworkModel(moduleModel).getBeanFactory().getBean(RouterSnapshotSwitcher.class);
boolean shouldFailFast = Boolean.parseBoolean(ConfigurationUtils.getProperty(moduleModel, Constants.SHOULD_FAIL_FAST_KEY, "true"));
RouterSnapshotSwitcher routerSnapshotSwitcher = ScopeModelUtil.getFrameworkModel(moduleModel).getBeanFactory().getBean(RouterSnapshotSwitcher.class);
return new SingleRouterChain<>(routers, stateRouters, shouldFailFast, routerSnapshotSwitcher);
}
@ -105,9 +106,9 @@ public class RouterChain<T> {
// If `availableInvokers` is created from origin invokers => use backup chain
// If `availableInvokers` is created from newly invokers => use main chain
BitList<Invoker<T>> notifying = notifyingInvokers.get();
if (notifying != null
&& currentChain == backupChain
&& availableInvokers.getOriginList() == notifying.getOriginList()) {
if (notifying != null &&
currentChain == backupChain &&
availableInvokers.getOriginList() == notifying.getOriginList()) {
return mainChain;
}
return currentChain;
@ -139,8 +140,7 @@ public class RouterChain<T> {
}
// Refresh main chain.
// No one can request to use main chain. `currentChain` is backup chain. `route` method cannot access main
// chain.
// No one can request to use main chain. `currentChain` is backup chain. `route` method cannot access main chain.
try {
// Lock main chain to wait all invocation end
// To wait until no one is using main chain.
@ -157,32 +157,26 @@ public class RouterChain<T> {
}
// Set the reference of newly invokers to temp variable.
// Reason: The next step will switch the invokers reference in directory, so we should check the
// `availableInvokers`
// argument when `route`. If the current invocation use newly invokers, we should use main chain to
// route, and
// Reason: The next step will switch the invokers reference in directory, so we should check the `availableInvokers`
// argument when `route`. If the current invocation use newly invokers, we should use main chain to route, and
// this can prevent use newly invokers to route backup chain, which can only route origin invokers now.
notifyingInvokers.set(invokers);
// Switch the invokers reference in directory.
// Cannot switch before update main chain or after backup chain update success. Or that will cause state
// inconsistent.
// Cannot switch before update main chain or after backup chain update success. Or that will cause state inconsistent.
switchAction.run();
try {
// Lock to prevent directory continue list
// The invokers reference in directory now should be the newly one and should always use the newly one once
// lock released.
// The invokers reference in directory now should be the newly one and should always use the newly one once lock released.
lock.writeLock().lock();
// Switch to main chain. Will update backup chain later.
currentChain = mainChain;
// Clean up temp variable.
// `availableInvokers` check is useless now, because `route` method will no longer receive any
// `availableInvokers` related
// with the origin invokers. The getter of invokers reference in directory is locked now, and will return
// newly invokers
// `availableInvokers` check is useless now, because `route` method will no longer receive any `availableInvokers` related
// with the origin invokers. The getter of invokers reference in directory is locked now, and will return newly invokers
// once lock released.
notifyingInvokers.set(null);
} finally {
@ -192,8 +186,7 @@ public class RouterChain<T> {
}
// Refresh main chain.
// No one can request to use main chain. `currentChain` is main chain. `route` method cannot access backup
// chain.
// No one can request to use main chain. `currentChain` is main chain. `route` method cannot access backup chain.
try {
// Lock main chain to wait all invocation end
backupChain.getLock().writeLock().lock();

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.URL;
@ -25,4 +26,5 @@ import java.util.List;
public interface RuleConverter {
List<URL> convert(URL subscribeUrl, Object source);
}

View File

@ -16,6 +16,13 @@
*/
package org.apache.dubbo.rpc.cluster;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
@ -33,13 +40,6 @@ import org.apache.dubbo.rpc.cluster.router.state.BitList;
import org.apache.dubbo.rpc.cluster.router.state.StateRouter;
import org.apache.dubbo.rpc.cluster.router.state.TailStateRouter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_STOP;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_NO_VALID_PROVIDER;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR;
@ -79,11 +79,7 @@ public class SingleRouterChain<T> {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public SingleRouterChain(
List<Router> routers,
List<StateRouter<T>> stateRouters,
boolean shouldFailFast,
RouterSnapshotSwitcher routerSnapshotSwitcher) {
public SingleRouterChain(List<Router> routers, List<StateRouter<T>> stateRouters, boolean shouldFailFast, RouterSnapshotSwitcher routerSnapshotSwitcher) {
initWithRouters(routers);
initWithStateRouters(stateRouters);
@ -138,12 +134,9 @@ public class SingleRouterChain<T> {
public List<Invoker<T>> route(URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
if (invokers.getOriginList() != availableInvokers.getOriginList()) {
logger.error(
INTERNAL_ERROR,
"",
"Router's invoker size: " + invokers.getOriginList().size() + " Invocation's invoker size: "
+ availableInvokers.getOriginList().size(),
"Reject to route, because the invokers has changed.");
logger.error(INTERNAL_ERROR, "", "Router's invoker size: " + invokers.getOriginList().size() +
" Invocation's invoker size: " + availableInvokers.getOriginList().size(),
"Reject to route, because the invokers has changed.");
throw new IllegalStateException("reject to route, because the invokers has changed.");
}
if (RpcContext.getServiceContext().isNeedPrintRouterSnapshot()) {
@ -209,10 +202,9 @@ public class SingleRouterChain<T> {
/**
* Build each router's result
*/
public RouterSnapshotNode<T> buildRouterSnapshot(
URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
public RouterSnapshotNode<T> buildRouterSnapshot(URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
BitList<Invoker<T>> resultInvokers = availableInvokers.clone();
RouterSnapshotNode<T> parentNode = new RouterSnapshotNode<>("Parent", resultInvokers.clone());
RouterSnapshotNode<T> parentNode = new RouterSnapshotNode<T>("Parent", resultInvokers.clone());
parentNode.setNodeOutputInvokers(resultInvokers.clone());
// 1. route state router
@ -227,7 +219,7 @@ public class SingleRouterChain<T> {
return parentNode;
}
RouterSnapshotNode<T> commonRouterNode = new RouterSnapshotNode<>("CommonRouter", resultInvokers.clone());
RouterSnapshotNode<T> commonRouterNode = new RouterSnapshotNode<T>("CommonRouter", resultInvokers.clone());
parentNode.appendNode(commonRouterNode);
List<Invoker<T>> commonRouterResult = resultInvokers;
@ -236,8 +228,7 @@ public class SingleRouterChain<T> {
// Copy resultInvokers to a arrayList. BitList not support
List<Invoker<T>> inputInvokers = new ArrayList<>(commonRouterResult);
RouterSnapshotNode<T> currentNode =
new RouterSnapshotNode<>(router.getClass().getSimpleName(), inputInvokers);
RouterSnapshotNode<T> currentNode = new RouterSnapshotNode<T>(router.getClass().getSimpleName(), inputInvokers);
// append to router node chain
commonRouterNode.appendNode(currentNode);
@ -277,27 +268,24 @@ public class SingleRouterChain<T> {
}
private void logRouterSnapshot(URL url, Invocation invocation, RouterSnapshotNode<T> snapshotNode) {
if (snapshotNode.getChainOutputInvokers() == null
|| snapshotNode.getChainOutputInvokers().isEmpty()) {
if (snapshotNode.getChainOutputInvokers() == null ||
snapshotNode.getChainOutputInvokers().isEmpty()) {
if (logger.isWarnEnabled()) {
String message = "No provider available after route for the service " + url.getServiceKey()
+ " from registry " + url.getAddress()
+ " on the consumer " + NetUtils.getLocalHost()
+ " using the dubbo version " + Version.getVersion() + ". Router snapshot is below: \n"
+ snapshotNode.toString();
+ " from registry " + url.getAddress()
+ " on the consumer " + NetUtils.getLocalHost()
+ " using the dubbo version " + Version.getVersion() + ". Router snapshot is below: \n" + snapshotNode.toString();
if (routerSnapshotSwitcher.isEnable()) {
routerSnapshotSwitcher.setSnapshot(message);
}
logger.warn(
CLUSTER_NO_VALID_PROVIDER, "No provider available after route for the service", "", message);
logger.warn(CLUSTER_NO_VALID_PROVIDER, "No provider available after route for the service", "", message);
}
} else {
if (logger.isInfoEnabled()) {
String message = "Router snapshot service " + url.getServiceKey()
+ " from registry " + url.getAddress()
+ " on the consumer " + NetUtils.getLocalHost()
+ " using the dubbo version " + Version.getVersion() + " is below: \n"
+ snapshotNode.toString();
+ " from registry " + url.getAddress()
+ " on the consumer " + NetUtils.getLocalHost()
+ " using the dubbo version " + Version.getVersion() + " is below: \n" + snapshotNode.toString();
if (routerSnapshotSwitcher.isEnable()) {
routerSnapshotSwitcher.setSnapshot(message);
}
@ -342,12 +330,7 @@ public class SingleRouterChain<T> {
try {
router.stop();
} catch (Exception e) {
logger.error(
CLUSTER_FAILED_STOP,
"route stop failed",
"",
"Error trying to stop router " + router.getClass(),
e);
logger.error(CLUSTER_FAILED_STOP, "route stop failed", "", "Error trying to stop router " + router.getClass(), e);
}
}
routers = Collections.emptyList();
@ -357,12 +340,7 @@ public class SingleRouterChain<T> {
try {
router.stop();
} catch (Exception e) {
logger.error(
CLUSTER_FAILED_STOP,
"StateRouter stop failed",
"",
"Error trying to stop StateRouter " + router.getClass(),
e);
logger.error(CLUSTER_FAILED_STOP, "StateRouter stop failed", "", "Error trying to stop StateRouter " + router.getClass(), e);
}
}
stateRouters = Collections.emptyList();

View File

@ -72,10 +72,7 @@ public abstract class AbstractConfigurator implements Configurator {
@Override
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) {
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;
}
@ -101,9 +98,7 @@ public abstract class AbstractConfigurator implements Configurator {
@Deprecated
private URL configureDeprecated(URL url) {
// If override url has port, means it is a provider address. We want to control a specific provider with this
// override url, it may take effect on the specific provider instance or on consumers holding this provider
// instance.
// If override url has port, means it is a provider address. We want to control a specific provider with this override url, it may take effect on the specific provider instance or on consumers holding this provider instance.
if (configuratorUrl.getPort() != 0) {
if (url.getPort() == configuratorUrl.getPort()) {
return configureIfMatch(url.getHost(), url);
@ -133,11 +128,10 @@ public abstract class AbstractConfigurator implements Configurator {
if (apiVersion != null && apiVersion.startsWith(RULE_VERSION_V30)) {
ConditionMatch matcher = (ConditionMatch) configuratorUrl.getAttribute(MATCH_CONDITION);
if (matcher != null) {
if (matcher.isMatch(host, url)) {
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);
logger.debug("Cannot apply configurator rule, param mismatch, current params are " + url + ", params in rule is " + matcher);
}
} else {
return doConfigure(url, configuratorUrl.removeParameters(conditionKeys));
@ -147,8 +141,7 @@ public abstract class AbstractConfigurator implements Configurator {
}
}
} else {
logger.debug("Cannot apply configurator rule, host mismatch, current host is " + host + ", host in rule is "
+ configuratorUrl.getHost());
logger.debug("Cannot apply configurator rule, host mismatch, current host is " + host + ", host in rule is " + configuratorUrl.getHost());
}
return url;
}
@ -166,16 +159,15 @@ public abstract class AbstractConfigurator implements Configurator {
String[] providerAddresses = providers.split(CommonConstants.COMMA_SEPARATOR);
for (String address : providerAddresses) {
if (address.equals(url.getAddress())
|| address.equals(ANYHOST_VALUE)
|| address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + ANY_VALUE)
|| address.equals(ANYHOST_VALUE + CommonConstants.GROUP_CHAR_SEPARATOR + url.getPort())
|| address.equals(url.getHost())) {
|| address.equals(ANYHOST_VALUE)
|| 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;
}
}
if (!match) {
logger.debug("Cannot apply configurator rule, provider address mismatch, current address "
+ url.getAddress() + ", address in rule is " + providers);
logger.debug("Cannot apply configurator rule, provider address mismatch, current address " + url.getAddress() + ", address in rule is " + providers);
return false;
}
}
@ -183,18 +175,17 @@ public abstract class AbstractConfigurator implements Configurator {
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);
&& !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);
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;
}
@ -211,9 +202,8 @@ public abstract class AbstractConfigurator implements Configurator {
if (startWithTilde) {
conditionKeys.add(key);
}
if (value != null
&& !ANY_VALUE.equals(value)
&& !value.equals(url.getParameter(startWithTilde ? key.substring(1) : key))) {
if (value != null && !ANY_VALUE.equals(value)
&& !value.equals(url.getParameter(startWithTilde ? key.substring(1) : key))) {
result = false;
break;
}
@ -223,7 +213,7 @@ public abstract class AbstractConfigurator implements Configurator {
}
private Set<String> genConditionKeys() {
Set<String> conditionKeys = new HashSet<>();
Set<String> conditionKeys = new HashSet<String>();
conditionKeys.add(CATEGORY_KEY);
conditionKeys.add(Constants.CHECK_KEY);
conditionKeys.add(DYNAMIC_KEY);
@ -243,4 +233,5 @@ public abstract class AbstractConfigurator implements Configurator {
}
protected abstract URL doConfigure(URL currentUrl, URL configUrl);
}

View File

@ -32,4 +32,5 @@ public class AbsentConfigurator extends AbstractConfigurator {
public URL doConfigure(URL currentUrl, URL configUrl) {
return currentUrl.addParametersIfAbsent(configUrl.getParameters());
}
}

View File

@ -30,4 +30,5 @@ public class AbsentConfiguratorFactory implements ConfiguratorFactory {
public Configurator getConfigurator(URL url) {
return new AbsentConfigurator(url);
}
}

View File

@ -36,4 +36,5 @@ public class OverrideConfigurator extends AbstractConfigurator {
logger.info("Start overriding url " + currentUrl + " with override url " + configUrl);
return currentUrl.addParameters(configUrl.getParameters());
}
}

View File

@ -30,4 +30,5 @@ public class OverrideConfiguratorFactory implements ConfiguratorFactory {
public Configurator getConfigurator(URL url) {
return new OverrideConfigurator(url);
}
}

View File

@ -23,14 +23,14 @@ import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfigItem;
import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import java.util.ArrayList;
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;
@ -104,12 +104,7 @@ public class ConfigParser {
if (CollectionUtils.isNotEmpty(apps)) {
apps.forEach(app -> {
StringBuilder tmpUrlBuilder = new StringBuilder(urlBuilder);
urls.add(appendMatchCondition(
URL.valueOf(tmpUrlBuilder
.append("&application=")
.append(app)
.toString()),
item));
urls.add(appendMatchCondition(URL.valueOf(tmpUrlBuilder.append("&application=").append(app).toString()), item));
});
} else {
urls.add(appendMatchCondition(URL.valueOf(urlBuilder.toString()), item));
@ -160,8 +155,8 @@ public class ConfigParser {
}
Map<String, String> parameters = item.getParameters();
if (CollectionUtils.isEmptyMap(parameters)) {
throw new IllegalStateException("Invalid configurator rule, please specify at least one parameter "
+ "you want to change in the rule.");
throw new IllegalStateException("Invalid configurator rule, please specify at least one parameter " +
"you want to change in the rule.");
}
parameters.forEach((k, v) -> {

View File

@ -26,7 +26,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
public class ConditionMatch {
private AddressMatch address;
private AddressMatch providerAddress;
private ListStringMatch service;
private ListStringMatch app;
private List<ParamMatch> param;
@ -39,14 +38,6 @@ public class ConditionMatch {
this.address = address;
}
public AddressMatch getProviderAddress() {
return providerAddress;
}
public void setProviderAddress(AddressMatch providerAddress) {
this.providerAddress = providerAddress;
}
public ListStringMatch getService() {
return service;
}
@ -71,12 +62,8 @@ public class ConditionMatch {
this.param = param;
}
public boolean isMatch(String host, URL url) {
if (getAddress() != null && !getAddress().isMatch(host)) {
return false;
}
if (getProviderAddress() != null && !getProviderAddress().isMatch(url.getAddress())) {
public boolean isMatch(URL url) {
if (getAddress() != null && !getAddress().isMatch(url.getAddress())) {
return false;
}
@ -101,11 +88,11 @@ public class ConditionMatch {
@Override
public String toString() {
return "ConditionMatch{" + "address='"
+ address + '\'' + "providerAddress='"
+ providerAddress + '\'' + ", service='"
+ service + '\'' + ", app='"
+ app + '\'' + ", param='"
+ param + '\'' + '}';
return "ConditionMatch{" +
"address='" + address + '\'' +
", service='" + service + '\'' +
", app='" + app + '\'' +
", param='" + param + '\'' +
'}';
}
}

View File

@ -68,33 +68,32 @@ public class ConfigItem {
Object addresses = map.get(ADDRESSES_KEY);
if (addresses != null && List.class.isAssignableFrom(addresses.getClass())) {
configItem.setAddresses(
((List<Object>) addresses).stream().map(String::valueOf).collect(Collectors.toList()));
configItem.setAddresses(((List<Object>) addresses).stream()
.map(String::valueOf).collect(Collectors.toList()));
}
Object providerAddresses = map.get(PROVIDER_ADDRESSES_KEY);
if (providerAddresses != null && List.class.isAssignableFrom(providerAddresses.getClass())) {
configItem.setProviderAddresses(((List<Object>) providerAddresses)
.stream().map(String::valueOf).collect(Collectors.toList()));
configItem.setProviderAddresses(((List<Object>) providerAddresses).stream()
.map(String::valueOf).collect(Collectors.toList()));
}
Object services = map.get(SERVICES_KEY);
if (services != null && List.class.isAssignableFrom(services.getClass())) {
configItem.setServices(
((List<Object>) services).stream().map(String::valueOf).collect(Collectors.toList()));
configItem.setServices(((List<Object>) services).stream()
.map(String::valueOf).collect(Collectors.toList()));
}
Object applications = map.get(APPLICATIONS_KEY);
if (applications != null && List.class.isAssignableFrom(applications.getClass())) {
configItem.setApplications(
((List<Object>) applications).stream().map(String::valueOf).collect(Collectors.toList()));
configItem.setApplications(((List<Object>) applications).stream()
.map(String::valueOf).collect(Collectors.toList()));
}
Object parameters = map.get(PARAMETERS_KEY);
if (parameters != null && Map.class.isAssignableFrom(parameters.getClass())) {
configItem.setParameters(((Map<String, Object>) parameters)
.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue()
.toString())));
configItem.setParameters(((Map<String, Object>) parameters).entrySet()
.stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().toString())));
}
try {
@ -103,12 +102,7 @@ public class ConfigItem {
configItem.setMatch(PojoUtils.mapToPojo((Map<String, Object>) 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);
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));

View File

@ -52,8 +52,8 @@ public class ConfiguratorConfig {
Object configs = map.get(CONFIGS_KEY);
if (configs != null && List.class.isAssignableFrom(configs.getClass())) {
configuratorConfig.setConfigs(((List<Map<String, Object>>) configs)
.stream().map(ConfigItem::parseFromMap).collect(Collectors.toList()));
configuratorConfig.setConfigs(((List<Map<String, Object>>) configs).stream()
.map(ConfigItem::parseFromMap).collect(Collectors.toList()));
}
return configuratorConfig;

View File

@ -40,16 +40,19 @@ public class ParamMatch {
}
public boolean isMatch(URL url) {
if (key == null || value == null) {
if (key == null) {
return false;
}
String input = url.getParameter(key);
return value.isMatch(input);
return input != null && value.isMatch(input);
}
@Override
public String toString() {
return "ParamMatch{" + "key='" + key + '\'' + ", value='" + value + '\'' + '}';
return "ParamMatch{" +
"key='" + key + '\'' +
", value='" + value + '\'' +
'}';
}
}

View File

@ -25,7 +25,6 @@ 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.LockUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metrics.event.MetricsEventBus;
@ -57,8 +56,6 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
@ -125,8 +122,6 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
private volatile ScheduledFuture<?> connectivityCheckFuture;
private final ReentrantLock invokerRefreshLock = new ReentrantLock();
/**
* The max count of invokers for each reconnect task select to try to reconnect.
*/
@ -165,20 +160,18 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
// remove some local only parameters
applicationModel = url.getOrDefaultApplicationModel();
this.queryMap =
applicationModel.getBeanFactory().getBean(ClusterUtils.class).mergeLocalParams(queryMap);
this.queryMap = applicationModel.getBeanFactory().getBean(ClusterUtils.class).mergeLocalParams(queryMap);
if (consumerUrl == null) {
String host =
isNotEmpty(queryMap.get(REGISTER_IP_KEY)) ? queryMap.get(REGISTER_IP_KEY) : this.url.getHost();
String host = isNotEmpty(queryMap.get(REGISTER_IP_KEY)) ? queryMap.get(REGISTER_IP_KEY) : this.url.getHost();
String path = isNotEmpty(queryMap.get(PATH_KEY)) ? queryMap.get(PATH_KEY) : queryMap.get(INTERFACE_KEY);
String consumedProtocol = isNotEmpty(queryMap.get(PROTOCOL_KEY)) ? queryMap.get(PROTOCOL_KEY) : CONSUMER;
URL consumerUrlFrom = this.url
.setHost(host)
.setPort(0)
.setProtocol(consumedProtocol)
.setPath(path);
.setHost(host)
.setPort(0)
.setProtocol(consumedProtocol)
.setPath(path);
if (isUrlFromRegistry) {
// reserve parameters if url is already a consumer url
consumerUrlFrom = consumerUrlFrom.clearParameters();
@ -186,23 +179,19 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
this.consumerUrl = consumerUrlFrom.addParameters(queryMap);
}
this.connectivityExecutor = applicationModel
.getFrameworkModel()
.getBeanFactory()
.getBean(FrameworkExecutorRepository.class)
.getConnectivityScheduledExecutor();
this.connectivityExecutor = applicationModel.getFrameworkModel().getBeanFactory()
.getBean(FrameworkExecutorRepository.class).getConnectivityScheduledExecutor();
Configuration configuration = ConfigurationUtils.getGlobalConfiguration(url.getOrDefaultModuleModel());
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);
}
@Override
public List<Invoker<T>> 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<Invoker<T>> availableInvokers;
@ -233,16 +222,14 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
if (routedResult.isEmpty()) {
// 2-2 - No provider available.
logger.warn(
CLUSTER_NO_VALID_PROVIDER,
"provider server or registry center crashed",
"",
"No provider available after connectivity filter for the service "
+ getConsumerUrl().getServiceKey()
+ " All routed invokers' size: " + routedResult.size()
+ " from registry " + this
+ " on the consumer " + NetUtils.getLocalHost()
+ " using the dubbo version " + Version.getVersion() + ".");
logger.warn(CLUSTER_NO_VALID_PROVIDER, "provider server or registry center crashed", "",
"No provider available after connectivity filter for the service " + getConsumerUrl().getServiceKey()
+ " All validInvokers' size: " + validInvokers.size()
+ " All routed invokers' size: " + routedResult.size()
+ " All invokers' size: " + invokers.size()
+ " from registry " + getUrl().getAddress()
+ " on the consumer " + NetUtils.getLocalHost()
+ " using the dubbo version " + Version.getVersion() + ".");
}
return Collections.unmodifiableList(routedResult);
} finally {
@ -298,109 +285,74 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
@Override
public void addInvalidateInvoker(Invoker<T> invoker) {
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
// 1. remove this invoker from validInvokers list, this invoker will not be listed in the next time
if (removeValidInvoker(invoker)) {
// 2. add this invoker to reconnect list
invokersToReconnect.add(invoker);
// 3. try start check connectivity task
checkConnectivity();
// 1. remove this invoker from validInvokers list, this invoker will not be listed in the next time
if (removeValidInvoker(invoker)) {
// 2. add this invoker to reconnect list
invokersToReconnect.add(invoker);
// 3. try start check connectivity task
checkConnectivity();
logger.info("The invoker " + invoker.getUrl()
+ " has been added to invalidate list due to connectivity problem. "
+ "Will trying to reconnect to it in the background.");
}
});
logger.info("The invoker " + invoker.getUrl() + " has been added to invalidate list due to connectivity problem. " +
"Will trying to reconnect to it in the background.");
}
}
public void checkConnectivity() {
// try to submit task, to ensure there is only one task at most for each directory
if (checkConnectivityPermit.tryAcquire()) {
this.connectivityCheckFuture = connectivityExecutor.schedule(
() -> {
try {
if (isDestroyed()) {
return;
this.connectivityCheckFuture = connectivityExecutor.schedule(() -> {
try {
if (isDestroyed()) {
return;
}
RpcContext.getServiceContext().setConsumerUrl(getConsumerUrl());
List<Invoker<T>> needDeleteList = new ArrayList<>();
List<Invoker<T>> invokersToTry = new ArrayList<>();
// 1. pick invokers from invokersToReconnect
// limit max reconnectTaskTryCount, prevent this task hang up all the connectivityExecutor for long time
if (invokersToReconnect.size() < reconnectTaskTryCount) {
invokersToTry.addAll(invokersToReconnect);
} else {
for (int i = 0; i < reconnectTaskTryCount; i++) {
Invoker<T> tInvoker = invokersToReconnect.get(ThreadLocalRandom.current().nextInt(invokersToReconnect.size()));
if (!invokersToTry.contains(tInvoker)) {
// ignore if is selected, invokersToTry's size is always smaller than reconnectTaskTryCount + 1
invokersToTry.add(tInvoker);
}
RpcContext.getServiceContext().setConsumerUrl(getConsumerUrl());
List<Invoker<T>> needDeleteList = new ArrayList<>();
List<Invoker<T>> invokersToTry = new ArrayList<>();
// 1. pick invokers from invokersToReconnect
// limit max reconnectTaskTryCount, prevent this task hang up all the connectivityExecutor
// for long time
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
if (invokersToReconnect.size() < reconnectTaskTryCount) {
invokersToTry.addAll(invokersToReconnect);
} else {
for (int i = 0; i < reconnectTaskTryCount; i++) {
Invoker<T> tInvoker = invokersToReconnect.get(
ThreadLocalRandom.current().nextInt(invokersToReconnect.size()));
if (!invokersToTry.contains(tInvoker)) {
// ignore if is selected, invokersToTry's size is always smaller than
// reconnectTaskTryCount + 1
invokersToTry.add(tInvoker);
}
}
}
});
// 2. try to check the invoker's status
for (Invoker<T> invoker : invokersToTry) {
AtomicBoolean invokerExist = new AtomicBoolean(false);
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
invokerExist.set(invokers.contains(invoker));
});
// Should not lock here, `invoker.isAvailable` may need some time to check
if (invokerExist.get()) {
if (invoker.isAvailable()) {
needDeleteList.add(invoker);
}
} else {
needDeleteList.add(invoker);
}
}
// 3. recover valid invoker
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
for (Invoker<T> tInvoker : needDeleteList) {
if (invokers.contains(tInvoker)) {
addValidInvoker(tInvoker);
logger.info("Recover service address: " + tInvoker.getUrl()
+ " from invalid list.");
} else {
logger.info(
"The invoker " + tInvoker.getUrl()
+ " has been removed from invokers list. Will remove it in reconnect list.");
}
invokersToReconnect.remove(tInvoker);
}
});
} catch (Throwable t) {
logger.error(
LoggerCodeConstants.INTERNAL_ERROR,
"",
"",
"Error occurred when check connectivity. ",
t);
} finally {
checkConnectivityPermit.release();
}
}
// 4. submit new task if it has more to recover
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
if (!invokersToReconnect.isEmpty()) {
checkConnectivity();
// 2. try to check the invoker's status
for (Invoker<T> invoker : invokersToTry) {
if (invokers.contains(invoker)) {
if (invoker.isAvailable()) {
needDeleteList.add(invoker);
}
});
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(
applicationModel, getSummary(), getDirectoryMeta()));
},
reconnectTaskPeriod,
TimeUnit.MILLISECONDS);
} else {
needDeleteList.add(invoker);
}
}
// 3. recover valid invoker
for (Invoker<T> tInvoker : needDeleteList) {
if (invokers.contains(tInvoker)) {
addValidInvoker(tInvoker);
logger.info("Recover service address: " + tInvoker.getUrl() + " from invalid list.");
}
invokersToReconnect.remove(tInvoker);
}
} finally {
checkConnectivityPermit.release();
}
// 4. submit new task if it has more to recover
if (!invokersToReconnect.isEmpty()) {
checkConnectivity();
}
}, reconnectTaskPeriod, TimeUnit.MILLISECONDS);
}
MetricsEventBus.publish(
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
}
/**
@ -411,20 +363,13 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
* 4. all the invokers disappeared from total invokers should be removed in the disabled invokers list
*/
public void refreshInvoker() {
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
if (invokersInitialized) {
refreshInvokerInternal();
}
});
MetricsEventBus.publish(
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
if (invokersInitialized) {
refreshInvokerInternal();
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
}
protected Map<String, String> getDirectoryMeta() {
return Collections.emptyMap();
}
private void refreshInvokerInternal() {
private synchronized void refreshInvokerInternal() {
BitList<Invoker<T>> copiedInvokers = invokers.clone();
refreshInvokers(copiedInvokers, invokersToReconnect);
refreshInvokers(copiedInvokers, disabledInvokers);
@ -445,47 +390,37 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
@Override
public void addDisabledInvoker(Invoker<T> invoker) {
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
if (invokers.contains(invoker)) {
disabledInvokers.add(invoker);
removeValidInvoker(invoker);
logger.info("Disable service address: " + invoker.getUrl() + ".");
}
});
MetricsEventBus.publish(
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
if (invokers.contains(invoker)) {
disabledInvokers.add(invoker);
removeValidInvoker(invoker);
logger.info("Disable service address: " + invoker.getUrl() + ".");
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
}
@Override
public void recoverDisabledInvoker(Invoker<T> invoker) {
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
if (disabledInvokers.remove(invoker)) {
try {
addValidInvoker(invoker);
logger.info("Recover service address: " + invoker.getUrl() + " from disabled list.");
} catch (Throwable ignore) {
if (disabledInvokers.remove(invoker)) {
try {
addValidInvoker(invoker);
logger.info("Recover service address: " + invoker.getUrl() + " from disabled list.");
} catch (Throwable ignore) {
}
}
});
MetricsEventBus.publish(
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
}
protected final void refreshRouter(BitList<Invoker<T>> newlyInvokers, Runnable switchAction) {
try {
routerChain.setInvokers(newlyInvokers.clone(), switchAction);
} catch (Throwable t) {
logger.error(
LoggerCodeConstants.INTERNAL_ERROR,
"",
"",
"Error occurred when refreshing router chain. " + "The addresses from notification: "
+ newlyInvokers.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(", ")),
t);
logger.error(LoggerCodeConstants.INTERNAL_ERROR, "", "", "Error occurred when refreshing router chain. " +
"The addresses from notification: " +
newlyInvokers.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(", ")), t);
throw t;
}
@ -526,48 +461,34 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
}
protected void setInvokers(BitList<Invoker<T>> invokers) {
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
this.invokers = invokers;
refreshInvokerInternal();
this.invokersInitialized = true;
});
this.invokers = invokers;
refreshInvokerInternal();
this.invokersInitialized = true;
MetricsEventBus.publish(
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
}
protected void destroyInvokers() {
// set empty instead of clearing to support concurrent access.
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
this.invokers = BitList.emptyList();
this.validInvokers = BitList.emptyList();
this.invokersInitialized = false;
});
this.invokers = BitList.emptyList();
this.validInvokers = BitList.emptyList();
this.invokersInitialized = false;
}
private boolean addValidInvoker(Invoker<T> invoker) {
AtomicBoolean result = new AtomicBoolean(false);
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
result.set(this.validInvokers.add(invoker));
});
MetricsEventBus.publish(
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
return result.get();
synchronized (this.validInvokers) {
return this.validInvokers.add(invoker);
}
}
private boolean removeValidInvoker(Invoker<T> invoker) {
AtomicBoolean result = new AtomicBoolean(false);
LockUtils.safeLock(invokerRefreshLock, LockUtils.DEFAULT_TIMEOUT, () -> {
result.set(this.validInvokers.remove(invoker));
});
MetricsEventBus.publish(
RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
return result.get();
synchronized (this.validInvokers) {
return this.validInvokers.remove(invoker);
}
}
protected abstract List<Invoker<T>> doList(
SingleRouterChain<T> singleRouterChain, BitList<Invoker<T>> invokers, Invocation invocation)
throws RpcException;
protected abstract List<Invoker<T>> doList(SingleRouterChain<T> singleRouterChain,
BitList<Invoker<T>> invokers, Invocation invocation) throws RpcException;
protected String joinValidInvokerAddresses() {
BitList<Invoker<T>> validInvokers = getValidInvokers().clone();
@ -575,10 +496,10 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
return "empty";
}
return validInvokers.stream()
.limit(5)
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(","));
.limit(5)
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(","));
}
private Map<MetricsKey, Map<String, Integer>> getSummary() {
@ -592,32 +513,17 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
}
private Map<String, Integer> groupByServiceKey(Collection<Invoker<T>> invokers) {
return Collections.singletonMap(getConsumerUrl().getServiceKey(), invokers.size());
}
@Override
public String toString() {
return "Directory(" + "invokers: "
+ invokers.size() + "["
+ invokers.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.limit(3)
.collect(Collectors.joining(", "))
+ "]" + ", validInvokers: "
+ validInvokers.size() + "["
+ validInvokers.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.limit(3)
.collect(Collectors.joining(", "))
+ "]" + ", invokersToReconnect: "
+ invokersToReconnect.size() + "["
+ invokersToReconnect.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.limit(3)
.collect(Collectors.joining(", "))
+ "]" + ')';
Map<String, Integer> serviceNumMap = new HashMap<>();
for (Invoker<T> invoker : invokers) {
if (invoker.getClass().getSimpleName().contains("Mockito")) {
return serviceNumMap;
}
}
if (invokers.size() > 0) {
serviceNumMap = invokers.stream().filter(invoker -> invoker.getInterface() != null).collect(Collectors.groupingBy(invoker -> invoker.getInterface().getName(), Collectors.reducing(0, e -> 1, Integer::sum)));
}
return serviceNumMap;
}
}

View File

@ -27,20 +27,15 @@ import org.apache.dubbo.rpc.cluster.RouterChain;
import org.apache.dubbo.rpc.cluster.SingleRouterChain;
import org.apache.dubbo.rpc.cluster.router.state.BitList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_SITE_SELECTION;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
/**
* StaticDirectory
*/
public class StaticDirectory<T> extends AbstractDirectory<T> {
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(StaticDirectory.class);
private final Class<T> interfaceClass;
public StaticDirectory(List<Invoker<T>> invokers) {
this(null, invokers, null);
@ -55,22 +50,16 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
}
public StaticDirectory(URL url, List<Invoker<T>> invokers, RouterChain<T> routerChain) {
super(
url == null && CollectionUtils.isNotEmpty(invokers)
? invokers.get(0).getUrl()
: url,
routerChain,
false);
super(url == null && CollectionUtils.isNotEmpty(invokers) ? invokers.get(0).getUrl() : url, routerChain, false);
if (CollectionUtils.isEmpty(invokers)) {
throw new IllegalArgumentException("invokers == null");
}
this.setInvokers(new BitList<>(invokers));
this.interfaceClass = invokers.get(0).getInterface();
}
@Override
public Class<T> getInterface() {
return interfaceClass;
return getInvokers().get(0).getInterface();
}
@Override
@ -106,45 +95,32 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
public void buildRouterChain() {
RouterChain<T> routerChain = RouterChain.buildChain(getInterface(), getUrl());
routerChain.setInvokers(getInvokers(), () -> {});
routerChain.setInvokers(getInvokers(), () -> {
});
this.setRouterChain(routerChain);
}
public void notify(List<Invoker<T>> invokers) {
BitList<Invoker<T>> bitList = new BitList<>(invokers);
if (routerChain != null) {
refreshRouter(bitList.clone(), () -> this.setInvokers(bitList));
refreshRouter(bitList.clone(), () -> this.setInvokers(bitList));
} else {
this.setInvokers(bitList);
}
}
@Override
protected List<Invoker<T>> doList(
SingleRouterChain<T> singleRouterChain, BitList<Invoker<T>> invokers, Invocation invocation)
throws RpcException {
protected List<Invoker<T>> doList(SingleRouterChain<T> singleRouterChain, BitList<Invoker<T>> invokers, Invocation invocation) throws RpcException {
if (singleRouterChain != null) {
try {
List<Invoker<T>> finalInvokers = singleRouterChain.route(getConsumerUrl(), invokers, invocation);
return finalInvokers == null ? BitList.emptyList() : finalInvokers;
} catch (Throwable t) {
logger.error(
CLUSTER_FAILED_SITE_SELECTION,
"Failed to execute router",
"",
"Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(),
t);
logger.error(CLUSTER_FAILED_SITE_SELECTION, "Failed to execute router", "", "Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
return BitList.emptyList();
}
}
return invokers;
}
@Override
protected Map<String, String> getDirectoryMeta() {
Map<String, String> metas = new HashMap<>();
metas.put(REGISTRY_KEY, "static");
metas.put(REGISTER_MODE_KEY, "static");
return metas;
}
}

View File

@ -21,4 +21,5 @@ import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.rpc.BaseFilter;
@SPI(scope = ExtensionScope.MODULE)
public interface ClusterFilter extends BaseFilter {}
public interface ClusterFilter extends BaseFilter {
}

View File

@ -47,14 +47,12 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
List<ModuleModel> moduleModels = getModuleModelsFromUrl(url);
List<Filter> filters;
if (moduleModels != null && moduleModels.size() == 1) {
filters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModels.get(0))
.getActivateExtension(url, key, group);
filters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModels.get(0)).getActivateExtension(url, key, group);
} else if (moduleModels != null && moduleModels.size() > 1) {
filters = new ArrayList<>();
List<ExtensionDirector> directors = new ArrayList<>();
for (ModuleModel moduleModel : moduleModels) {
List<Filter> tempFilters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModel)
.getActivateExtension(url, key, group);
List<Filter> tempFilters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModel).getActivateExtension(url, key, group);
filters.addAll(tempFilters);
directors.add(moduleModel.getExtensionDirector());
}
@ -64,6 +62,7 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
filters = ScopeModelUtil.getExtensionLoader(Filter.class, null).getActivateExtension(url, key, group);
}
if (!CollectionUtils.isEmpty(filters)) {
for (int i = filters.size() - 1; i >= 0; i--) {
final Filter filter = filters.get(i);
@ -80,29 +79,25 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
* build consumer cluster filter chain
*/
@Override
public <T> ClusterInvoker<T> buildClusterInvokerChain(
final ClusterInvoker<T> originalInvoker, String key, String group) {
public <T> ClusterInvoker<T> buildClusterInvokerChain(final ClusterInvoker<T> originalInvoker, String key, String group) {
ClusterInvoker<T> last = originalInvoker;
URL url = originalInvoker.getUrl();
List<ModuleModel> moduleModels = getModuleModelsFromUrl(url);
List<ClusterFilter> filters;
if (moduleModels != null && moduleModels.size() == 1) {
filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModels.get(0))
.getActivateExtension(url, key, group);
filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModels.get(0)).getActivateExtension(url, key, group);
} else if (moduleModels != null && moduleModels.size() > 1) {
filters = new ArrayList<>();
List<ExtensionDirector> directors = new ArrayList<>();
for (ModuleModel moduleModel : moduleModels) {
List<ClusterFilter> tempFilters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModel)
.getActivateExtension(url, key, group);
List<ClusterFilter> tempFilters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModel).getActivateExtension(url, key, group);
filters.addAll(tempFilters);
directors.add(moduleModel.getExtensionDirector());
}
filters = sortingAndDeduplication(filters, directors);
} else {
filters =
ScopeModelUtil.getExtensionLoader(ClusterFilter.class, null).getActivateExtension(url, key, group);
filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, null).getActivateExtension(url, key, group);
}
if (!CollectionUtils.isEmpty(filters)) {
@ -146,4 +141,5 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
}
return moduleModels;
}
}

View File

@ -21,7 +21,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.rpc.AsyncRpcResult;
import org.apache.dubbo.rpc.BaseFilter;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
@ -37,7 +36,6 @@ import java.util.List;
import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_EXECUTE_FILTER_EXCEPTION;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR;
import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
@SPI(value = "default", scope = APPLICATION)
@ -92,8 +90,7 @@ public interface FilterChainBuilder {
public Result invoke(Invocation invocation) throws RpcException {
Result asyncResult;
try {
InvocationProfilerUtils.enterDetailProfiler(
invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
asyncResult = filter.invoke(nextNode, invocation);
} catch (Exception e) {
InvocationProfilerUtils.releaseDetailProfiler(invocation);
@ -160,11 +157,12 @@ public interface FilterChainBuilder {
* @param <TYPE>
*/
class ClusterFilterChainNode<T, TYPE extends ClusterInvoker<T>, FILTER extends BaseFilter>
extends FilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
extends FilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
public ClusterFilterChainNode(TYPE originalInvoker, Invoker<T> nextNode, FILTER filter) {
super(originalInvoker, nextNode, filter);
}
@Override
public URL getRegistryUrl() {
return getOriginalInvoker().getRegistryUrl();
@ -182,8 +180,7 @@ public interface FilterChainBuilder {
}
class CallbackRegistrationInvoker<T, FILTER extends BaseFilter> implements Invoker<T> {
private static final ErrorTypeAwareLogger LOGGER =
LoggerFactory.getErrorTypeAwareLogger(CallbackRegistrationInvoker.class);
private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(CallbackRegistrationInvoker.class);
final Invoker<T> filterInvoker;
final List<FILTER> filters;
@ -224,20 +221,9 @@ public interface FilterChainBuilder {
}
}
} catch (RuntimeException runtimeException) {
LOGGER.error(
CLUSTER_EXECUTE_FILTER_EXCEPTION,
"the custom filter is abnormal",
"",
String.format(
"Exception occurred while executing the %s filter named %s.",
i, filter.getClass().getSimpleName()));
LOGGER.error(CLUSTER_EXECUTE_FILTER_EXCEPTION, "the custom filter is abnormal", "", String.format("Exception occurred while executing the %s filter named %s.", i, filter.getClass().getSimpleName()));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format(
"Whole filter list is: %s",
filters.stream()
.map(tmpFilter ->
tmpFilter.getClass().getSimpleName())
.collect(Collectors.toList())));
LOGGER.debug(String.format("Whole filter list is: %s", filters.stream().map(tmpFilter -> tmpFilter.getClass().getSimpleName()).collect(Collectors.toList())));
}
filterRuntimeException = runtimeException;
t = runtimeException;
@ -276,12 +262,11 @@ public interface FilterChainBuilder {
}
}
class ClusterCallbackRegistrationInvoker<T, FILTER extends BaseFilter>
extends CallbackRegistrationInvoker<T, FILTER> implements ClusterInvoker<T> {
class ClusterCallbackRegistrationInvoker<T, FILTER extends BaseFilter> extends CallbackRegistrationInvoker<T, FILTER>
implements ClusterInvoker<T> {
private ClusterInvoker<T> originalInvoker;
public ClusterCallbackRegistrationInvoker(
ClusterInvoker<T> originalInvoker, Invoker<T> filterInvoker, List<FILTER> filters) {
public ClusterCallbackRegistrationInvoker(ClusterInvoker<T> originalInvoker, Invoker<T> filterInvoker, List<FILTER> filters) {
super(filterInvoker, filters);
this.originalInvoker = originalInvoker;
}
@ -306,11 +291,9 @@ public interface FilterChainBuilder {
}
}
@Experimental(
"Works for the same purpose as FilterChainNode, replace FilterChainNode with this one when proved stable enough")
@Experimental("Works for the same purpose as FilterChainNode, replace FilterChainNode with this one when proved stable enough")
class CopyOfFilterChainNode<T, TYPE extends Invoker<T>, FILTER extends BaseFilter> implements Invoker<T> {
private static final ErrorTypeAwareLogger LOGGER =
LoggerFactory.getErrorTypeAwareLogger(CopyOfFilterChainNode.class);
TYPE originalInvoker;
Invoker<T> nextNode;
FILTER filter;
@ -344,17 +327,8 @@ public interface FilterChainBuilder {
public Result invoke(Invocation invocation) throws RpcException {
Result asyncResult;
try {
InvocationProfilerUtils.enterDetailProfiler(
invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
asyncResult = filter.invoke(nextNode, invocation);
if (!(asyncResult instanceof AsyncRpcResult)) {
String msg =
"The result of filter invocation must be AsyncRpcResult. (If you want to recreate a result, please use AsyncRpcResult.newDefaultAsyncResult.) "
+ "Filter class: " + filter.getClass().getName() + ". Result class: "
+ asyncResult.getClass().getName() + ".";
LOGGER.error(INTERNAL_ERROR, "", "", msg);
throw new RpcException(msg);
}
} catch (Exception e) {
InvocationProfilerUtils.releaseDetailProfiler(invocation);
if (filter instanceof ListenableFilter) {
@ -389,14 +363,14 @@ public interface FilterChainBuilder {
}
}
@Experimental(
"Works for the same purpose as ClusterFilterChainNode, replace ClusterFilterChainNode with this one when proved stable enough")
@Experimental("Works for the same purpose as ClusterFilterChainNode, replace ClusterFilterChainNode with this one when proved stable enough")
class CopyOfClusterFilterChainNode<T, TYPE extends ClusterInvoker<T>, FILTER extends BaseFilter>
extends CopyOfFilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
extends CopyOfFilterChainNode<T, TYPE, FILTER> implements ClusterInvoker<T> {
public CopyOfClusterFilterChainNode(TYPE originalInvoker, Invoker<T> nextNode, FILTER filter) {
super(originalInvoker, nextNode, filter);
}
@Override
public URL getRegistryUrl() {
return getOriginalInvoker().getRegistryUrl();

View File

@ -62,8 +62,7 @@ public class ProtocolFilterWrapper implements Protocol {
}
private <T> FilterChainBuilder getFilterChainBuilder(URL url) {
return ScopeModelUtil.getExtensionLoader(FilterChainBuilder.class, url.getScopeModel())
.getDefaultExtension();
return ScopeModelUtil.getExtensionLoader(FilterChainBuilder.class, url.getScopeModel()).getDefaultExtension();
}
@Override
@ -84,4 +83,5 @@ public class ProtocolFilterWrapper implements Protocol {
public List<ProtocolServer> getServers() {
return protocol.getServers();
}
}

View File

@ -35,8 +35,8 @@ public class ConsumerClassLoaderFilter implements ClusterFilter {
ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader();
try {
Optional.ofNullable(invocation.getServiceModel())
.map(ServiceModel::getClassLoader)
.ifPresent(Thread.currentThread()::setContextClassLoader);
.map(ServiceModel::getClassLoader)
.ifPresent(Thread.currentThread()::setContextClassLoader);
return invoker.invoke(invocation);
} finally {
Thread.currentThread().setContextClassLoader(originClassLoader);

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.rpc.cluster.filter.support;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.rpc.AsyncRpcResult;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
@ -55,68 +56,69 @@ public class ConsumerContextFilter implements ClusterFilter, ClusterFilter.Liste
private Set<PenetrateAttachmentSelector> supportedSelectors;
public ConsumerContextFilter(ApplicationModel applicationModel) {
ExtensionLoader<PenetrateAttachmentSelector> selectorExtensionLoader =
applicationModel.getExtensionLoader(PenetrateAttachmentSelector.class);
ExtensionLoader<PenetrateAttachmentSelector> selectorExtensionLoader = applicationModel.getExtensionLoader(PenetrateAttachmentSelector.class);
supportedSelectors = selectorExtensionLoader.getSupportedExtensionInstances();
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
RpcContext.getServiceContext().setInvoker(invoker).setInvocation(invocation);
RpcContext.RestoreServiceContext originServiceContext = RpcContext.storeServiceContext();
try {
RpcContext.getServiceContext()
.setInvoker(invoker)
.setInvocation(invocation)
.setLocalAddress(NetUtils.getLocalHost(), 0);
RpcContext context = RpcContext.getClientAttachment();
context.setAttachment(REMOTE_APPLICATION_KEY, invoker.getUrl().getApplication());
if (invocation instanceof RpcInvocation) {
((RpcInvocation) invocation).setInvoker(invoker);
}
RpcContext context = RpcContext.getClientAttachment();
context.setAttachment(REMOTE_APPLICATION_KEY, invoker.getUrl().getApplication());
if (invocation instanceof RpcInvocation) {
((RpcInvocation) invocation).setInvoker(invoker);
}
if (CollectionUtils.isNotEmpty(supportedSelectors)) {
for (PenetrateAttachmentSelector supportedSelector : supportedSelectors) {
Map<String, Object> selected = supportedSelector.select(
invocation, RpcContext.getClientAttachment(), RpcContext.getServerAttachment());
if (CollectionUtils.isNotEmptyMap(selected)) {
((RpcInvocation) invocation).addObjectAttachments(selected);
if (CollectionUtils.isNotEmpty(supportedSelectors)) {
for (PenetrateAttachmentSelector supportedSelector : supportedSelectors) {
Map<String, Object> selected = supportedSelector.select(invocation, RpcContext.getClientAttachment(), RpcContext.getServerAttachment());
if (CollectionUtils.isNotEmptyMap(selected)) {
((RpcInvocation) invocation).addObjectAttachments(selected);
}
}
} else {
((RpcInvocation) invocation).addObjectAttachments(RpcContext.getServerAttachment().getObjectAttachments());
}
Map<String, Object> contextAttachments = RpcContext.getClientAttachment().getObjectAttachments();
if (CollectionUtils.isNotEmptyMap(contextAttachments)) {
/**
* invocation.addAttachmentsIfAbsent(context){@link RpcInvocation#addAttachmentsIfAbsent(Map)}should not be used here,
* because the {@link RpcContext#setAttachment(String, String)} is passed in the Filter when the call is triggered
* by the built-in retry mechanism of the Dubbo. The attachment to update RpcContext will no longer work, which is
* a mistake in most cases (for example, through Filter to RpcContext output traceId and spanId and other information).
*/
((RpcInvocation) invocation).addObjectAttachments(contextAttachments);
}
// pass default timeout set by end user (ReferenceConfig)
Object countDown = RpcContext.getServerAttachment().getObjectAttachment(TIME_COUNTDOWN_KEY);
if (countDown != null) {
String methodName = RpcUtils.getMethodName(invocation);
// When the client has enabled the timeout-countdown function,
// the subsequent calls launched by the Server side will be enabled by default,
// and support to turn off the function on a node to get rid of the timeout control.
if (invoker.getUrl().getMethodParameter(methodName, ENABLE_TIMEOUT_COUNTDOWN_KEY, true)) {
context.setObjectAttachment(TIME_COUNTDOWN_KEY, countDown);
TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countDown;
if (timeoutCountDown.isExpired()) {
return AsyncRpcResult.newDefaultAsyncResult(new RpcException(RpcException.TIMEOUT_TERMINATE,
"No time left for making the following call: " + invocation.getServiceName() + "."
+ invocation.getMethodName() + ", terminate directly."), invocation);
}
}
}
} else {
((RpcInvocation) invocation)
.addObjectAttachments(RpcContext.getServerAttachment().getObjectAttachments());
RpcContext.removeClientResponseContext();
return invoker.invoke(invocation);
} finally {
RpcContext.restoreServiceContext(originServiceContext);
}
Map<String, Object> contextAttachments =
RpcContext.getClientAttachment().getObjectAttachments();
if (CollectionUtils.isNotEmptyMap(contextAttachments)) {
/**
* invocation.addAttachmentsIfAbsent(context){@link RpcInvocation#addAttachmentsIfAbsent(Map)}should not be used here,
* because the {@link RpcContext#setAttachment(String, String)} is passed in the Filter when the call is triggered
* by the built-in retry mechanism of the Dubbo. The attachment to update RpcContext will no longer work, which is
* a mistake in most cases (for example, through Filter to RpcContext output traceId and spanId and other information).
*/
((RpcInvocation) invocation).addObjectAttachments(contextAttachments);
}
// pass default timeout set by end user (ReferenceConfig)
Object countDown = RpcContext.getServerAttachment().getObjectAttachment(TIME_COUNTDOWN_KEY);
if (countDown != null) {
String methodName = RpcUtils.getMethodName(invocation);
// When the client has enabled the timeout-countdown function,
// the subsequent calls launched by the Server side will be enabled by default,
// and support to turn off the function on a node to get rid of the timeout control.
if (invoker.getUrl().getMethodParameter(methodName, ENABLE_TIMEOUT_COUNTDOWN_KEY, true)) {
context.setObjectAttachment(TIME_COUNTDOWN_KEY, countDown);
TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countDown;
if (timeoutCountDown.isExpired()) {
return AsyncRpcResult.newDefaultAsyncResult(
new RpcException(
RpcException.TIMEOUT_TERMINATE,
"No time left for making the following call: " + invocation.getServiceName() + "."
+ RpcUtils.getMethodName(invocation) + ", terminate directly."),
invocation);
}
}
}
RpcContext.removeClientResponseContext();
return invoker.invoke(invocation);
}
@Override
@ -138,15 +140,14 @@ public class ConsumerContextFilter implements ClusterFilter, ClusterFilter.Liste
RpcInvocation rpcInvocation = (RpcInvocation) invocation;
if (rpcInvocation.getInvokeMode() != null) {
// clear service context if not in sync mode
if (rpcInvocation.getInvokeMode() == InvokeMode.ASYNC
|| rpcInvocation.getInvokeMode() == InvokeMode.FUTURE) {
if (rpcInvocation.getInvokeMode() == InvokeMode.ASYNC || rpcInvocation.getInvokeMode() == InvokeMode.FUTURE) {
RpcContext.removeServiceContext();
}
}
}
// server context must not be removed because user might use it on callback.
// So the clear of is delayed til the start of the next rpc call, see RpcContext.removeServerContext(); in
// invoke() above
// So the clear of is delayed til the start of the next rpc call, see RpcContext.removeServerContext(); in invoke() above
// RpcContext.removeServerContext();
}
}

View File

@ -14,14 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.filter.support;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
import org.apache.dubbo.metrics.event.MetricsDispatcher;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.event.RequestEvent;
import org.apache.dubbo.metrics.model.MethodMetric;
import org.apache.dubbo.metrics.event.RequestBeforeEvent;
import org.apache.dubbo.rpc.BaseFilter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
@ -32,24 +32,17 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
@Activate(group = CONSUMER, onClass = "org.apache.dubbo.metrics.collector.DefaultMetricsCollector")
public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {
private ApplicationModel applicationModel;
private DefaultMetricsCollector collector;
private String appName;
private MetricsDispatcher metricsDispatcher;
private boolean serviceLevel;
@Override
public void setApplicationModel(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
this.collector = applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
this.appName = applicationModel.tryGetApplicationName();
this.metricsDispatcher = applicationModel.getBeanFactory().getBean(MetricsDispatcher.class);
this.serviceLevel = MethodMetric.isServiceLevel(applicationModel);
}
@Override
@ -74,15 +67,9 @@ public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener,
if (t instanceof RpcException) {
RpcException e = (RpcException) t;
if (e.isForbidden()) {
MetricsEventBus.publish(RequestEvent.toRequestErrorEvent(
applicationModel,
appName,
metricsDispatcher,
invocation,
CONSUMER_SIDE,
e.getCode(),
serviceLevel));
MetricsEventBus.publish(RequestBeforeEvent.toEvent(applicationModel, invocation));
}
}
}
}

View File

@ -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.cluster.filter.support;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.metrics.filter.MetricsFilter;
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 static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
@Activate(
group = {CONSUMER},
order = Integer.MIN_VALUE + 100)
public class MetricsConsumerFilter extends MetricsFilter implements ClusterFilter, BaseFilter.Listener {
public MetricsConsumerFilter() {}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
return super.invoke(invoker, invocation, false);
}
@Override
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
super.onResponse(appResponse, invoker, invocation, false);
}
@Override
public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
super.onError(t, invoker, invocation, false);
}
}

View File

@ -50,8 +50,7 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
applicationModel.getApplicationConfigManager().getTracing().ifPresent(cfg -> {
if (Boolean.TRUE.equals(cfg.getEnabled())) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
clientObservationConvention =
applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class);
clientObservationConvention = applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class);
}
});
}
@ -65,8 +64,7 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
final Observation observation = DubboObservationDocumentation.CLIENT.observation(
this.clientObservationConvention,
DefaultDubboClientObservationConvention.getInstance(),
() -> senderContext,
observationRegistry);
() -> senderContext, observationRegistry);
invocation.put(Observation.class, observation.start());
return observation.scoped(() -> invoker.invoke(invocation));
}

View File

@ -54,6 +54,7 @@ public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleReposi
}
private DynamicConfiguration getDynamicConfiguration() {
return moduleModel.modelEnvironment().getDynamicConfiguration().orElse(null);
return moduleModel.getModelEnvironment().getDynamicConfiguration().orElse(null);
}
}

View File

@ -36,6 +36,7 @@ public interface GovernanceRuleRepository {
addListener(key, DEFAULT_GROUP, listener);
}
/**
* {@link #removeListener(String, String, ConfigurationListener)}
*

View File

@ -22,7 +22,6 @@ import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.support.RpcUtils;
import java.util.List;
@ -47,7 +46,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
* @return weight which takes warmup into account
*/
static int calculateWarmupWeight(int uptime, int warmup, int weight) {
int ww = (int) (uptime / ((float) warmup / weight));
int ww = (int) ( uptime / ((float) warmup / weight));
return ww < 1 ? 1 : (Math.min(ww, weight));
}
@ -64,6 +63,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);
/**
* Get the weight of the invoker's invocation which takes warmup time into account
* if the uptime is within the warmup time, the weight will be reduce proportionally
@ -83,7 +83,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
if (REGISTRY_SERVICE_REFERENCE_PATH.equals(url.getServiceInterface())) {
weight = url.getParameter(WEIGHT_KEY, DEFAULT_WEIGHT);
} else {
weight = url.getMethodParameter(RpcUtils.getMethodName(invocation), WEIGHT_KEY, DEFAULT_WEIGHT);
weight = url.getMethodParameter(invocation.getMethodName(), WEIGHT_KEY, DEFAULT_WEIGHT);
if (weight > 0) {
long timestamp = invoker.getUrl().getParameter(TIMESTAMP_KEY, 0L);
if (timestamp > 0L) {
@ -93,7 +93,7 @@ public abstract class AbstractLoadBalance implements LoadBalance {
}
int warmup = invoker.getUrl().getParameter(WARMUP_KEY, DEFAULT_WARMUP);
if (uptime > 0 && uptime < warmup) {
weight = calculateWarmupWeight((int) uptime, warmup, weight);
weight = calculateWarmupWeight((int)uptime, warmup, weight);
}
}
}

View File

@ -41,36 +41,36 @@ public class AdaptiveLoadBalance extends AbstractLoadBalance {
public static final String NAME = "adaptive";
// default key
//default key
private String attachmentKey = "mem,load";
private final AdaptiveMetrics adaptiveMetrics;
public AdaptiveLoadBalance(ApplicationModel scopeModel) {
public AdaptiveLoadBalance(ApplicationModel scopeModel){
adaptiveMetrics = scopeModel.getBeanFactory().getBean(AdaptiveMetrics.class);
}
@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
Invoker<T> invoker = selectByP2C(invokers, invocation);
invocation.setAttachment(Constants.ADAPTIVE_LOADBALANCE_ATTACHMENT_KEY, attachmentKey);
Invoker<T> invoker = selectByP2C(invokers,invocation);
invocation.setAttachment(Constants.ADAPTIVE_LOADBALANCE_ATTACHMENT_KEY,attachmentKey);
long startTime = System.currentTimeMillis();
invocation.getAttributes().put(Constants.ADAPTIVE_LOADBALANCE_START_TIME, startTime);
invocation.getAttributes().put(LOADBALANCE_KEY, LoadbalanceRules.ADAPTIVE);
adaptiveMetrics.addConsumerReq(getServiceKey(invoker, invocation));
adaptiveMetrics.setPickTime(getServiceKey(invoker, invocation), startTime);
invocation.getAttributes().put(Constants.ADAPTIVE_LOADBALANCE_START_TIME,startTime);
invocation.getAttributes().put(LOADBALANCE_KEY,LoadbalanceRules.ADAPTIVE);
adaptiveMetrics.addConsumerReq(getServiceKey(invoker,invocation));
adaptiveMetrics.setPickTime(getServiceKey(invoker,invocation),startTime);
return invoker;
}
private <T> Invoker<T> selectByP2C(List<Invoker<T>> invokers, Invocation invocation) {
private <T> Invoker<T> selectByP2C(List<Invoker<T>> invokers, Invocation invocation){
int length = invokers.size();
if (length == 1) {
if(length == 1) {
return invokers.get(0);
}
if (length == 2) {
return chooseLowLoadInvoker(invokers.get(0), invokers.get(1), invocation);
if(length == 2) {
return chooseLowLoadInvoker(invokers.get(0),invokers.get(1),invocation);
}
int pos1 = ThreadLocalRandom.current().nextInt(length);
@ -79,22 +79,22 @@ public class AdaptiveLoadBalance extends AbstractLoadBalance {
pos2 = pos2 + 1;
}
return chooseLowLoadInvoker(invokers.get(pos1), invokers.get(pos2), invocation);
return chooseLowLoadInvoker(invokers.get(pos1),invokers.get(pos2),invocation);
}
private String getServiceKey(Invoker<?> invoker, Invocation invocation) {
private String getServiceKey(Invoker<?> invoker,Invocation invocation){
String key = (String) invocation.getAttributes().get(invoker);
if (StringUtils.isNotEmpty(key)) {
if (StringUtils.isNotEmpty(key)){
return key;
}
key = buildServiceKey(invoker, invocation);
invocation.getAttributes().put(invoker, key);
key = buildServiceKey(invoker,invocation);
invocation.getAttributes().put(invoker,key);
return key;
}
private String buildServiceKey(Invoker<?> invoker, Invocation invocation) {
private String buildServiceKey(Invoker<?> invoker,Invocation invocation){
URL url = invoker.getUrl();
StringBuilder sb = new StringBuilder(128);
sb.append(url.getAddress()).append(":").append(invocation.getProtocolServiceKey());
@ -104,19 +104,16 @@ public class AdaptiveLoadBalance extends AbstractLoadBalance {
private int getTimeout(Invoker<?> invoker, Invocation invocation) {
URL url = invoker.getUrl();
String methodName = RpcUtils.getMethodName(invocation);
return (int)
RpcUtils.getTimeout(url, methodName, RpcContext.getClientAttachment(), invocation, DEFAULT_TIMEOUT);
return (int) RpcUtils.getTimeout(url,methodName, RpcContext.getClientAttachment(),invocation, DEFAULT_TIMEOUT);
}
private <T> Invoker<T> chooseLowLoadInvoker(Invoker<T> invoker1, Invoker<T> invoker2, Invocation invocation) {
private <T> Invoker<T> chooseLowLoadInvoker(Invoker<T> invoker1,Invoker<T> invoker2,Invocation invocation){
int weight1 = getWeight(invoker1, invocation);
int weight2 = getWeight(invoker2, invocation);
int timeout1 = getTimeout(invoker1, invocation);
int timeout1 = getTimeout(invoker2, invocation);
int timeout2 = getTimeout(invoker2, invocation);
long load1 = Double.doubleToLongBits(
adaptiveMetrics.getLoad(getServiceKey(invoker1, invocation), weight1, timeout1));
long load2 = Double.doubleToLongBits(
adaptiveMetrics.getLoad(getServiceKey(invoker2, invocation), weight2, timeout2));
long load1 = Double.doubleToLongBits(adaptiveMetrics.getLoad(getServiceKey(invoker1,invocation),weight1,timeout1 ));
long load2 = Double.doubleToLongBits(adaptiveMetrics.getLoad(getServiceKey(invoker2,invocation),weight2,timeout2 ));
if (load1 == load2) {
// The sum of weights
@ -132,4 +129,5 @@ public class AdaptiveLoadBalance extends AbstractLoadBalance {
}
return load1 > load2 ? invoker2 : invoker1;
}
}

View File

@ -28,6 +28,7 @@ import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
/**
@ -46,7 +47,7 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
*/
public static final String HASH_ARGUMENTS = "hash.arguments";
private final ConcurrentMap<String, ConsistentHashSelector<?>> selectors = new ConcurrentHashMap<>();
private final ConcurrentMap<String, ConsistentHashSelector<?>> selectors = new ConcurrentHashMap<String, ConsistentHashSelector<?>>();
@SuppressWarnings("unchecked")
@Override
@ -74,7 +75,7 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
private final int[] argumentIndex;
ConsistentHashSelector(List<Invoker<T>> invokers, String methodName, int identityHashCode) {
this.virtualInvokers = new TreeMap<>();
this.virtualInvokers = new TreeMap<Long, Invoker<T>>();
this.identityHashCode = identityHashCode;
URL url = invokers.get(0).getUrl();
this.replicaNumber = url.getMethodParameter(methodName, HASH_NODES, 160);
@ -96,12 +97,17 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
}
public Invoker<T> select(Invocation invocation) {
String key = toKey(RpcUtils.getArguments(invocation));
boolean isGeneric = invocation.getMethodName().equals($INVOKE);
String key = toKey(invocation.getArguments(),isGeneric);
byte[] digest = Bytes.getMD5(key);
return selectForKey(hash(digest, 0));
}
private String toKey(Object[] args, boolean isGeneric) {
return isGeneric ? toKey((Object[]) args[1]) : toKey(args);
}
private String toKey(Object[] args) {
StringBuilder buf = new StringBuilder();
for (int i : argumentIndex) {
@ -122,10 +128,11 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
private long hash(byte[] digest, int number) {
return (((long) (digest[3 + number * 4] & 0xFF) << 24)
| ((long) (digest[2 + number * 4] & 0xFF) << 16)
| ((long) (digest[1 + number * 4] & 0xFF) << 8)
| (digest[number * 4] & 0xFF))
| ((long) (digest[2 + number * 4] & 0xFF) << 16)
| ((long) (digest[1 + number * 4] & 0xFF) << 8)
| (digest[number * 4] & 0xFF))
& 0xFFFFFFFFL;
}
}
}

View File

@ -20,7 +20,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcStatus;
import org.apache.dubbo.rpc.support.RpcUtils;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
@ -56,18 +55,17 @@ public class LeastActiveLoadBalance extends AbstractLoadBalance {
// Every least active invoker has the same weight value?
boolean sameWeight = true;
// Filter out all the least active invokers
for (int i = 0; i < length; i++) {
Invoker<T> invoker = invokers.get(i);
// Get the active number of the invoker
int active = RpcStatus.getStatus(invoker.getUrl(), RpcUtils.getMethodName(invocation))
.getActive();
int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive();
// Get the weight of the invoker's configuration. The default value is 100.
int afterWarmup = getWeight(invoker, invocation);
// save for later use
weights[i] = afterWarmup;
// If it is the first invoker or the active number of the invoker is less than the current least active
// number
// If it is the first invoker or the active number of the invoker is less than the current least active number
if (leastActive == -1 || active < leastActive) {
// Reset the active number of the current invoker to the least active number
leastActive = active;
@ -99,7 +97,7 @@ public class LeastActiveLoadBalance extends AbstractLoadBalance {
return invokers.get(leastIndexes[0]);
}
if (!sameWeight && totalWeight > 0) {
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on
// totalWeight.
int offsetWeight = ThreadLocalRandom.current().nextInt(totalWeight);
// Return a invoker based on the random value.

View File

@ -21,7 +21,6 @@ import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
import org.apache.dubbo.rpc.support.RpcUtils;
import java.util.Arrays;
import java.util.List;
@ -78,8 +77,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.
// 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 an invoker based on the random value.
if (length <= 4) {
@ -93,7 +91,7 @@ public class RandomLoadBalance extends AbstractLoadBalance {
if (i < 0) {
i = -i - 1;
} else {
while (weights[i + 1] == offset) {
while (weights[i+1] == offset) {
i++;
}
i++;
@ -117,7 +115,7 @@ public class RandomLoadBalance extends AbstractLoadBalance {
String weight = invokerUrl.getParameter(WEIGHT_KEY);
return StringUtils.isNotEmpty(weight);
} else {
String weight = invokerUrl.getMethodParameter(RpcUtils.getMethodName(invocation), WEIGHT_KEY);
String weight = invokerUrl.getMethodParameter(invocation.getMethodName(), WEIGHT_KEY);
if (StringUtils.isNotEmpty(weight)) {
return true;
} else {

View File

@ -20,7 +20,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.support.RpcUtils;
import java.util.Collection;
import java.util.List;
@ -37,8 +36,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
private static final int RECYCLE_PERIOD = 60000;
private final ConcurrentMap<String, ConcurrentMap<String, WeightedRoundRobin>> methodWeightMap =
new ConcurrentHashMap<>();
private final ConcurrentMap<String, ConcurrentMap<String, WeightedRoundRobin>> methodWeightMap = new ConcurrentHashMap<>();
protected static class WeightedRoundRobin {
private int weight;
@ -81,7 +79,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
* @return
*/
protected <T> Collection<String> getInvokerAddrList(List<Invoker<T>> invokers, Invocation invocation) {
String key = invokers.get(0).getUrl().getServiceKey() + "." + RpcUtils.getMethodName(invocation);
String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName();
Map<String, WeightedRoundRobin> map = methodWeightMap.get(key);
if (map != null) {
return map.keySet();
@ -91,9 +89,8 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
String key = invokers.get(0).getUrl().getServiceKey() + "." + RpcUtils.getMethodName(invocation);
ConcurrentMap<String, WeightedRoundRobin> map =
ConcurrentHashMapUtils.computeIfAbsent(methodWeightMap, key, k -> new ConcurrentHashMap<>());
String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName();
ConcurrentMap<String, WeightedRoundRobin> map = ConcurrentHashMapUtils.computeIfAbsent(methodWeightMap, key, k -> new ConcurrentHashMap<>());
int totalWeight = 0;
long maxCurrent = Long.MIN_VALUE;
long now = System.currentTimeMillis();
@ -109,7 +106,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
});
if (weight != weightedRoundRobin.getWeight()) {
// weight changed
//weight changed
weightedRoundRobin.setWeight(weight);
}
long cur = weightedRoundRobin.increaseCurrent();
@ -131,4 +128,5 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
// should not happen here
return invokers.get(0);
}
}

View File

@ -25,7 +25,6 @@ import org.apache.dubbo.rpc.RpcStatus;
import org.apache.dubbo.rpc.cluster.Constants;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
import org.apache.dubbo.rpc.support.RpcUtils;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@ -59,15 +58,9 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
@Override
public void setApplicationModel(ApplicationModel applicationModel) {
slidePeriod = applicationModel
.modelEnvironment()
.getConfiguration()
.getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
executorService = applicationModel
.getFrameworkModel()
.getBeanFactory()
.getBean(FrameworkExecutorRepository.class)
.getSharedExecutor();
slidePeriod = applicationModel.getModelEnvironment().getConfiguration().getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
executorService = applicationModel.getFrameworkModel().getBeanFactory()
.getBean(FrameworkExecutorRepository.class).getSharedExecutor();
}
protected static class SlideWindowData {
@ -123,12 +116,10 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
// Filter out all the shortest response invokers
for (int i = 0; i < length; i++) {
Invoker<T> invoker = invokers.get(i);
RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), RpcUtils.getMethodName(invocation));
SlideWindowData slideWindowData =
ConcurrentHashMapUtils.computeIfAbsent(methodMap, rpcStatus, SlideWindowData::new);
RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName());
SlideWindowData slideWindowData = ConcurrentHashMapUtils.computeIfAbsent(methodMap, rpcStatus, SlideWindowData::new);
// Calculate the estimated response time from the product of active connections and succeeded average
// elapsed time.
// Calculate the estimated response time from the product of active connections and succeeded average elapsed time.
long estimateResponse = slideWindowData.getEstimateResponse();
int afterWarmup = getWeight(invoker, invocation);
weights[i] = afterWarmup;
@ -143,15 +134,16 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
} else if (estimateResponse == shortestResponse) {
shortestIndexes[shortestCount++] = i;
totalWeight += afterWarmup;
if (sameWeight && i > 0 && afterWarmup != firstWeight) {
if (sameWeight && i > 0
&& afterWarmup != firstWeight) {
sameWeight = false;
}
}
}
if (System.currentTimeMillis() - lastUpdateTime > slidePeriod
&& onResetSlideWindow.compareAndSet(false, true)) {
// reset slideWindowData in async way
&& onResetSlideWindow.compareAndSet(false, true)) {
//reset slideWindowData in async way
executorService.execute(() -> {
methodMap.values().forEach(SlideWindowData::reset);
lastUpdateTime = System.currentTimeMillis();

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;
@ -42,4 +43,5 @@ public class BooleanArrayMerger implements Merger<boolean[]> {
}
return result;
}
}

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;
@ -42,4 +43,5 @@ public class ByteArrayMerger implements Merger<byte[]> {
}
return result;
}
}

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;
@ -29,8 +30,7 @@ public class DoubleArrayMerger implements Merger<double[]> {
if (ArrayUtils.isEmpty(items)) {
return new double[0];
}
return Arrays.stream(items)
.filter(Objects::nonNull)
return Arrays.stream(items).filter(Objects::nonNull)
.flatMapToDouble(Arrays::stream)
.toArray();
}

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;
@ -29,9 +30,9 @@ public class IntArrayMerger implements Merger<int[]> {
if (ArrayUtils.isEmpty(items)) {
return new int[0];
}
return Arrays.stream(items)
.filter(Objects::nonNull)
return Arrays.stream(items).filter(Objects::nonNull)
.flatMapToInt(Arrays::stream)
.toArray();
}
}

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;
@ -33,9 +34,10 @@ public class ListMerger implements Merger<List<?>> {
if (ArrayUtils.isEmpty(items)) {
return Collections.emptyList();
}
return Stream.of(items)
.filter(Objects::nonNull)
return Stream.of(items).filter(Objects::nonNull)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
}

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;
@ -29,8 +30,7 @@ public class LongArrayMerger implements Merger<long[]> {
if (ArrayUtils.isEmpty(items)) {
return new long[0];
}
return Arrays.stream(items)
.filter(Objects::nonNull)
return Arrays.stream(items).filter(Objects::nonNull)
.flatMapToLong(Arrays::stream)
.toArray();
}

View File

@ -32,8 +32,9 @@ public class MapMerger implements Merger<Map<?, ?>> {
if (ArrayUtils.isEmpty(items)) {
return Collections.emptyMap();
}
Map<Object, Object> result = new HashMap<>();
Map<Object, Object> result = new HashMap<Object, Object>();
Stream.of(items).filter(Objects::nonNull).forEach(result::putAll);
return result;
}
}

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
@ -36,7 +37,7 @@ public class MergerFactory implements ScopeModelAware {
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MergerFactory.class);
private ConcurrentMap<Class<?>, Merger<?>> MERGER_CACHE = new ConcurrentHashMap<>();
private ConcurrentMap<Class<?>, Merger<?>> MERGER_CACHE = new ConcurrentHashMap<Class<?>, Merger<?>>();
private ScopeModel scopeModel;
@Override
@ -68,17 +69,13 @@ public class MergerFactory implements ScopeModelAware {
}
private void loadMergers() {
Set<String> names = scopeModel.getExtensionLoader(Merger.class).getSupportedExtensions();
Set<String> names = scopeModel.getExtensionLoader(Merger.class)
.getSupportedExtensions();
for (String name : names) {
Merger m = scopeModel.getExtensionLoader(Merger.class).getExtension(name);
Class<?> actualTypeArg = getActualTypeArgument(m.getClass());
if (actualTypeArg == null) {
logger.warn(
CLUSTER_FAILED_LOAD_MERGER,
"load merger config failed",
"",
"Failed to get actual type argument from merger "
+ m.getClass().getName());
logger.warn(CLUSTER_FAILED_LOAD_MERGER,"load merger config failed","","Failed to get actual type argument from merger " + m.getClass().getName());
continue;
}
MERGER_CACHE.putIfAbsent(actualTypeArg, m);
@ -97,7 +94,7 @@ public class MergerFactory implements ScopeModelAware {
ParameterizedType mergerType;
for (Type it : interfaceTypes) {
if (it instanceof ParameterizedType
&& (mergerType = ((ParameterizedType) it)).getRawType() == Merger.class) {
&& (mergerType = ((ParameterizedType) it)).getRawType() == Merger.class) {
Type typeArg = mergerType.getActualTypeArguments()[0];
return TypeUtils.getRawClass(typeArg);
}

View File

@ -32,7 +32,7 @@ public class SetMerger implements Merger<Set<?>> {
if (ArrayUtils.isEmpty(items)) {
return Collections.emptySet();
}
Set<Object> result = new HashSet<>();
Set<Object> result = new HashSet<Object>();
Stream.of(items).filter(Objects::nonNull).forEach(result::addAll);
return result;
}

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.utils.ArrayUtils;

View File

@ -28,13 +28,12 @@ public abstract class AbstractRouter implements Router {
private GovernanceRuleRepository ruleRepository;
public AbstractRouter(URL url) {
this.ruleRepository = url.getOrDefaultModuleModel()
.getExtensionLoader(GovernanceRuleRepository.class)
.getDefaultExtension();
this.ruleRepository = url.getOrDefaultModuleModel().getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
this.url = url;
}
public AbstractRouter() {}
public AbstractRouter() {
}
@Override
public URL getUrl() {
@ -68,7 +67,8 @@ public abstract class AbstractRouter implements Router {
this.priority = priority;
}
public GovernanceRuleRepository getRuleRepository() {
public GovernanceRuleRepository getRuleRepository(){
return this.ruleRepository;
}
}

View File

@ -34,7 +34,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
public class RouterSnapshotFilter implements ClusterFilter, BaseFilter.Listener {
private final RouterSnapshotSwitcher switcher;
private static final Logger logger = LoggerFactory.getLogger(RouterSnapshotFilter.class);
private final static Logger logger = LoggerFactory.getLogger(RouterSnapshotFilter.class);
public RouterSnapshotFilter(FrameworkModel frameworkModel) {
this.switcher = frameworkModel.getBeanFactory().getBean(RouterSnapshotSwitcher.class);

View File

@ -114,55 +114,43 @@ public class RouterSnapshotNode<T> {
public String toString(int level) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder
.append("[ ")
.append(name)
.append(' ')
.append("(Input: ")
.append(beforeSize)
.append(") ")
.append("(Current Node Output: ")
.append(nodeOutputSize)
.append(") ")
.append("(Chain Node Output: ")
.append(chainOutputSize)
.append(')')
.append(routerMessage == null ? "" : " Router message: ")
.append(routerMessage == null ? "" : routerMessage)
.append(" ] ");
stringBuilder.append("[ ")
.append(name)
.append(' ')
.append("(Input: ").append(beforeSize).append(") ")
.append("(Current Node Output: ").append(nodeOutputSize).append(") ")
.append("(Chain Node Output: ").append(chainOutputSize).append(')')
.append(routerMessage == null ? "" : " Router message: ")
.append(routerMessage == null ? "" : routerMessage)
.append(" ] ");
if (level == 1) {
stringBuilder
.append("Input: ")
.append(
CollectionUtils.isEmpty(inputInvokers)
? "Empty"
: inputInvokers.subList(0, Math.min(5, inputInvokers.size())).stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(",")))
.append(" -> ");
stringBuilder.append("Input: ")
.append(CollectionUtils.isEmpty(inputInvokers) ? "Empty" :
inputInvokers.subList(0, Math.min(5, inputInvokers.size()))
.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(",")))
.append(" -> ");
stringBuilder
.append("Chain Node Output: ")
.append(
CollectionUtils.isEmpty(chainOutputInvokers)
? "Empty"
: chainOutputInvokers.subList(0, Math.min(5, chainOutputInvokers.size())).stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(",")));
stringBuilder.append("Chain Node Output: ")
.append(CollectionUtils.isEmpty(chainOutputInvokers) ? "Empty" :
chainOutputInvokers.subList(0, Math.min(5, chainOutputInvokers.size()))
.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(",")));
} else {
stringBuilder
.append("Current Node Output: ")
.append(
CollectionUtils.isEmpty(nodeOutputInvokers)
? "Empty"
: nodeOutputInvokers.subList(0, Math.min(5, nodeOutputInvokers.size())).stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(",")));
stringBuilder.append("Current Node Output: ")
.append(CollectionUtils.isEmpty(nodeOutputInvokers) ? "Empty" :
nodeOutputInvokers.subList(0, Math.min(5, nodeOutputInvokers.size()))
.stream()
.map(Invoker::getUrl)
.map(URL::getAddress)
.collect(Collectors.joining(",")));
}
if (nodeOutputInvokers != null && nodeOutputInvokers.size() > 5) {
stringBuilder.append("...");
}

View File

@ -26,7 +26,7 @@ public class RouterSnapshotSwitcher {
private volatile boolean enable;
private final Set<String> enabledService = new ConcurrentHashSet<>();
private static final int MAX_LENGTH = 1 << 5; // 2 ^ 5 = 31
private final static int MAX_LENGTH = 1 << 5; // 2 ^ 5 = 31
private final AtomicInteger offset = new AtomicInteger(0);
private volatile String[] recentSnapshot = new String[MAX_LENGTH];

View File

@ -84,8 +84,7 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
super(url);
this.setForce(force);
this.enabled = enabled;
matcherFactories =
moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions();
matcherFactories = moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions();
if (enabled) {
this.init(rule);
}
@ -95,8 +94,7 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
super(url);
this.setUrl(url);
this.setForce(url.getParameter(FORCE_KEY, false));
matcherFactories =
moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions();
matcherFactories = moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions();
this.enabled = url.getParameter(ENABLED_KEY, true);
if (enabled) {
init(url.getParameterAndDecoded(RULE_KEY));
@ -112,10 +110,8 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
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<String, ConditionMatcher> when =
StringUtils.isBlank(whenRule) || "true".equals(whenRule) ? new HashMap<>() : parseRule(whenRule);
Map<String, ConditionMatcher> then =
StringUtils.isBlank(thenRule) || "false".equals(thenRule) ? null : parseRule(thenRule);
Map<String, ConditionMatcher> when = StringUtils.isBlank(whenRule) || "true".equals(whenRule) ? new HashMap<>() : parseRule(whenRule);
Map<String, ConditionMatcher> 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;
@ -124,7 +120,8 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
}
}
private Map<String, ConditionMatcher> parseRule(String rule) throws ParseException {
private Map<String, ConditionMatcher> parseRule(String rule)
throws ParseException {
Map<String, ConditionMatcher> condition = new HashMap<>();
if (StringUtils.isBlank(rule)) {
return condition;
@ -154,12 +151,10 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
// The Value in the KV part.
else if ("=".equals(separator)) {
if (matcherPair == null) {
throw new ParseException(
"Illegal route rule \""
+ rule + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".",
matcher.start());
throw new ParseException("Illegal route rule \""
+ rule + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".", matcher.start());
}
values = matcherPair.getMatches();
@ -168,12 +163,10 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
// The Value in the KV part.
else if ("!=".equals(separator)) {
if (matcherPair == null) {
throw new ParseException(
"Illegal route rule \""
+ rule + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".",
matcher.start());
throw new ParseException("Illegal route rule \""
+ rule + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".", matcher.start());
}
values = matcherPair.getMismatches();
@ -182,34 +175,25 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
// The Value in the KV part, if Value have more than one items.
else if (",".equals(separator)) { // Should be separated by ','
if (values == null || values.isEmpty()) {
throw new ParseException(
"Illegal route rule \""
+ rule + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".",
matcher.start());
throw new ParseException("Illegal route rule \""
+ rule + "\", The error char '" + separator
+ "' at index " + matcher.start() + " before \""
+ content + "\".", matcher.start());
}
values.add(content);
} else {
throw new ParseException(
"Illegal route rule \"" + rule
+ "\", The error char '" + separator + "' at index "
+ matcher.start() + " before \"" + content + "\".",
matcher.start());
throw new ParseException("Illegal route rule \"" + rule
+ "\", The error char '" + separator + "' at index "
+ matcher.start() + " before \"" + content + "\".", matcher.start());
}
}
return condition;
}
@Override
protected BitList<Invoker<T>> doRoute(
BitList<Invoker<T>> invokers,
URL url,
Invocation invocation,
boolean needToPrintMessage,
Holder<RouterSnapshotNode<T>> nodeHolder,
Holder<String> messageHolder)
throws RpcException {
protected BitList<Invoker<T>> doRoute(BitList<Invoker<T>> invokers, URL url, Invocation invocation,
boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> nodeHolder,
Holder<String> messageHolder) throws RpcException {
if (!enabled) {
if (needToPrintMessage) {
messageHolder.set("Directly return. Reason: ConditionRouter disabled.");
@ -231,13 +215,7 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
return invokers;
}
if (thenCondition == null) {
logger.warn(
CLUSTER_CONDITIONAL_ROUTE_LIST_EMPTY,
"condition state router thenCondition is empty",
"",
"The current consumer in the service blocklist. consumer: " + NetUtils.getLocalHost()
+ ", service: " + url.getServiceKey());
if (needToPrintMessage) {
logger.warn(CLUSTER_CONDITIONAL_ROUTE_LIST_EMPTY,"condition state router thenCondition is empty","","The current consumer in the service blacklist. consumer: " + NetUtils.getLocalHost() + ", service: " + url.getServiceKey()); if (needToPrintMessage) {
messageHolder.set("Empty return. Reason: ThenCondition is empty.");
}
return BitList.emptyList();
@ -251,26 +229,14 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
}
return result;
} else if (this.isForce()) {
logger.warn(
CLUSTER_CONDITIONAL_ROUTE_LIST_EMPTY,
"execute condition state router result list is empty. and force=true",
"",
"The route result is empty and force execute. consumer: " + NetUtils.getLocalHost()
+ ", service: " + url.getServiceKey() + ", router: "
+ url.getParameterAndDecoded(RULE_KEY));
logger.warn(CLUSTER_CONDITIONAL_ROUTE_LIST_EMPTY,"execute condition state router result list is empty. and force=true","","The route result is empty and force execute. consumer: " + NetUtils.getLocalHost() + ", service: " + url.getServiceKey() + ", router: " + url.getParameterAndDecoded(RULE_KEY));
if (needToPrintMessage) {
messageHolder.set("Empty return. Reason: Empty result from condition and condition is force.");
}
return result;
}
} catch (Throwable t) {
logger.error(
CLUSTER_FAILED_EXEC_CONDITION_ROUTER,
"execute condition state router exception",
"",
"Failed to execute condition router rule: " + getUrl() + ", invokers: " + invokers + ", cause: "
+ t.getMessage(),
t);
logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER,"execute condition state router exception","","Failed to execute condition router rule: " + getUrl() + ", invokers: " + invokers + ", cause: " + t.getMessage(),t);
}
if (needToPrintMessage) {
messageHolder.set("Directly return. Reason: Error occurred ( or result is empty ).");
@ -281,7 +247,7 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
@Override
public boolean isRuntime() {
// We always return true for previously defined Router, that is, old Router doesn't support cache anymore.
// return true;
// return true;
return this.getUrl().getParameter(RUNTIME_KEY, false);
}
@ -291,10 +257,7 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
return factory.createMatcher(key, moduleModel);
}
}
return moduleModel
.getExtensionLoader(ConditionMatcherFactory.class)
.getExtension("param")
.createMatcher(key, moduleModel);
return moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getExtension("param").createMatcher(key, moduleModel);
}
boolean matchWhen(URL url, Invocation invocation) {
@ -313,12 +276,7 @@ public class ConditionStateRouter<T> extends AbstractStateRouter<T> {
return doMatch(url, param, null, thenCondition, false);
}
private boolean doMatch(
URL url,
URL param,
Invocation invocation,
Map<String, ConditionMatcher> conditions,
boolean isWhenCondition) {
private boolean doMatch(URL url, URL param, Invocation invocation, Map<String, ConditionMatcher> conditions, boolean isWhenCondition) {
Map<String, String> sample = url.toOriginalMap();
for (Map.Entry<String, ConditionMatcher> entry : conditions.entrySet()) {
ConditionMatcher matchPair = entry.getValue();

View File

@ -30,6 +30,6 @@ public class ConditionStateRouterFactory extends CacheableStateRouterFactory {
@Override
protected <T> StateRouter<T> createRouter(Class<T> interfaceClass, URL url) {
return new ConditionStateRouter<>(url);
return new ConditionStateRouter<T>(url);
}
}

View File

@ -50,8 +50,7 @@ public abstract class ListenableStateRouter<T> extends AbstractStateRouter<T> im
public static final String NAME = "LISTENABLE_ROUTER";
public static final String RULE_SUFFIX = ".condition-router";
private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class);
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class);
private volatile ConditionRouterRule routerRule;
private volatile List<ConditionStateRouter<T>> conditionRouters = Collections.emptyList();
private final String ruleKey;
@ -65,9 +64,9 @@ public abstract class ListenableStateRouter<T> extends AbstractStateRouter<T> im
@Override
public synchronized void process(ConfigChangedEvent event) {
if (logger.isInfoEnabled()) {
logger.info("Notification of condition rule, change type is: " + event.getChangeType() + ", raw rule is:\n "
+ event.getContent());
if (logger.isDebugEnabled()) {
logger.debug("Notification of condition rule, change type is: " + event.getChangeType() +
", raw rule is:\n " + event.getContent());
}
if (event.getChangeType().equals(ConfigChangeType.DELETED)) {
@ -78,31 +77,18 @@ public abstract class ListenableStateRouter<T> extends AbstractStateRouter<T> im
routerRule = ConditionRuleParser.parse(event.getContent());
generateConditions(routerRule);
} catch (Exception e) {
logger.error(
CLUSTER_FAILED_RULE_PARSING,
"Failed to parse the raw condition rule",
"",
"Failed to parse the raw condition rule and it will not take effect, please check "
+ "if the condition rule matches with the template, the raw rule is:\n "
+ event.getContent(),
e);
logger.error(CLUSTER_FAILED_RULE_PARSING,"Failed to parse the raw condition rule","","Failed to parse the raw condition rule and it will not take effect, please check " +
"if the condition rule matches with the template, the raw rule is:\n " + event.getContent(),e);
}
}
}
@Override
public BitList<Invoker<T>> doRoute(
BitList<Invoker<T>> invokers,
URL url,
Invocation invocation,
boolean needToPrintMessage,
Holder<RouterSnapshotNode<T>> nodeHolder,
Holder<String> messageHolder)
throws RpcException {
public BitList<Invoker<T>> doRoute(BitList<Invoker<T>> invokers, URL url, Invocation invocation,
boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> nodeHolder, Holder<String> messageHolder) throws RpcException {
if (CollectionUtils.isEmpty(invokers) || conditionRouters.size() == 0) {
if (needToPrintMessage) {
messageHolder.set(
"Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty.");
messageHolder.set("Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty.");
}
return invokers;
}
@ -137,9 +123,9 @@ public abstract class ListenableStateRouter<T> extends AbstractStateRouter<T> im
private void generateConditions(ConditionRouterRule rule) {
if (rule != null && rule.isValid()) {
this.conditionRouters = rule.getConditions().stream()
.map(condition ->
new ConditionStateRouter<T>(getUrl(), condition, rule.isForce(), rule.isEnabled()))
this.conditionRouters = rule.getConditions()
.stream()
.map(condition -> new ConditionStateRouter<T>(getUrl(), condition, rule.isForce(), rule.isEnabled()))
.collect(Collectors.toList());
for (ConditionStateRouter<T> conditionRouter : this.conditionRouters) {
conditionRouter.setNextRouter(TailStateRouter.getInstance());

View File

@ -33,8 +33,7 @@ import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
* Application level router, "application.condition-router"
*/
public class ProviderAppStateRouter<T> extends ListenableStateRouter<T> {
private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class);
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ListenableStateRouter.class);
public static final String NAME = "PROVIDER_APP_ROUTER";
private String application;
private final String currentApplication;
@ -55,15 +54,8 @@ public class ProviderAppStateRouter<T> extends ListenableStateRouter<T> {
String providerApplication = url.getRemoteApplication();
// provider application is empty or equals with the current application
if (isEmpty(providerApplication)) {
logger.warn(
CLUSTER_TAG_ROUTE_EMPTY,
"condition router get providerApplication is empty, will not subscribe to provider app rules.",
"",
"");
return;
}
if (providerApplication.equals(currentApplication)) {
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;
}

View File

@ -32,6 +32,7 @@ public class ServiceStateRouterFactory extends CacheableStateRouterFactory {
@Override
protected <T> StateRouter<T> createRouter(Class<T> interfaceClass, URL url) {
return new ServiceStateRouter<>(url);
return new ServiceStateRouter<T>(url);
}
}

View File

@ -34,14 +34,15 @@ public class ConditionRouterRule extends AbstractRouterRule {
Object conditions = map.get(CONDITIONS_KEY);
if (conditions != null && List.class.isAssignableFrom(conditions.getClass())) {
conditionRouterRule.setConditions(
((List<Object>) conditions).stream().map(String::valueOf).collect(Collectors.toList()));
conditionRouterRule.setConditions(((List<Object>) conditions).stream()
.map(String::valueOf).collect(Collectors.toList()));
}
return conditionRouterRule;
}
public ConditionRouterRule() {}
public ConditionRouterRule() {
}
public List<String> getConditions() {
return conditions;

View File

@ -18,12 +18,12 @@ package org.apache.dubbo.rpc.cluster.router.condition.config.model;
import org.apache.dubbo.common.utils.CollectionUtils;
import java.util.Map;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import java.util.Map;
/**
* %YAML1.2
*
@ -51,4 +51,5 @@ public class ConditionRuleParser {
return rule;
}
}

View File

@ -22,7 +22,6 @@ 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 org.apache.dubbo.rpc.support.RpcUtils;
import java.util.HashSet;
import java.util.List;
@ -38,8 +37,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAIL
* provides the common match logics.
*/
public abstract class AbstractConditionMatcher implements ConditionMatcher {
public static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(AbstractConditionMatcher.class);
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<String> matches = new HashSet<>();
final Set<String> mismatches = new HashSet<>();
@ -53,12 +51,11 @@ public abstract class AbstractConditionMatcher implements ConditionMatcher {
this.valueMatchers = model.getExtensionLoader(ValuePattern.class).getActivateExtensions();
}
public static String getSampleValueFromUrl(
String conditionKey, Map<String, String> sample, URL param, Invocation invocation) {
public static String getSampleValueFromUrl(String conditionKey, Map<String, String> sample, URL param, Invocation invocation) {
String sampleValue;
// get real invoked method name from invocation
//get real invoked method name from invocation
if (invocation != null && (METHOD_KEY.equals(conditionKey) || METHODS_KEY.equals(conditionKey))) {
sampleValue = RpcUtils.getMethodName(invocation);
sampleValue = invocation.getMethodName();
} else {
sampleValue = sample.get(conditionKey);
}
@ -69,8 +66,7 @@ public abstract class AbstractConditionMatcher implements ConditionMatcher {
public boolean isMatch(Map<String, String> 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.
// if key does not present in whichever of url, invocation or attachment based on the matcher type, then return false.
return false;
}
@ -93,7 +89,7 @@ public abstract class AbstractConditionMatcher implements ConditionMatcher {
}
if (!matches.isEmpty() && !mismatches.isEmpty()) {
// when both mismatches and matches contain the same value, then using mismatches first
//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;
@ -120,23 +116,16 @@ public abstract class AbstractConditionMatcher implements ConditionMatcher {
}
// range, equal or other methods
protected boolean doPatternMatch(
String pattern, String value, URL url, Invocation invocation, boolean isWhenCondition) {
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.");
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");
ValuePattern paramValueMatcher = model.getExtensionLoader(ValuePattern.class).getExtension("wildcard");
return paramValueMatcher.match(pattern, value, url, invocation, isWhenCondition);
}
@ -145,4 +134,5 @@ public abstract class AbstractConditionMatcher implements ConditionMatcher {
* This makes condition rule possible to check values in any place of a request.
*/
protected abstract String getValue(Map<String, String> sample, URL url, Invocation invocation);
}

View File

@ -38,8 +38,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAIL
*/
@Activate
public class ArgumentConditionMatcher extends AbstractConditionMatcher {
private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(ArgumentConditionMatcher.class);
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) {
@ -57,21 +56,16 @@ public class ArgumentConditionMatcher extends AbstractConditionMatcher {
return DOES_NOT_FOUND_VALUE;
}
// extract the argument index
//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
//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);
logger.warn(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Parse argument match condition failed", "", "Invalid , will ignore., ", e);
}
return DOES_NOT_FOUND_VALUE;
}

View File

@ -38,8 +38,7 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAIL
*/
@Activate
public class AttachmentConditionMatcher extends AbstractConditionMatcher {
private static final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(AttachmentConditionMatcher.class);
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AttachmentConditionMatcher.class);
private static final Pattern ATTACHMENTS_PATTERN = Pattern.compile("attachments\\[(.+)\\]");
public AttachmentConditionMatcher(String key, ModuleModel model) {
@ -57,21 +56,20 @@ public class AttachmentConditionMatcher extends AbstractConditionMatcher {
return DOES_NOT_FOUND_VALUE;
}
// extract the argument index
//extract the argument index
String attachmentKey = matcher.group(1);
if (StringUtils.isEmpty(attachmentKey)) {
return DOES_NOT_FOUND_VALUE;
}
// extract the argument 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);
logger.warn(CLUSTER_FAILED_EXEC_CONDITION_ROUTER,
"condition state router attachment match failed",
"",
"Invalid match condition: " + key,
e);
}
return DOES_NOT_FOUND_VALUE;
}

View File

@ -37,4 +37,5 @@ public class UrlParamConditionMatcher extends AbstractConditionMatcher {
protected String getValue(Map<String, String> sample, URL url, Invocation invocation) {
return getSampleValueFromUrl(key, sample, url, invocation);
}
}

View File

@ -46,11 +46,7 @@ public class RangeValuePattern implements ValuePattern {
String[] arr = pattern.split("~");
if (arr.length < 2) {
logger.error(
CLUSTER_FAILED_EXEC_CONDITION_ROUTER,
"",
"",
"Invalid condition rule " + pattern + " or value " + value + ", will ignore.");
logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "", "", "Invalid condition rule " + pattern + " or value " + value + ", will ignore.");
return defaultValue;
}
@ -79,12 +75,7 @@ public class RangeValuePattern implements ValuePattern {
}
}
} catch (Exception e) {
logger.error(
CLUSTER_FAILED_EXEC_CONDITION_ROUTER,
"Parse integer error",
"",
"Invalid condition rule " + pattern + " or value " + value + ", will ignore.",
e);
logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Parse integer error", "", "Invalid condition rule " + pattern + " or value " + value + ", will ignore.", e);
return defaultValue;
}

View File

@ -46,9 +46,7 @@ public class FileStateRouterFactory implements StateRouterFactory {
try {
// Transform File URL into Script Route URL, and Load
// file:///d:/path/to/route.js?router=script ==> script:///d:/path/to/route.js?type=js&rule=<file-content>
String protocol = url.getParameter(
ROUTER_KEY,
ScriptStateRouterFactory.NAME); // Replace original protocol (maybe 'file') with 'script'
String protocol = url.getParameter(ROUTER_KEY, ScriptStateRouterFactory.NAME); // Replace original protocol (maybe 'file') with 'script'
String type = null; // Use file suffix to config script type, e.g., js, groovy ...
String path = url.getPath();
if (path != null) {
@ -73,4 +71,5 @@ public class FileStateRouterFactory implements StateRouterFactory {
throw new IllegalStateException(e.getMessage(), e);
}
}
}

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