Compare commits
82 Commits
3.2
...
3.3-config
| Author | SHA1 | Date |
|---|---|---|
|
|
f020f3e3d1 | |
|
|
9eb83d16bb | |
|
|
98e7313e71 | |
|
|
a6a6d57dd7 | |
|
|
8009c72030 | |
|
|
7e6a32ba68 | |
|
|
36a80e4db7 | |
|
|
bf3d4f4ca3 | |
|
|
f91246ab09 | |
|
|
679ce4496c | |
|
|
4e9a0a41fc | |
|
|
7a4ec6c525 | |
|
|
ae150c01e5 | |
|
|
629bee3987 | |
|
|
5ae875d951 | |
|
|
04f3fe7d2b | |
|
|
059fdf2613 | |
|
|
7c971ca1bd | |
|
|
b18eeb7077 | |
|
|
6c5a876f31 | |
|
|
ce65317207 | |
|
|
046898bbc8 | |
|
|
29d9c070d4 | |
|
|
8fefd95a98 | |
|
|
2973426b2a | |
|
|
70605f4dd0 | |
|
|
d1719c5358 | |
|
|
0e17f4f168 | |
|
|
72e5d20ce9 | |
|
|
0db8605974 | |
|
|
80d496c5b1 | |
|
|
093fb7c208 | |
|
|
f78b4f5dea | |
|
|
1f8a0fa5ec | |
|
|
f2ec217f54 | |
|
|
c7d411c3cb | |
|
|
8bb17b85f2 | |
|
|
4b62513dff | |
|
|
9bbf7625a8 | |
|
|
0d4e8304bc | |
|
|
48cc5b24de | |
|
|
37f150263a | |
|
|
95207b9079 | |
|
|
da8d0cd994 | |
|
|
27e6838c3b | |
|
|
1c65617fb1 | |
|
|
cf2a63580e | |
|
|
d6776e4008 | |
|
|
b14201f393 | |
|
|
c96a06eba1 | |
|
|
1e59ab524a | |
|
|
fd14e7b76f | |
|
|
642f741dba | |
|
|
85bc6ea472 | |
|
|
391d3cdb35 | |
|
|
2031a4c531 | |
|
|
e642e72ce8 | |
|
|
4604b8074a | |
|
|
30daba2d74 | |
|
|
1f39543632 | |
|
|
71046bdd6f | |
|
|
ae4899a462 | |
|
|
7661cab6f5 | |
|
|
d798e7c3be | |
|
|
34eb252178 | |
|
|
59758f4b58 | |
|
|
52e4e4e301 | |
|
|
71cc51bf69 | |
|
|
a80ad7f505 | |
|
|
9f0e1589a5 | |
|
|
471f44b52d | |
|
|
992abd2d34 | |
|
|
9d9df82194 | |
|
|
6c8f79c889 | |
|
|
2997fa6a2e | |
|
|
13558a8e6a | |
|
|
59832d45d4 | |
|
|
fe55491d4a | |
|
|
b23bae38cc | |
|
|
0b6f2e4a8d | |
|
|
414785c05b | |
|
|
52611099ab |
42
.artifacts
42
.artifacts
|
|
@ -19,6 +19,7 @@
|
|||
dubbo
|
||||
dubbo-auth
|
||||
dubbo-apache-release
|
||||
dubbo-all-shaded
|
||||
dubbo-bom
|
||||
dubbo-build-tools
|
||||
dubbo-cluster
|
||||
|
|
@ -28,7 +29,11 @@ dubbo-compiler
|
|||
dubbo-config
|
||||
dubbo-config-api
|
||||
dubbo-config-spring
|
||||
dubbo-config-spring6
|
||||
dubbo-config-test
|
||||
dubbo-configcenter
|
||||
dubbo-configcenter-api
|
||||
dubbo-configcenter-file
|
||||
dubbo-configcenter-apollo
|
||||
dubbo-configcenter-nacos
|
||||
dubbo-configcenter-zookeeper
|
||||
|
|
@ -49,6 +54,7 @@ dubbo-kubernetes
|
|||
dubbo-maven-plugin
|
||||
dubbo-metadata
|
||||
dubbo-metadata-api
|
||||
dubbo-metadata-rest
|
||||
dubbo-metadata-definition-protobuf
|
||||
dubbo-metadata-processor
|
||||
dubbo-metadata-report-nacos
|
||||
|
|
@ -61,11 +67,13 @@ dubbo-metrics-metadata
|
|||
dubbo-metrics-prometheus
|
||||
dubbo-metrics-registry
|
||||
dubbo-metrics-config-center
|
||||
dubbo-metrics-netty
|
||||
dubbo-metrics-event
|
||||
dubbo-monitor
|
||||
dubbo-monitor-api
|
||||
dubbo-monitor-common
|
||||
dubbo-monitor-default
|
||||
dubbo-native
|
||||
dubbo-native-plugin
|
||||
dubbo-parent
|
||||
dubbo-plugin
|
||||
dubbo-qos
|
||||
|
|
@ -82,6 +90,7 @@ dubbo-remoting-api
|
|||
dubbo-remoting-http
|
||||
dubbo-remoting-netty
|
||||
dubbo-remoting-netty4
|
||||
dubbo-remoting-zookeeper-api
|
||||
dubbo-remoting-zookeeper
|
||||
dubbo-remoting-zookeeper-curator5
|
||||
dubbo-rpc
|
||||
|
|
@ -102,16 +111,35 @@ dubbo-spring-boot-actuator-compatible
|
|||
dubbo-spring-boot-autoconfigure
|
||||
dubbo-spring-boot-autoconfigure-compatible
|
||||
dubbo-spring-boot-compatible
|
||||
dubbo-spring-boot-observability-starters
|
||||
dubbo-spring-boot-observability-autoconfigure
|
||||
dubbo-spring-boot-tracing-brave-zipkin-starter
|
||||
dubbo-spring-boot-tracing-otel-zipkin-starter
|
||||
dubbo-spring-boot-tracing-otel-otlp-starter
|
||||
dubbo-spring-boot-observability-starter
|
||||
dubbo-observability-spring-boot-starters
|
||||
dubbo-observability-spring-boot-autoconfigure
|
||||
dubbo-tracing-brave-zipkin-spring-boot-starter
|
||||
dubbo-tracing-otel-zipkin-spring-boot-starter
|
||||
dubbo-tracing-otel-otlp-spring-boot-starter
|
||||
dubbo-observability-spring-boot-starter
|
||||
dubbo-spring-boot-starter
|
||||
dubbo-spring-boot-starters
|
||||
dubbo-spring-boot-interceptor
|
||||
dubbo-nacos-spring-boot-starter
|
||||
dubbo-zookeeper-spring-boot-starter
|
||||
dubbo-zookeeper-curator5-spring-boot-starter
|
||||
dubbo-sentinel-spring-boot-starter
|
||||
dubbo-seata-spring-boot-starter
|
||||
dubbo-spring-security
|
||||
dubbo-tracing
|
||||
dubbo-xds
|
||||
dubbo-plugin-cluster-mergeable
|
||||
dubbo-plugin-mock
|
||||
dubbo-plugin-router-script
|
||||
dubbo-plugin-router-mesh
|
||||
dubbo-plugin-router-condition
|
||||
dubbo-plugin-router-tag
|
||||
dubbo-plugin-loadbalance-adaptive
|
||||
dubbo-plugin-access-log
|
||||
dubbo-plugin-tps
|
||||
dubbo-plugin-token
|
||||
dubbo-plugin-generic-invoke
|
||||
dubbo-plugin-context
|
||||
dubbo-plugin-classloader-filter
|
||||
dubbo-plugin-proxy-bytebuddy
|
||||
dubbo-plugin-qos-trace
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
@ -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!"
|
||||
|
|
@ -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!"
|
||||
|
|
@ -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!"
|
||||
|
|
@ -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!
|
||||
```
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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. -->
|
||||
|
|
@ -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 -->
|
||||
|
||||
|
|
@ -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. -->
|
||||
|
|
@ -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
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
## What is the purpose of the change
|
||||
|
||||
|
||||
|
||||
## Brief changelog
|
||||
|
||||
|
||||
## Verifying this change
|
||||
|
||||
|
||||
<!-- Follow this checklist to help us incorporate your contribution quickly and easily: -->
|
||||
|
||||
## Checklist
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change (usually before you start working on it). Trivial changes like typos do not require a GitHub issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
|
||||
- [ ] Each commit in the pull request should have a meaningful subject line and body.
|
||||
- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [ ] Check if is necessary to patch to Dubbo 3 if you are work on Dubbo 2.7
|
||||
- [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [ ] Add some description to [dubbo-website](https://github.com/apache/dubbo-website) project if you are requesting to add a feature.
|
||||
- [ ] GitHub Actions works fine on your own branch.
|
||||
- [ ] If this contribution is large, please follow the [Software Donation Guide](https://github.com/apache/dubbo/wiki/Software-donation-guide).
|
||||
|
|
@ -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 }}
|
||||
|
|
@ -97,7 +54,7 @@ jobs:
|
|||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 8
|
||||
java-version: 17
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
|
|
@ -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: |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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: |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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: |
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ header:
|
|||
- '**/*.fc'
|
||||
- '**/*.javascript'
|
||||
- '**/*.properties'
|
||||
- '**/*.thrift'
|
||||
- '**/*.sh'
|
||||
- '**/*.bat'
|
||||
- '**/*.md'
|
||||
|
|
@ -96,10 +97,13 @@ header:
|
|||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/api/ExecutableMode.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/api/MemberCategory.java'
|
||||
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboMergingDigest.java'
|
||||
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboAbstractTDigest.java'
|
||||
- 'dubbo-annotation-processor/src/main/java/org/apache/dubbo/annotation/permit/**'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/FormattingTuple.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/MessageFormatter.java'
|
||||
|
||||
comment: on-failure
|
||||
|
||||
|
|
@ -198,10 +202,26 @@ dependency:
|
|||
license: Apache-2.0
|
||||
- name: org.sonatype.plexus:plexus-cipher
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-apache-dubbo3-adapter
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-transport-simple-http
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-transport-common
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-datasource-extension
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-core
|
||||
license: Apache-2.0
|
||||
- name: com.google.protobuf:protobuf-java
|
||||
license: BSD 3-clause
|
||||
- name: com.google.protobuf:protobuf-java-util
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:antlr4
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:antlr-runtime
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:ST4
|
||||
license: BSD 3-clause
|
||||
# multi license
|
||||
- name: org.javassist:javassist
|
||||
license: Apache-2.0
|
||||
|
|
|
|||
4
NOTICE
4
NOTICE
|
|
@ -1,10 +1,10 @@
|
|||
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/).
|
||||
|
||||
This product contains code form the Netty Project:
|
||||
This product contains code from the Netty Project:
|
||||
|
||||
The Netty Project
|
||||
=================
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
## What is the purpose of the change?
|
||||
|
||||
|
||||
## Checklist
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change.
|
||||
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [x] Write necessary unit-test to verify your logic correction. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [x] Make sure gitHub actions can pass. [Why the workflow is failing and how to fix it?](./CONTRIBUTING.md)
|
||||
286
README.md
286
README.md
|
|
@ -6,267 +6,73 @@
|
|||

|
||||
[](http://isitmaintained.com/project/apache/dubbo "Average time to resolve an issue")
|
||||
[](http://isitmaintained.com/project/apache/dubbo "Percentage of issues still open")
|
||||
[](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)
|
||||
[](https://twitter.com/intent/follow?screen_name=ApacheDubbo)
|
||||
[](https://gitter.im/alibaba/dubbo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Apache Dubbo is a high-performance, Java-based open-source RPC framework. Please visit the [official site](http://dubbo.apache.org) for the quick start guide and documentation, as well as the [wiki](https://github.com/apache/dubbo/wiki) for news, FAQ, and release notes.
|
||||
Apache Dubbo is an easy-to-use Web and RPC framework that provides multiple
|
||||
language implementations(Java, [Go](https://github.com/apache/dubbo-go), [Rust](https://github.com/apache/dubbo-rust), [Node.js](https://github.com/apache/dubbo-js), [Web](https://github.com/apache/dubbo-js)) for communication, service discovery, traffic management,
|
||||
observability, security, tools, and best practices for building enterprise-ready microservices.
|
||||
|
||||
We are now collecting Dubbo user info to help us to improve Dubbo further. Kindly support us by providing your usage information on [Wanted: who's using dubbo](https://github.com/apache/dubbo/discussions/13842), thanks :)
|
||||
Visit [the official website](https://dubbo.apache.org/) for more information.
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Transparent interface based RPC
|
||||
* Intelligent load balancing
|
||||
* Automatic service registration and discovery
|
||||
* High extensibility
|
||||
* Runtime traffic routing
|
||||
* Visualized service governance
|
||||
* Consumer and provider communicate with each other using RPC protocol like triple, tcp, rest, etc.
|
||||
* Consumers automatically trace provider instances registered in registries(Zookeeper, Nacos) and distribute traffic among them by following traffic strategies.
|
||||
* Rich features for monitoring and managing the cluster with dynamic configuration, metrics, tracing, security, and visualized console.
|
||||
|
||||
## Getting started
|
||||
Follow the instructions below to learn how to:
|
||||
|
||||
The following code snippet comes from [Dubbo Samples](https://github.com/apache/dubbo-samples.git). You may clone the sample project and step into the `dubbo-samples-api` subdirectory before proceeding.
|
||||
### Programming with lightweight RPC API
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/rpc/java)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/apache/dubbo-samples.git
|
||||
cd dubbo-samples/1-basic/dubbo-samples-api
|
||||
```
|
||||
|
||||
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
|
||||
|
||||
### Maven dependency
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<dubbo.version>3.2.13-SNAPSHOT</dubbo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-zookeeper</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### Define service interfaces
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.api;
|
||||
|
||||
public interface GreetingsService {
|
||||
String sayHi(String name);
|
||||
}
|
||||
```
|
||||
|
||||
*See [api/GreetingsService.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java) on GitHub.*
|
||||
|
||||
### Implement service interface for the provider
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.provider;
|
||||
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
|
||||
public class GreetingsServiceImpl implements GreetingsService {
|
||||
@Override
|
||||
public String sayHi(String name) {
|
||||
return "hi, " + name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*See [provider/GreetingsServiceImpl.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java) on GitHub.*
|
||||
|
||||
### Start service provider
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.provider;
|
||||
Dubbo supports building RPC services with only a few lines of code while depending only on a lightweight SDK (<10MB). The protocol on the wire can be [Triple](https://dubbo.apache.org/zh-cn/overview/reference/protocols/triple/)(fully gRPC compatible and HTTP-friendly), Dubbo2(TCP), REST, or any protocol of your choice.
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
### Building a microservice application with Spring Boot
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/microservice)
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
It's highly recommended to start your microservice application with the Spring Boot Starter `dubbo-spring-boot-starter` provided by Dubbo. With only a single dependency and yaml file, and optionally a bunch of other useful spring boot starters, you can enable all of the Dubo features like service discovery, observability, tracing, etc.
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
Next, learn how to [deploy](https://dubbo.apache.org/zh-cn/overview/tasks/deploy/), [monitor](https://dubbo.apache.org/zh-cn/overview/tasks/observability/), and [manage the traffic](https://dubbo.apache.org/zh-cn/overview/tasks/traffic-management/) of your Dubbo application and cluster.
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
|
||||
service.setApplication(new ApplicationConfig("first-dubbo-provider"));
|
||||
service.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
service.setInterface(GreetingsService.class);
|
||||
service.setRef(new GreetingsServiceImpl());
|
||||
service.export();
|
||||
## More Features
|
||||
Get more details by visiting the links below to get your hands dirty with some well-designed tasks on our website.
|
||||
|
||||
System.out.println("dubbo service started");
|
||||
new CountDownLatch(1).await();
|
||||
}
|
||||
}
|
||||
```
|
||||
* [Launch a Dubbo project](https://dubbo.apache.org/zh-cn/overview/tasks/develop/template/)
|
||||
* [RPC protocols](https://dubbo.apache.org/zh-cn/overview/core-features/protocols/)
|
||||
* [Traffic management](https://dubbo.apache.org/zh-cn/overview/core-features/traffic/)
|
||||
* [Service discovery](https://dubbo.apache.org/zh-cn/overview/core-features/service-discovery/)
|
||||
* [Observability](https://dubbo.apache.org/zh-cn/overview/core-features/observability/)
|
||||
* [Extensibility](https://dubbo.apache.org/zh-cn/overview/core-features/extensibility/)
|
||||
* [Security](https://dubbo.apache.org/zh-cn/overview/core-features/security/)
|
||||
* [Visualized console and control plane](https://dubbo.apache.org/zh-cn/overview/reference/admin/)
|
||||
* [Kubernetes and Service mesh](https://dubbo.apache.org/zh-cn/overview/core-features/service-mesh/)
|
||||
|
||||
*See [provider/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-spring-xml/src/main/java/org/apache/dubbo/samples/provider/Application.java) on GitHub.*
|
||||
## Which Dubbo version should I use?
|
||||
| **Dubbo3** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 3.3.0-beta| 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/3.3/dubbo-dependencies-bom/pom.xml#L94) | **- Unstable version** <br/> **- Features** <br/> - Triple - gRPC and cURL compatible.<br/> - Rest-style programming support.<br/> - Spring Boot Starters. |
|
||||
| 3.2.5 | 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.5/dubbo-dependencies-bom/pom.xml#L94) | **- Stable version (active)** <br/> **- Features** <br/> - Out-of-box metrics and tracing support.<br/> - Threadpool Isolation<br/> - 30% performance<br/> - Native Image|
|
||||
| 3.1.11 | 1.8 ~ 11 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.11/dubbo-dependencies-bom/pom.xml#L94) | **Stable version (not active)** |
|
||||
|
||||
### Build and run the provider
|
||||
| **Dubbo2** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 2.7.23 | 1.8 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-2.7.23/dubbo-dependencies-bom/pom.xml#L92) | EOL |
|
||||
| 2.6.x, 2.5.x | 1.6 ~ 1.7 | | EOL |
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java
|
||||
```
|
||||
|
||||
### Call remote service in the consumer
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.client;
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
|
||||
public static void main(String[] args) {
|
||||
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
|
||||
reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
|
||||
reference.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
reference.setInterface(GreetingsService.class);
|
||||
GreetingsService service = reference.get();
|
||||
String message = service.sayHi("dubbo");
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
```
|
||||
*See [client/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java) on GitHub.*
|
||||
|
||||
### Build and run the consumer
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.client.Application exec:java
|
||||
```
|
||||
|
||||
The consumer will print out `hi, dubbo` on the screen.
|
||||
|
||||
|
||||
### Next steps
|
||||
|
||||
* [Your first Dubbo application](https://dubbo.apache.org/en/blog/2018/08/07/dubbo-101/) - A 101 tutorial to reveal more details, with the same code above.
|
||||
* [Dubbo user manual](https://dubbo.apache.org/en/overview/what/) - How to use Dubbo and all its features.
|
||||
* [Dubbo developer guide](https://dubbo.apache.org/en/docs3-v2/java-sdk/) - How to involve in Dubbo development.
|
||||
* [Dubbo admin manual](https://dubbo.apache.org/en/docs/v2.7/admin/ops/) - How to admin and manage Dubbo services.
|
||||
|
||||
## Building
|
||||
|
||||
If you want to try out the cutting-edge features, you can build with the following commands. (Java 1.8 is needed to build the master branch)
|
||||
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
## Recommended Test Environment
|
||||
To avoid intermittent test failures (i.e., flaky tests), it is recommended to have a machine or virtual machine with the following specifications:
|
||||
|
||||
* Minimum of 2CPUs.
|
||||
* Minimum of 2Gb of RAM.
|
||||
|
||||
### 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.
|
||||
## Contributing
|
||||
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
## Contact
|
||||
|
||||
* Mailing list:
|
||||
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
|
||||
|
||||
* Bugs: [Issues](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md)
|
||||
* Gitter: [Gitter channel](https://gitter.im/alibaba/dubbo)
|
||||
* WeChat: apachedubbo
|
||||
* DingTalk group: 37290003945
|
||||
* Mailing list: [guide](https://dubbo.apache.org/zh-cn/contact/)
|
||||
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
|
||||
|
||||
## 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 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)
|
||||
* [Node.js](https://github.com/apache/dubbo-js)
|
||||
* [Python](https://github.com/dubbo/py-client-for-apache-dubbo)
|
||||
* [PHP](https://github.com/apache/dubbo-php-framework)
|
||||
* [Erlang](https://github.com/apache/dubbo-erlang)
|
||||
* Security issues: please mail to [us](mailto:security@dubbo.apache.org) privately.
|
||||
|
||||
## License
|
||||
|
||||
Apache Dubbo software is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
Apache Dubbo is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
|
|
|
|||
12
SECURITY.md
12
SECURITY.md
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -29,6 +29,6 @@ ignore:
|
|||
- "**/dubbo-test/**"
|
||||
- "**/dubbo-compatible/**"
|
||||
- "**/dubbo-native/**"
|
||||
- "**/dubbo-native-plugin/**"
|
||||
- "**/dubbo-common/src/main/java/org/apache/dubbo/common/json/*.java" # internal JSON impl is deprecate, ignore test coverage for them
|
||||
- "**/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java" # Deprecated
|
||||
- "**/dubbo-rpc/dubbo-rpc-thrift/**"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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-annotation-processor</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<!-- System dependencies may cause problems in checkstyle. -->
|
||||
<checkstyle.skip>true</checkstyle.skip>
|
||||
<checkstyle_unix.skip>true</checkstyle_unix.skip>
|
||||
<rat.skip>true</rat.skip>
|
||||
<jacoco.skip>true</jacoco.skip>
|
||||
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
|
||||
<junit_jupiter_version>5.9.0</junit_jupiter_version>
|
||||
<javassist_version>3.29.2-GA</javassist_version>
|
||||
</properties>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- JUnit Jupiter Engine to depend on the JUnit5 engine and JUnit 5 API -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit_jupiter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit_jupiter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${junit_jupiter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>${javassist_version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<configuration>
|
||||
<proc>none</proc>
|
||||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>default-profile-in-jdk-8</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>${java.home}/../lib/tools.jar</exists>
|
||||
</file>
|
||||
<jdk>(, 9)</jdk>
|
||||
</activation>
|
||||
<properties>
|
||||
<toolsjar>${java.home}/../lib/tools.jar</toolsjar>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javac</groupId>
|
||||
<artifactId>javac</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${toolsjar}</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>legacy-apple-jdk-profile</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
<file>
|
||||
<exists>${java.home}/../Classes/classes.jar</exists>
|
||||
</file>
|
||||
<jdk>(, 9)</jdk>
|
||||
</activation>
|
||||
|
||||
<properties>
|
||||
<toolsjar>${java.home}/../Classes/classes.jar</toolsjar>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javac</groupId>
|
||||
<artifactId>javac</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${toolsjar}</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>add-export-greater-than-9</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
<jdk>[9, )</jdk>
|
||||
</activation>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<configuration>
|
||||
<fork>true</fork>
|
||||
<proc>none</proc>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
@ -14,28 +14,31 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.metadata.annotation.processing.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
package org.apache.dubbo.annotation;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* {@link Collection} Type Model
|
||||
*
|
||||
* @since 2.7.6
|
||||
* Represents an annotation processing handler, which is invoked by DispatchingAnnotationProcessor.
|
||||
*/
|
||||
public class CollectionTypeModel {
|
||||
public interface AnnotationProcessingHandler {
|
||||
|
||||
private Collection<String> strings; // The composite element is simple type
|
||||
/**
|
||||
* Set the annotations that this handler will handle.
|
||||
*
|
||||
* @return annotations to handle
|
||||
*/
|
||||
Set<Class<? extends Annotation>> getAnnotationsToHandle();
|
||||
|
||||
private List<Color> colors; // The composite element is Enum type
|
||||
|
||||
private Queue<PrimitiveTypeModel> primitiveTypeModels; // The composite element is POJO type
|
||||
|
||||
private Deque<Model> models; // The composite element is hierarchical POJO type
|
||||
|
||||
private Set<Model[]> modelArrays; // The composite element is hierarchical POJO type
|
||||
/**
|
||||
* Formal processing method.
|
||||
*
|
||||
* @param elements the elements that annotated by the annotations of getAnnotationsToHandle()
|
||||
* @param annotationProcessorContext the annotation processor context object (Javac object encapsulation)
|
||||
*/
|
||||
void process(Set<Element> elements,
|
||||
AnnotationProcessorContext annotationProcessorContext);
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation;
|
||||
|
||||
import com.sun.source.util.Trees;
|
||||
import com.sun.tools.javac.api.JavacTrees;
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.Names;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The Context Object of Annotation Processor, which stores objects related to javac.
|
||||
*/
|
||||
public class AnnotationProcessorContext {
|
||||
private JavacProcessingEnvironment javacProcessingEnvironment;
|
||||
private JavacTrees javacTrees;
|
||||
private TreeMaker treeMaker;
|
||||
private Names names;
|
||||
private Context javacContext;
|
||||
private Trees trees;
|
||||
|
||||
private AnnotationProcessorContext() { }
|
||||
|
||||
private static <T> T jbUnwrap(Class<? extends T> iface, T wrapper) {
|
||||
T unwrapped = null;
|
||||
try {
|
||||
final Class<?> apiWrappers = wrapper.getClass().getClassLoader().loadClass("org.jetbrains.jps.javac.APIWrappers");
|
||||
final Method unwrapMethod = apiWrappers.getDeclaredMethod("unwrap", Class.class, Object.class);
|
||||
unwrapped = iface.cast(unwrapMethod.invoke(null, iface, wrapper));
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
return unwrapped != null ? unwrapped : wrapper;
|
||||
}
|
||||
|
||||
public static AnnotationProcessorContext fromProcessingEnvironment(ProcessingEnvironment processingEnv) {
|
||||
AnnotationProcessorContext apContext = new AnnotationProcessorContext();
|
||||
|
||||
Object procEnvToUnwrap = processingEnv.getClass() == JavacProcessingEnvironment.class ?
|
||||
processingEnv : jbUnwrap(JavacProcessingEnvironment.class, processingEnv);
|
||||
|
||||
JavacProcessingEnvironment jcProcessingEnvironment = (JavacProcessingEnvironment) procEnvToUnwrap;
|
||||
|
||||
Context context = jcProcessingEnvironment.getContext();
|
||||
|
||||
apContext.javacProcessingEnvironment = jcProcessingEnvironment;
|
||||
|
||||
apContext.javacContext = context;
|
||||
apContext.javacTrees = JavacTrees.instance(jcProcessingEnvironment);
|
||||
apContext.treeMaker = TreeMaker.instance(context);
|
||||
apContext.names = Names.instance(context);
|
||||
|
||||
apContext.trees = Trees.instance(jcProcessingEnvironment);
|
||||
|
||||
return apContext;
|
||||
}
|
||||
|
||||
// Auto-generated methods.
|
||||
|
||||
public JavacTrees getJavacTrees() {
|
||||
return javacTrees;
|
||||
}
|
||||
|
||||
public TreeMaker getTreeMaker() {
|
||||
return treeMaker;
|
||||
}
|
||||
|
||||
public Names getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
public Context getJavacContext() {
|
||||
return javacContext;
|
||||
}
|
||||
|
||||
public Trees getTrees() {
|
||||
return trees;
|
||||
}
|
||||
|
||||
public JavacProcessingEnvironment getJavacProcessingEnvironment() {
|
||||
return javacProcessingEnvironment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
AnnotationProcessorContext context = (AnnotationProcessorContext) o;
|
||||
|
||||
if (!Objects.equals(javacTrees, context.javacTrees)) return false;
|
||||
if (!Objects.equals(treeMaker, context.treeMaker)) return false;
|
||||
if (!Objects.equals(names, context.names)) return false;
|
||||
if (!Objects.equals(javacContext, context.javacContext))
|
||||
return false;
|
||||
return Objects.equals(trees, context.trees);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = javacTrees != null ? javacTrees.hashCode() : 0;
|
||||
result = 31 * result + (treeMaker != null ? treeMaker.hashCode() : 0);
|
||||
result = 31 * result + (names != null ? names.hashCode() : 0);
|
||||
result = 31 * result + (javacContext != null ? javacContext.hashCode() : 0);
|
||||
result = 31 * result + (trees != null ? trees.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AnnotationProcessorContext{" +
|
||||
"javacTrees=" + javacTrees +
|
||||
", treeMaker=" + treeMaker +
|
||||
", names=" + names +
|
||||
", javacContext=" + javacContext +
|
||||
", trees=" + trees +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation;
|
||||
|
||||
import org.apache.dubbo.annotation.permit.Permit;
|
||||
import org.apache.dubbo.annotation.util.FileUtils;
|
||||
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.processing.JavacRoundEnvironment;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Dispatching annotation processor, which uses a file to locate handlers and invoke them.
|
||||
*/
|
||||
@SupportedAnnotationTypes("*")
|
||||
public class DispatchingAnnotationProcessor extends AbstractProcessor {
|
||||
|
||||
private static Set<AnnotationProcessingHandler> handlers;
|
||||
|
||||
private static Set<AnnotationProcessingHandler> loadHandlers() {
|
||||
List<String> classNames = FileUtils.loadConfigurationFileInResources("handlers.cfg");
|
||||
Set<AnnotationProcessingHandler> tempHandlers = new HashSet<>();
|
||||
|
||||
for (String clsName : classNames) {
|
||||
try {
|
||||
Class<? extends AnnotationProcessingHandler> cls = (Class<? extends AnnotationProcessingHandler>) Class.forName(clsName);
|
||||
AnnotationProcessingHandler r = cls.getConstructor().newInstance();
|
||||
|
||||
tempHandlers.add(r);
|
||||
|
||||
} catch (InstantiationException | NoSuchMethodException | InvocationTargetException |
|
||||
IllegalAccessException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(tempHandlers);
|
||||
}
|
||||
|
||||
private AnnotationProcessorContext apContext;
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
Permit.addOpens();
|
||||
super.init(processingEnv);
|
||||
|
||||
if (processingEnv.getClass().getName().startsWith("org.eclipse.jdt.")) {
|
||||
// Don't run on ECJ, since this processor is javac based.
|
||||
processingEnv
|
||||
.getMessager()
|
||||
.printMessage(Diagnostic.Kind.WARNING, "The Annotation processor doesn't support ECJ.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (handlers == null) {
|
||||
handlers = loadHandlers();
|
||||
}
|
||||
|
||||
apContext = AnnotationProcessorContext.fromProcessingEnvironment(processingEnv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
|
||||
if (processingEnv.getClass().getName().startsWith("org.eclipse.jdt.")) {
|
||||
// Don't run on ECJ, since this processor is javac based.
|
||||
return false;
|
||||
}
|
||||
|
||||
for (AnnotationProcessingHandler i : handlers) {
|
||||
Set<Element> elements = new HashSet<>(16);
|
||||
|
||||
for (Class<? extends Annotation> annotationClass : i.getAnnotationsToHandle()) {
|
||||
elements.addAll(getElementsAnnotatedWith(annotationClass, roundEnv));
|
||||
}
|
||||
|
||||
i.process(elements, apContext);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A hack to make comment only .java file pass the compilation by skipping package symbol scan.
|
||||
*
|
||||
* @param annotationClass the annotation class to find
|
||||
* @param roundEnvironment the javac's round environment
|
||||
* @return the elements annotated with specified annotation
|
||||
*/
|
||||
private Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> annotationClass, RoundEnvironment roundEnvironment) {
|
||||
|
||||
TypeElement a = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName());
|
||||
|
||||
// Detect the Javac's version.
|
||||
if (Integer.parseInt(SourceVersion.latest().name().split("_")[1]) > 8) {
|
||||
return roundEnvironment.getElementsAnnotatedWith(a);
|
||||
}
|
||||
|
||||
Set<Element> result = Collections.emptySet();
|
||||
|
||||
try {
|
||||
Class annotationSetScannerClass = Class.forName("com.sun.tools.javac.processing.JavacRoundEnvironment$AnnotationSetScanner");
|
||||
Constructor scannerConstructor = Permit.getConstructor(annotationSetScannerClass, JavacRoundEnvironment.class, Set.class);
|
||||
Object scanner = scannerConstructor.newInstance(roundEnvironment, result);
|
||||
|
||||
Set<? extends Element> rootElements1 = roundEnvironment
|
||||
.getRootElements()
|
||||
.stream()
|
||||
.filter(x -> x.getClass() != Symbol.PackageSymbol.class)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
for (Element element : rootElements1) {
|
||||
Method scanningMethod = Permit.getMethod(annotationSetScannerClass, "scan", Element.class, TypeElement.class);
|
||||
result = (Set<Element>) scanningMethod.invoke(scanner, element, a);
|
||||
}
|
||||
|
||||
} catch (InstantiationException | NoSuchMethodException | ClassNotFoundException | InvocationTargetException |
|
||||
IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latestSupported();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation.handler;
|
||||
|
||||
import org.apache.dubbo.annotation.AnnotationProcessingHandler;
|
||||
import org.apache.dubbo.annotation.AnnotationProcessorContext;
|
||||
import org.apache.dubbo.annotation.util.ASTUtils;
|
||||
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.TreeTranslator;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Handles @Deprecated annotation and adds logger warn call to the methods that are annotated with it.
|
||||
*/
|
||||
public class DeprecatedHandler implements AnnotationProcessingHandler {
|
||||
|
||||
@Override
|
||||
public Set<Class<? extends Annotation>> getAnnotationsToHandle() {
|
||||
return new HashSet<>(
|
||||
Collections.singletonList(Deprecated.class)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(Set<Element> elements, AnnotationProcessorContext apContext) {
|
||||
for (Element element : elements) {
|
||||
// Only interested in methods.
|
||||
if (!(element instanceof Symbol.MethodSymbol)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Symbol.ClassSymbol classSymbol = (Symbol.ClassSymbol) element.getEnclosingElement();
|
||||
|
||||
ASTUtils.addImportStatement(apContext, classSymbol, "org.apache.dubbo.common", "DeprecatedMethodInvocationCounter");
|
||||
|
||||
JCTree methodTree = apContext.getJavacTrees().getTree(element);
|
||||
|
||||
methodTree.accept(new TreeTranslator() {
|
||||
@Override
|
||||
public void visitMethodDef(JCTree.JCMethodDecl jcMethodDecl) {
|
||||
|
||||
JCTree.JCBlock block = jcMethodDecl.body;
|
||||
|
||||
if (block == null) {
|
||||
// No method body. (i.e. interface method declaration.)
|
||||
return;
|
||||
}
|
||||
|
||||
ASTUtils.insertStatementToHeadOfMethod(block, jcMethodDecl, generateCounterStatement(apContext, classSymbol, jcMethodDecl));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an expression statement like this:
|
||||
* <code>DeprecatedMethodInvocationCounter.onDeprecatedMethodCalled("....");
|
||||
*
|
||||
* @param originalMethodDecl the method declaration that will add logger statement
|
||||
* @param apContext annotation processor context
|
||||
* @param classSymbol the enclosing class that will be the logger's name
|
||||
* @return generated expression statement
|
||||
*/
|
||||
private JCTree.JCExpressionStatement generateCounterStatement(AnnotationProcessorContext apContext,
|
||||
Symbol.ClassSymbol classSymbol,
|
||||
JCTree.JCMethodDecl originalMethodDecl) {
|
||||
|
||||
JCTree.JCExpression fullStatement = apContext.getTreeMaker().Apply(
|
||||
com.sun.tools.javac.util.List.nil(),
|
||||
|
||||
apContext.getTreeMaker().Select(
|
||||
apContext.getTreeMaker().Ident(apContext.getNames().fromString("DeprecatedMethodInvocationCounter")),
|
||||
apContext.getNames().fromString("onDeprecatedMethodCalled")
|
||||
),
|
||||
|
||||
com.sun.tools.javac.util.List.of(
|
||||
apContext.getTreeMaker().Literal(getMethodDefinition(classSymbol, originalMethodDecl))
|
||||
)
|
||||
);
|
||||
|
||||
return apContext.getTreeMaker().Exec(fullStatement);
|
||||
}
|
||||
|
||||
private String getMethodDefinition(Symbol.ClassSymbol classSymbol, JCTree.JCMethodDecl originalMethodDecl) {
|
||||
return classSymbol.getQualifiedName() + "."
|
||||
+ originalMethodDecl.name.toString() + "(" + originalMethodDecl.params.toString() + ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
* Authored by Project Lombok and licensed by MIT License, which is attached below:
|
||||
*
|
||||
* Copyright (C) 2018-2021 The Project Lombok Authors.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation.permit;
|
||||
|
||||
import org.apache.dubbo.annotation.permit.dummy.Parent;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
// sunapi suppresses javac's warning about using Unsafe; 'all' suppresses eclipse's warning about the unspecified 'sunapi' key. Leave them both.
|
||||
// Yes, javac's definition of the word 'all' is quite contrary to what the dictionary says it means. 'all' does NOT include 'sunapi' according to javac.
|
||||
@SuppressWarnings({"sunapi", "all"})
|
||||
public class Permit {
|
||||
private Permit() {
|
||||
}
|
||||
|
||||
|
||||
private static final long ACCESSIBLE_OVERRIDE_FIELD_OFFSET;
|
||||
private static final IllegalAccessException INIT_ERROR;
|
||||
private static final sun.misc.Unsafe UNSAFE = (sun.misc.Unsafe) reflectiveStaticFieldAccess(sun.misc.Unsafe.class, "theUnsafe");
|
||||
|
||||
static {
|
||||
Field f;
|
||||
long g;
|
||||
Throwable ex;
|
||||
|
||||
try {
|
||||
g = getOverrideFieldOffset();
|
||||
ex = null;
|
||||
} catch (Throwable t) {
|
||||
f = null;
|
||||
g = -1L;
|
||||
ex = t;
|
||||
}
|
||||
|
||||
ACCESSIBLE_OVERRIDE_FIELD_OFFSET = g;
|
||||
if (ex == null) INIT_ERROR = null;
|
||||
else if (ex instanceof IllegalAccessException) INIT_ERROR = (IllegalAccessException) ex;
|
||||
else {
|
||||
INIT_ERROR = new IllegalAccessException("Cannot initialize Unsafe-based permit");
|
||||
INIT_ERROR.initCause(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends AccessibleObject> T setAccessible(T accessor) {
|
||||
if (INIT_ERROR == null) {
|
||||
UNSAFE.putBoolean(accessor, ACCESSIBLE_OVERRIDE_FIELD_OFFSET, true);
|
||||
} else {
|
||||
accessor.setAccessible(true);
|
||||
}
|
||||
|
||||
return accessor;
|
||||
}
|
||||
|
||||
private static long getOverrideFieldOffset() throws Throwable {
|
||||
Field f = null;
|
||||
Throwable saved = null;
|
||||
try {
|
||||
f = AccessibleObject.class.getDeclaredField("override");
|
||||
} catch (Throwable t) {
|
||||
saved = t;
|
||||
}
|
||||
|
||||
if (f != null) {
|
||||
return UNSAFE.objectFieldOffset(f);
|
||||
}
|
||||
// The below seems very risky, but for all AccessibleObjects in java today it does work, and starting with JDK12, making the field accessible is no longer possible.
|
||||
try {
|
||||
return UNSAFE.objectFieldOffset(Fake.class.getDeclaredField("override"));
|
||||
} catch (Throwable t) {
|
||||
throw saved;
|
||||
}
|
||||
}
|
||||
|
||||
static class Fake {
|
||||
boolean override;
|
||||
Object accessCheckCache;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> c, String mName, Class<?>... parameterTypes) throws NoSuchMethodException {
|
||||
Method m = null;
|
||||
Class<?> oc = c;
|
||||
while (c != null) {
|
||||
try {
|
||||
m = c.getDeclaredMethod(mName, parameterTypes);
|
||||
break;
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
c = c.getSuperclass();
|
||||
}
|
||||
|
||||
if (m == null) throw new NoSuchMethodException(oc.getName() + " :: " + mName + "(args)");
|
||||
return setAccessible(m);
|
||||
}
|
||||
|
||||
public static Method permissiveGetMethod(Class<?> c, String mName, Class<?>... parameterTypes) {
|
||||
try {
|
||||
return getMethod(c, mName, parameterTypes);
|
||||
} catch (Exception ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Field getField(Class<?> c, String fName) throws NoSuchFieldException {
|
||||
Field f = null;
|
||||
Class<?> oc = c;
|
||||
while (c != null) {
|
||||
try {
|
||||
f = c.getDeclaredField(fName);
|
||||
break;
|
||||
} catch (NoSuchFieldException e) {
|
||||
}
|
||||
c = c.getSuperclass();
|
||||
}
|
||||
|
||||
if (f == null) throw new NoSuchFieldException(oc.getName() + " :: " + fName);
|
||||
|
||||
return setAccessible(f);
|
||||
}
|
||||
|
||||
public static Field permissiveGetField(Class<?> c, String fName) {
|
||||
try {
|
||||
return getField(c, fName);
|
||||
} catch (Exception ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T permissiveReadField(Class<T> type, Field f, Object instance) {
|
||||
try {
|
||||
return type.cast(f.get(instance));
|
||||
} catch (Exception ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Constructor<T> getConstructor(Class<T> c, Class<?>... parameterTypes) throws NoSuchMethodException {
|
||||
return setAccessible(c.getDeclaredConstructor(parameterTypes));
|
||||
}
|
||||
|
||||
private static Object reflectiveStaticFieldAccess(Class<?> c, String fName) {
|
||||
try {
|
||||
Field f = c.getDeclaredField(fName);
|
||||
f.setAccessible(true);
|
||||
return f.get(null);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDebugReflection() {
|
||||
return !"false".equals(System.getProperty("lombok.debug.reflection", "false"));
|
||||
}
|
||||
|
||||
public static void handleReflectionDebug(Throwable t, Throwable initError) {
|
||||
if (!isDebugReflection()) return;
|
||||
|
||||
System.err.println("** LOMBOK REFLECTION exception: " + t.getClass() + ": " + (t.getMessage() == null ? "(no message)" : t.getMessage()));
|
||||
t.printStackTrace(System.err);
|
||||
if (initError != null) {
|
||||
System.err.println("*** ADDITIONALLY, exception occurred setting up reflection: ");
|
||||
initError.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object invoke(Method m, Object receiver, Object... args) throws IllegalAccessException, InvocationTargetException {
|
||||
return invoke(null, m, receiver, args);
|
||||
}
|
||||
|
||||
public static Object invoke(Throwable initError, Method m, Object receiver, Object... args) throws IllegalAccessException, InvocationTargetException {
|
||||
try {
|
||||
return m.invoke(receiver, args);
|
||||
} catch (IllegalAccessException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object invokeSneaky(Method m, Object receiver, Object... args) {
|
||||
return invokeSneaky(null, m, receiver, args);
|
||||
}
|
||||
|
||||
public static Object invokeSneaky(Throwable initError, Method m, Object receiver, Object... args) {
|
||||
try {
|
||||
return m.invoke(receiver, args);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
|
||||
//do anything useful here.
|
||||
return null;
|
||||
} catch (NullPointerException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
|
||||
//do anything useful here.
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw sneakyThrow(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw sneakyThrow(e.getCause());
|
||||
} catch (RuntimeException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T newInstance(Constructor<T> c, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
return newInstance(null, c, args);
|
||||
}
|
||||
|
||||
public static <T> T newInstance(Throwable initError, Constructor<T> c, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
try {
|
||||
return c.newInstance(args);
|
||||
} catch (IllegalAccessException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
} catch (InstantiationException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T newInstanceSneaky(Constructor<T> c, Object... args) {
|
||||
return newInstanceSneaky(null, c, args);
|
||||
}
|
||||
|
||||
public static <T> T newInstanceSneaky(Throwable initError, Constructor<T> c, Object... args) {
|
||||
try {
|
||||
return c.newInstance(args);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
|
||||
//do anything useful here.
|
||||
return null;
|
||||
} catch (NullPointerException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
|
||||
//do anything useful here.
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw sneakyThrow(e);
|
||||
} catch (InstantiationException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw sneakyThrow(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw sneakyThrow(e.getCause());
|
||||
} catch (RuntimeException e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
handleReflectionDebug(e, initError);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object get(Field f, Object receiver) throws IllegalAccessException {
|
||||
try {
|
||||
return f.get(receiver);
|
||||
} catch (IllegalAccessException e) {
|
||||
handleReflectionDebug(e, null);
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
handleReflectionDebug(e, null);
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
handleReflectionDebug(e, null);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void set(Field f, Object receiver, Object newValue) throws IllegalAccessException {
|
||||
try {
|
||||
f.set(receiver, newValue);
|
||||
} catch (IllegalAccessException e) {
|
||||
handleReflectionDebug(e, null);
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
handleReflectionDebug(e, null);
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
handleReflectionDebug(e, null);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void reportReflectionProblem(Throwable initError, String msg) {
|
||||
if (!isDebugReflection()) return;
|
||||
System.err.println("** LOMBOK REFLECTION issue: " + msg);
|
||||
if (initError != null) {
|
||||
System.err.println("*** ADDITIONALLY, exception occurred setting up reflection: ");
|
||||
initError.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
public static RuntimeException sneakyThrow(Throwable t) {
|
||||
if (t == null) throw new NullPointerException("t");
|
||||
return Permit.<RuntimeException>sneakyThrow0(t);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T {
|
||||
throw (T) t;
|
||||
}
|
||||
|
||||
private static Object getJdkCompilerModule() {
|
||||
/* call public api: ModuleLayer.boot().findModule("jdk.compiler").get();
|
||||
but use reflection because we don't want this code to crash on jdk1.7 and below.
|
||||
In that case, none of this stuff was needed in the first place, so we just exit via
|
||||
the catch block and do nothing.
|
||||
*/
|
||||
|
||||
try {
|
||||
Class<?> cModuleLayer = Class.forName("java.lang.ModuleLayer");
|
||||
Method mBoot = cModuleLayer.getDeclaredMethod("boot");
|
||||
Object bootLayer = mBoot.invoke(null);
|
||||
Class<?> cOptional = Class.forName("java.util.Optional");
|
||||
Method mFindModule = cModuleLayer.getDeclaredMethod("findModule", String.class);
|
||||
Object oCompilerO = mFindModule.invoke(bootLayer, "jdk.compiler");
|
||||
return cOptional.getDeclaredMethod("get").invoke(oCompilerO);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getOwnModule() {
|
||||
try {
|
||||
Method m = Permit.getMethod(Class.class, "getModule");
|
||||
return m.invoke(Permit.class);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static long getFirstFieldOffset(Unsafe unsafe) {
|
||||
try {
|
||||
return unsafe.objectFieldOffset(Parent.class.getDeclaredField("first"));
|
||||
} catch (NoSuchFieldException e) {
|
||||
// can't happen.
|
||||
throw new RuntimeException(e);
|
||||
} catch (SecurityException e) {
|
||||
// can't happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addOpens() {
|
||||
Class<?> cModule;
|
||||
try {
|
||||
cModule = Class.forName("java.lang.Module");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return; //jdk8-; this is not needed.
|
||||
}
|
||||
|
||||
Unsafe unsafe = UNSAFE;
|
||||
|
||||
Object jdkCompilerModule = getJdkCompilerModule();
|
||||
Object ownModule = getOwnModule();
|
||||
String[] allPkgs = {
|
||||
"com.sun.tools.javac.code",
|
||||
"com.sun.tools.javac.comp",
|
||||
"com.sun.tools.javac.file",
|
||||
"com.sun.tools.javac.main",
|
||||
"com.sun.tools.javac.model",
|
||||
"com.sun.tools.javac.parser",
|
||||
"com.sun.tools.javac.processing",
|
||||
"com.sun.tools.javac.tree",
|
||||
"com.sun.tools.javac.util",
|
||||
"com.sun.tools.javac.jvm",
|
||||
"com.sun.tools.javac.api"
|
||||
};
|
||||
|
||||
try {
|
||||
Method m = cModule.getDeclaredMethod("implAddOpens", String.class, cModule);
|
||||
long firstFieldOffset = getFirstFieldOffset(unsafe);
|
||||
unsafe.putBooleanVolatile(m, firstFieldOffset, true);
|
||||
for (String p : allPkgs) m.invoke(jdkCompilerModule, p, ownModule);
|
||||
} catch (Exception ignore) {}
|
||||
|
||||
try {
|
||||
Method m = cModule.getDeclaredMethod("implAddExports", String.class, cModule);
|
||||
long firstFieldOffset = getFirstFieldOffset(unsafe);
|
||||
unsafe.putBooleanVolatile(m, firstFieldOffset, true);
|
||||
for (String p : allPkgs) m.invoke(jdkCompilerModule, p, ownModule);
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Authored by Project Lombok and licensed by MIT License, which is attached below:
|
||||
*
|
||||
* Copyright (C) 2018-2021 The Project Lombok Authors.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation.permit.dummy;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public abstract class Child extends Parent {
|
||||
private transient volatile boolean foo;
|
||||
private transient volatile Object[] bar;
|
||||
private transient volatile Object baz;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Authored by Project Lombok and licensed by MIT License, which is attached below:
|
||||
*
|
||||
* Copyright (C) 2018-2021 The Project Lombok Authors.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation.permit.dummy;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public final class GrandChild extends Child {
|
||||
private Class<?> a;
|
||||
private int b;
|
||||
private String c;
|
||||
private Class<?> d;
|
||||
private Class<?>[] e;
|
||||
private Class<?>[] f;
|
||||
private int g;
|
||||
private transient String h;
|
||||
private transient Object i;
|
||||
private byte[] j;
|
||||
private byte[] k;
|
||||
private byte[] l;
|
||||
private volatile Object m;
|
||||
private Object n;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Authored by Project Lombok and licensed by MIT License, which is attached below:
|
||||
*
|
||||
* Copyright (C) 2018-2021 The Project Lombok Authors.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation.permit.dummy;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class Parent {
|
||||
boolean first;
|
||||
static final Object staticObj = OutputStream.class;
|
||||
volatile Object second;
|
||||
private static volatile boolean staticSecond;
|
||||
private static volatile boolean staticThird;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Authored by Project Lombok and licensed by MIT License, which is attached below:
|
||||
*
|
||||
* Copyright (C) 2018-2021 The Project Lombok Authors.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package recreates the type hierarchy of {@code java.lang.reflect.AccessibleObject} and friends (such as {@code java.lang.reflect.Method});
|
||||
* its purpose is to allow us to ask {@code sun.misc.internal.Unsafe} about the exact offset of the {@code override} field of {@code AccessibleObject};
|
||||
* asking about that field directly doesn't work after jdk14, presumably because the fields of AO are expressly hidden somehow.
|
||||
* <p>
|
||||
* NB: It's usually 12, on the vast majority of OS, VM, and architecture combos.
|
||||
*/
|
||||
package org.apache.dubbo.annotation.permit.dummy;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Authored by Project Lombok and licensed by MIT License, which is attached below:
|
||||
*
|
||||
* Copyright (C) 2018-2021 The Project Lombok Authors.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a reduced copy of the nqzero Permit-reflect project.
|
||||
* https://github.com/nqzero/permit-reflect
|
||||
* <p>
|
||||
* Many thanks to nqzero. The permit-reflect project is, like lombok itself, licensed under the MIT license.
|
||||
* See https://github.com/nqzero/permit-reflect/blob/master/License for license info.
|
||||
*/
|
||||
package org.apache.dubbo.annotation.permit;
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation.util;
|
||||
|
||||
import org.apache.dubbo.annotation.AnnotationProcessorContext;
|
||||
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Some utils about AST manipulating.
|
||||
*/
|
||||
public final class ASTUtils {
|
||||
|
||||
private ASTUtils() {
|
||||
throw new UnsupportedOperationException("No instance of 'ASTUtils' for you! ");
|
||||
}
|
||||
|
||||
public static void addImportStatement(AnnotationProcessorContext apContext,
|
||||
Symbol.ClassSymbol classSymbol,
|
||||
String packageName,
|
||||
String className) {
|
||||
|
||||
JCTree.JCImport jcImport = apContext.getTreeMaker().Import(
|
||||
apContext.getTreeMaker().Select(
|
||||
apContext.getTreeMaker().Ident(apContext.getNames().fromString(packageName)),
|
||||
apContext.getNames().fromString(className)
|
||||
), false);
|
||||
|
||||
TreePath treePath = apContext.getTrees().getPath(classSymbol);
|
||||
TreePath parentPath = treePath.getParentPath();
|
||||
JCTree.JCCompilationUnit compilationUnit = (JCTree.JCCompilationUnit) parentPath.getCompilationUnit();
|
||||
|
||||
List<JCTree.JCImport> imports = compilationUnit.getImports();
|
||||
if (imports.stream().noneMatch(x -> x.qualid.toString().contains(packageName + "." + className))) {
|
||||
|
||||
compilationUnit.accept(new JCTree.Visitor() {
|
||||
@Override
|
||||
public void visitTopLevel(JCTree.JCCompilationUnit that) {
|
||||
|
||||
List<JCTree> defs = compilationUnit.defs;
|
||||
|
||||
ListBuffer<JCTree> newDefs = new ListBuffer<>();
|
||||
|
||||
newDefs.add(defs.get(0));
|
||||
newDefs.add(jcImport);
|
||||
newDefs.addAll(defs.subList(1, defs.size()));
|
||||
|
||||
compilationUnit.defs = newDefs.toList();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert statement to head of the method.
|
||||
*
|
||||
* @param block the method body
|
||||
* @param originalMethodDecl the method declaration that will add logger statement
|
||||
* @param fullExpressionStatement the statement to insert.
|
||||
*/
|
||||
public static void insertStatementToHeadOfMethod(JCTree.JCBlock block,
|
||||
JCTree.JCMethodDecl originalMethodDecl,
|
||||
JCTree.JCStatement fullExpressionStatement) {
|
||||
|
||||
boolean isConstructor = originalMethodDecl.name.toString().equals("<init>");
|
||||
ListBuffer<JCTree.JCStatement> statements = new ListBuffer<>();
|
||||
|
||||
// In constructor, super(...) or this(...) should be the first statement.
|
||||
|
||||
if (isConstructor && !block.stats.isEmpty()) {
|
||||
|
||||
boolean startsWithSuper = block.stats.get(0).toString().startsWith("super(");
|
||||
boolean startsWithThis = block.stats.get(0).toString().startsWith("this(");
|
||||
|
||||
if (startsWithSuper || startsWithThis) {
|
||||
statements.add(block.stats.get(0));
|
||||
statements.add(fullExpressionStatement);
|
||||
statements.addAll(block.stats.subList(1, block.stats.size()));
|
||||
} else {
|
||||
statements.add(fullExpressionStatement);
|
||||
statements.addAll(block.stats);
|
||||
}
|
||||
|
||||
} else {
|
||||
statements.add(fullExpressionStatement);
|
||||
statements.addAll(block.stats);
|
||||
}
|
||||
|
||||
block.stats = statements.toList();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Utilities of iterating file.
|
||||
*/
|
||||
public final class FileUtils {
|
||||
|
||||
private static final Pattern WINDOWS_PATH_PATTERN = Pattern.compile("file:/\\w:/.*");
|
||||
|
||||
|
||||
private FileUtils() {
|
||||
throw new UnsupportedOperationException("No instance of FileUtils for you! ");
|
||||
}
|
||||
|
||||
public static List<Path> getAllClassFilePaths(String rootPath) {
|
||||
List<Path> targetFolders;
|
||||
|
||||
try (Stream<Path> filesStream = Files.walk(Paths.get(rootPath))) {
|
||||
targetFolders = filesStream.filter(x -> !x.toFile().isFile())
|
||||
.filter(x -> x.toString().contains("classes") && !x.toString().contains("test-classes"))
|
||||
.filter(x -> x.toString().contains("\\org\\apache\\dubbo".replace('\\', File.separatorChar)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return targetFolders;
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] openFileAsByteArray(String filePath) {
|
||||
try (FileChannel fileChannel = FileChannel.open(Paths.get(filePath))) {
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate((int) fileChannel.size());
|
||||
fileChannel.read(byteBuffer);
|
||||
|
||||
return byteBuffer.array();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String openFileAsString(String filePath) {
|
||||
return new String(openFileAsByteArray(filePath));
|
||||
}
|
||||
|
||||
public static String getSourceFilePathFromClassFilePath(String classFilePath) {
|
||||
|
||||
String classesPathString = "\\target\\classes\\".replace("\\", File.separator);
|
||||
String sourcesPathString = "\\src\\main\\java\\".replace("\\", File.separator);
|
||||
|
||||
String sourceFilePathByReplace = classFilePath.replace(classesPathString, sourcesPathString)
|
||||
.replace(".class", ".java");
|
||||
|
||||
// Inner classes.
|
||||
if (sourceFilePathByReplace.lastIndexOf('$') != -1) {
|
||||
int dollarCharIndex = sourceFilePathByReplace.lastIndexOf('$');
|
||||
String outerClassPath = sourceFilePathByReplace.substring(0, dollarCharIndex);
|
||||
|
||||
return outerClassPath + ".java";
|
||||
}
|
||||
|
||||
return sourceFilePathByReplace;
|
||||
}
|
||||
|
||||
public static List<String> loadConfigurationFileInResources(String path) {
|
||||
|
||||
ReadableByteChannel resourceReadableByteChannel = Channels.newChannel(
|
||||
Objects.requireNonNull(FileUtils.class.getClassLoader().getResourceAsStream(path)));
|
||||
|
||||
List<String> lines = new ArrayList<>();
|
||||
|
||||
try (Scanner scanner = new Scanner(resourceReadableByteChannel)) {
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine().trim();
|
||||
|
||||
if (!line.startsWith("#") && !line.isEmpty()) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Get absolute path of resource.
|
||||
*
|
||||
* <p>Retained for testing. It won't work in JAR.
|
||||
*
|
||||
* @param path relative path of resources folder.
|
||||
* @return absolute path of resource
|
||||
*/
|
||||
public static String getResourceFilePath(String path) {
|
||||
String resourceFilePath = FileUtils.class.getClassLoader().getResource(path).toString();
|
||||
|
||||
if (WINDOWS_PATH_PATTERN.matcher(resourceFilePath).matches()) {
|
||||
resourceFilePath = resourceFilePath.replace("file:/", "");
|
||||
} else {
|
||||
resourceFilePath = resourceFilePath.replace("file:", "");
|
||||
}
|
||||
|
||||
return resourceFilePath;
|
||||
}
|
||||
|
||||
public static List<Path> getAllFilesInDirectory(Path targetFolder) {
|
||||
|
||||
try (Stream<Path> classFilesStream = Files.walk(targetFolder)) {
|
||||
|
||||
return classFilesStream
|
||||
.filter(x -> x.toFile().isFile())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} catch (IOException e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
org.apache.dubbo.annotation.DispatchingAnnotationProcessor
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
org.apache.dubbo.annotation.handler.DeprecatedHandler
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation;
|
||||
|
||||
import org.apache.dubbo.annotation.util.FileUtils;
|
||||
import org.apache.dubbo.eci.extractor.JavassistUtils;
|
||||
|
||||
import javassist.bytecode.ClassFile;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Real invocation test of DispatchingAnnotationProcessor (and DeprecatedHandler).
|
||||
*/
|
||||
class RealInvocationTest {
|
||||
|
||||
/**
|
||||
* [File name, Should the counter exist in the class file? ]
|
||||
*/
|
||||
private static final Map<String, Boolean> FILES = new HashMap<>(5, 1);
|
||||
|
||||
static {
|
||||
FILES.put("TestConstructorMethod.java", true);
|
||||
FILES.put("TestDeprecatedMethod.java", true);
|
||||
FILES.put("TestInterfaceDeprecatedMethod.java", false);
|
||||
FILES.put("TestConstructorMethodParentClass.java", false);
|
||||
FILES.put("TestConstructorMethodSubClass.java", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
|
||||
for (Map.Entry<String, Boolean> i : FILES.entrySet()) {
|
||||
String filePath = FileUtils.getResourceFilePath("org/testing/dm/" + i.getKey());
|
||||
|
||||
Assertions.assertTrue(TestingCommons.compileTheSource(filePath), "Compile failed! ");
|
||||
|
||||
String classFilePath = filePath.replace(".java", ".class");
|
||||
ClassFile classFile = JavassistUtils.openClassFile(classFilePath);
|
||||
List<String> stringItems = JavassistUtils.getConstPoolStringItems(classFile.getConstPool());
|
||||
|
||||
Assertions.assertEquals(i.getValue(), stringItems.contains("org/apache/dubbo/common/DeprecatedMethodInvocationCounter"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.annotation;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* Common code of annotation processor testing.
|
||||
*/
|
||||
public final class TestingCommons {
|
||||
private TestingCommons() {
|
||||
throw new UnsupportedOperationException("No instance of TestingCommons for you! ");
|
||||
}
|
||||
|
||||
private static class ObjectHolders {
|
||||
static final JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
static final StandardJavaFileManager javaFileManager = javaCompiler.getStandardFileManager(
|
||||
null,
|
||||
Locale.ROOT,
|
||||
StandardCharsets.UTF_8
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean compileTheSource(String filePath) {
|
||||
|
||||
|
||||
JavaCompiler.CompilationTask compilationTask = ObjectHolders.javaCompiler.getTask(
|
||||
null,
|
||||
ObjectHolders.javaFileManager,
|
||||
null,
|
||||
asList("-parameters", "-Xlint:unchecked", "-nowarn", "-Xlint:deprecation"),
|
||||
null,
|
||||
getSourceFileJavaFileObject(filePath)
|
||||
);
|
||||
|
||||
compilationTask.setProcessors(
|
||||
Collections.singletonList(new DispatchingAnnotationProcessor())
|
||||
);
|
||||
|
||||
return compilationTask.call();
|
||||
}
|
||||
|
||||
private static Iterable<? extends JavaFileObject> getSourceFileJavaFileObject(String filePath) {
|
||||
|
||||
return ObjectHolders.javaFileManager.getJavaFileObjects(filePath);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,24 +14,23 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.context.annotation.provider;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.apache.dubbo.config.spring.api.HelloService;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
package org.apache.dubbo.common;
|
||||
|
||||
/**
|
||||
* Default {@link HelloService} annotation with Spring's {@link Service}
|
||||
* and Dubbo's {@link org.apache.dubbo.config.annotation.Service}
|
||||
*
|
||||
* Reduced mock of Deprecated method invocation counter.
|
||||
*/
|
||||
@Service
|
||||
@DubboService
|
||||
public class DefaultHelloService implements HelloService {
|
||||
public final class DeprecatedMethodInvocationCounter {
|
||||
private DeprecatedMethodInvocationCounter() {
|
||||
throw new UnsupportedOperationException("No instance of DeprecatedMethodInvocationCounter for you! ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sayHello(String name) {
|
||||
return "Greeting, " + name;
|
||||
/**
|
||||
* Invoked by (modified) deprecated method.
|
||||
*
|
||||
* @param methodDefinition filled by annotation processor. (like 'org.apache.dubbo.common.URL.getServiceName()')
|
||||
*/
|
||||
public static void onDeprecatedMethodCalled(String methodDefinition) {
|
||||
// Intended to be empty.
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.eci.extractor;
|
||||
|
||||
import org.apache.dubbo.annotation.util.FileUtils;
|
||||
|
||||
import javassist.bytecode.ClassFile;
|
||||
import javassist.bytecode.ConstPool;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utilities of Javassist.
|
||||
*/
|
||||
public class JavassistUtils {
|
||||
private static final Map<Class, Field> stringFieldCache = new HashMap<>(2, 1);
|
||||
|
||||
private static Method getItemMethodCache = null;
|
||||
|
||||
private JavassistUtils() {
|
||||
throw new UnsupportedOperationException("No instance of JavassistUtils for you! ");
|
||||
}
|
||||
|
||||
public static ClassFile openClassFile(String classFilePath) {
|
||||
try {
|
||||
byte[] clsB = FileUtils.openFileAsByteArray(classFilePath);
|
||||
return new ClassFile(new DataInputStream(new ByteArrayInputStream(clsB)));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static List<Object> getConstPoolItems(ConstPool cp) {
|
||||
List<Object> objects = new ArrayList<>(cp.getSize());
|
||||
|
||||
for (int i = 0; i < cp.getSize(); i++) {
|
||||
objects.add(getConstPoolItem(cp, i));
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls ConstPool.getItem() method reflectively.
|
||||
*
|
||||
* @param cp The ConstPool object.
|
||||
* @param index The index of items.
|
||||
* @return The XXXInfo Object. Since it's invisible, return Object instead.
|
||||
*/
|
||||
static Object getConstPoolItem(ConstPool cp, int index) {
|
||||
|
||||
if (getItemMethodCache == null) {
|
||||
Class<ConstPool> cpc = ConstPool.class;
|
||||
Method getItemMethod;
|
||||
try {
|
||||
getItemMethod = cpc.getDeclaredMethod("getItem", int.class);
|
||||
getItemMethod.setAccessible(true);
|
||||
|
||||
getItemMethodCache = getItemMethod;
|
||||
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("Javassist internal method changed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return getItemMethodCache.invoke(cp, index);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException("Javassist internal method changed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getConstPoolStringItems(ConstPool cp) {
|
||||
List<Object> objects = getConstPoolItems(cp);
|
||||
List<String> stringItems = new ArrayList<>(cp.getSize());
|
||||
|
||||
for (Object item : objects) {
|
||||
|
||||
Field stringField;
|
||||
|
||||
if (item != null) {
|
||||
stringField = getStringFieldInConstPoolItems(item);
|
||||
|
||||
if (stringField == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object fieldData;
|
||||
|
||||
try {
|
||||
fieldData = stringField.get(item);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Javassist internal field changed.", e);
|
||||
}
|
||||
|
||||
if (fieldData.getClass() == String.class) {
|
||||
stringItems.add((String) fieldData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stringItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the 'string' field in Utf8Info and StringInfo.
|
||||
*
|
||||
* @param item The instance of Utf8Info and StringInfo.
|
||||
* @return 'string' field's value
|
||||
*/
|
||||
static Field getStringFieldInConstPoolItems(Object item) {
|
||||
if (stringFieldCache.containsKey(item.getClass())) {
|
||||
return stringFieldCache.get(item.getClass());
|
||||
} else {
|
||||
try {
|
||||
Field stringField = item.getClass().getDeclaredField("string");
|
||||
stringField.setAccessible(true);
|
||||
stringFieldCache.put(item.getClass(), stringField);
|
||||
|
||||
return stringField;
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.eci.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Tools of reflective operations.
|
||||
*/
|
||||
public final class ReflectUtils {
|
||||
private ReflectUtils() {
|
||||
throw new UnsupportedOperationException("No instance of ReflectUtils for you! ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches (a private) field in super classes recursively.
|
||||
*
|
||||
* @param cls the actual type
|
||||
* @param name the field name
|
||||
* @return the corresponding Field object, or null if the field does not exist.
|
||||
*/
|
||||
public static Field getDeclaredFieldRecursively(Class cls, String name) {
|
||||
try {
|
||||
Field indexField = cls.getDeclaredField(name);
|
||||
indexField.setAccessible(true);
|
||||
|
||||
return indexField;
|
||||
} catch (NoSuchFieldException e) {
|
||||
if (cls == Object.class) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getDeclaredFieldRecursively(cls.getSuperclass(), name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.testing.dm;
|
||||
|
||||
public class TestConstructorMethod {
|
||||
@Deprecated
|
||||
TestConstructorMethod() {
|
||||
this("1");
|
||||
}
|
||||
|
||||
TestConstructorMethod(String s) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.testing.dm;
|
||||
|
||||
public class TestConstructorMethodParentClass {
|
||||
|
||||
public TestConstructorMethodParentClass() {
|
||||
}
|
||||
|
||||
public TestConstructorMethodParentClass(String s) {
|
||||
}
|
||||
}
|
||||
|
|
@ -14,22 +14,17 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.metadata.tools;
|
||||
|
||||
import java.io.Serializable;
|
||||
package org.testing.dm;
|
||||
|
||||
/**
|
||||
* Ancestor
|
||||
*/
|
||||
public class Ancestor implements Serializable {
|
||||
public class TestConstructorMethodSubClass extends TestConstructorMethodParentClass {
|
||||
|
||||
private boolean z;
|
||||
|
||||
public boolean isZ() {
|
||||
return z;
|
||||
@Deprecated
|
||||
public TestConstructorMethodSubClass(int i) {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setZ(boolean z) {
|
||||
this.z = z;
|
||||
public TestConstructorMethodSubClass(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.testing.dm;
|
||||
|
||||
public class TestDeprecatedMethod {
|
||||
|
||||
@Deprecated
|
||||
public void m1() {
|
||||
System.out.println("M1! ");
|
||||
}
|
||||
}
|
||||
|
|
@ -14,8 +14,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.api;
|
||||
|
||||
public interface HelloService {
|
||||
String sayHello(String name);
|
||||
package org.testing.dm;
|
||||
|
||||
public interface TestInterfaceDeprecatedMethod {
|
||||
|
||||
@Deprecated
|
||||
public void m1();
|
||||
}
|
||||
|
|
@ -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:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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>
|
||||
|
||||
<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>
|
||||
<properties>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -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,77 @@
|
|||
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>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.config.AbstractInterfaceConfig;
|
||||
import org.apache.dubbo.config.MethodConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
import org.apache.dubbo.rpc.cluster.Cluster;
|
||||
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.FILTER_KEY;
|
||||
import static org.apache.dubbo.config.Constants.LAYER_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.PROXY_KEY;
|
||||
|
||||
@Activate
|
||||
public class InterfaceConfigValidator implements ConfigValidator<AbstractInterfaceConfig> {
|
||||
|
||||
public static void validateAbstractInterfaceConfig(AbstractInterfaceConfig config) {
|
||||
ConfigValidationUtils.checkName(LOCAL_KEY, config.getLocal());
|
||||
ConfigValidationUtils.checkName("stub", config.getStub());
|
||||
ConfigValidationUtils.checkMultiName("owner", config.getOwner());
|
||||
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), ProxyFactory.class, PROXY_KEY, config.getProxy());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Cluster.class, CLUSTER_KEY, config.getCluster());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), Arrays.asList(Filter.class, ClusterFilter.class), FILTER_KEY, config.getFilter());
|
||||
ConfigValidationUtils.checkNameHasSymbol(LAYER_KEY, config.getLayer());
|
||||
|
||||
List<MethodConfig> methods = config.getMethods();
|
||||
if (CollectionUtils.isNotEmpty(methods)) {
|
||||
methods.forEach(MethodConfig::validate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(AbstractInterfaceConfig config) {
|
||||
validateAbstractInterfaceConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return AbstractInterfaceConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.MethodConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
|
||||
import static org.apache.dubbo.rpc.Constants.FAIL_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.FORCE_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
|
||||
|
||||
@Activate
|
||||
public class MethodConfigValidator implements ConfigValidator<MethodConfig> {
|
||||
|
||||
public static void validateMethodConfig(MethodConfig config) {
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), LoadBalance.class, LOADBALANCE_KEY, config.getLoadbalance());
|
||||
ConfigValidationUtils.checkParameterName(config.getParameters());
|
||||
ConfigValidationUtils.checkMethodName("name", config.getName());
|
||||
|
||||
String mock = config.getMock();
|
||||
if (isNotEmpty(mock)) {
|
||||
if (mock.startsWith(RETURN_PREFIX) || mock.startsWith(THROW_PREFIX + " ")) {
|
||||
ConfigValidationUtils.checkLength(MOCK_KEY, mock);
|
||||
} else if (mock.startsWith(FAIL_PREFIX) || mock.startsWith(FORCE_PREFIX)) {
|
||||
ConfigValidationUtils.checkNameHasSymbol(MOCK_KEY, mock);
|
||||
} else {
|
||||
ConfigValidationUtils.checkName(MOCK_KEY, mock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(MethodConfig config) {
|
||||
validateMethodConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return MethodConfig.class.equals(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import org.apache.dubbo.rpc.RpcException;
|
|||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.DEFAULT_CLUSTER;
|
||||
|
||||
/**
|
||||
* Cluster. (SPI, Singleton, ThreadSafe)
|
||||
* <p>
|
||||
|
|
@ -31,11 +33,9 @@ import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
|||
* <a href="http://en.wikipedia.org/wiki/Fault-tolerant_system">Fault-Tolerant</a>
|
||||
*
|
||||
*/
|
||||
@SPI(Cluster.DEFAULT)
|
||||
@SPI(DEFAULT_CLUSTER)
|
||||
public interface Cluster {
|
||||
|
||||
String DEFAULT = "failover";
|
||||
|
||||
/**
|
||||
* Merge the directory invokers to a virtual invoker.
|
||||
*
|
||||
|
|
@ -53,10 +53,8 @@ public interface Cluster {
|
|||
|
||||
static Cluster getCluster(ScopeModel scopeModel, String name, boolean wrap) {
|
||||
if (StringUtils.isEmpty(name)) {
|
||||
name = Cluster.DEFAULT;
|
||||
name = DEFAULT_CLUSTER;
|
||||
}
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel)
|
||||
.getExtensionLoader(Cluster.class)
|
||||
.getExtension(name, wrap);
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel).getExtensionLoader(Cluster.class).getExtension(name, wrap);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,9 @@
|
|||
package org.apache.dubbo.rpc.cluster;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.rpc.AdaptiveMetrics;
|
||||
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
|
||||
import org.apache.dubbo.rpc.cluster.factory.DefaultClusterInvokerFactory;
|
||||
import org.apache.dubbo.rpc.cluster.factory.StaticDirectoryStrategy;
|
||||
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
|
||||
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
|
@ -28,23 +27,22 @@ import org.apache.dubbo.rpc.model.ModuleModel;
|
|||
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
|
||||
|
||||
public class ClusterScopeModelInitializer implements ScopeModelInitializer {
|
||||
|
||||
@Override
|
||||
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
|
||||
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
|
||||
beanFactory.registerBean(RouterSnapshotSwitcher.class);
|
||||
beanFactory.registerBean(StaticDirectoryStrategy.class);
|
||||
beanFactory.registerBean(DefaultClusterInvokerFactory.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeApplicationModel(ApplicationModel applicationModel) {
|
||||
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
|
||||
beanFactory.registerBean(MergerFactory.class);
|
||||
beanFactory.registerBean(ClusterUtils.class);
|
||||
beanFactory.registerBean(AdaptiveMetrics.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeModuleModel(ModuleModel moduleModel) {
|
||||
ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
|
||||
beanFactory.registerBean(MeshRuleManager.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,4 +46,5 @@ public interface LoadBalance {
|
|||
*/
|
||||
@Adaptive("loadbalance")
|
||||
<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ import org.apache.dubbo.common.extension.SPI;
|
|||
public interface Merger<T> {
|
||||
|
||||
T merge(T... items);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -136,8 +131,7 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
if (matcher.isMatch(host, 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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,4 +32,5 @@ public class AbsentConfigurator extends AbstractConfigurator {
|
|||
public URL doConfigure(URL currentUrl, URL configUrl) {
|
||||
return currentUrl.addParametersIfAbsent(configUrl.getParameters());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ public class AbsentConfiguratorFactory implements ConfiguratorFactory {
|
|||
public Configurator getConfigurator(URL url) {
|
||||
return new AbsentConfigurator(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,4 +36,5 @@ public class OverrideConfigurator extends AbstractConfigurator {
|
|||
logger.info("Start overriding url " + currentUrl + " with override url " + configUrl);
|
||||
return currentUrl.addParameters(configUrl.getParameters());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ public class OverrideConfiguratorFactory implements ConfiguratorFactory {
|
|||
public Configurator getConfigurator(URL url) {
|
||||
return new OverrideConfigurator(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) -> {
|
||||
|
|
|
|||
|
|
@ -101,11 +101,12 @@ public class ConditionMatch {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConditionMatch{" + "address='"
|
||||
+ address + '\'' + "providerAddress='"
|
||||
+ providerAddress + '\'' + ", service='"
|
||||
+ service + '\'' + ", app='"
|
||||
+ app + '\'' + ", param='"
|
||||
+ param + '\'' + '}';
|
||||
return "ConditionMatch{" +
|
||||
"address='" + address + '\'' +
|
||||
"providerAddress='" + providerAddress + '\'' +
|
||||
", service='" + service + '\'' +
|
||||
", app='" + app + '\'' +
|
||||
", param='" + param + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ public class ParamMatch {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParamMatch{" + "key='" + key + '\'' + ", value='" + value + '\'' + '}';
|
||||
return "ParamMatch{" +
|
||||
"key='" + key + '\'' +
|
||||
", value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,12 @@ 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 routed invokers' size: " + routedResult.size()
|
||||
+ " from registry " + this
|
||||
+ " on the consumer " + NetUtils.getLocalHost()
|
||||
+ " using the dubbo version " + Version.getVersion() + ".");
|
||||
}
|
||||
return Collections.unmodifiableList(routedResult);
|
||||
} finally {
|
||||
|
|
@ -298,109 +283,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(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -411,20 +361,17 @@ 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(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
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 +392,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(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
@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(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
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 +463,40 @@ 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(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
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();
|
||||
boolean result;
|
||||
synchronized (this.validInvokers) {
|
||||
result = this.validInvokers.add(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result;
|
||||
}
|
||||
|
||||
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();
|
||||
boolean result;
|
||||
synchronized (this.validInvokers) {
|
||||
result = this.validInvokers.remove(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result;
|
||||
}
|
||||
|
||||
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 +504,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() {
|
||||
|
|
@ -597,27 +526,25 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
@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(", "))
|
||||
+ "]" + ')';
|
||||
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(", ")) + "]" +
|
||||
')';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,12 +55,7 @@ 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");
|
||||
}
|
||||
|
|
@ -106,34 +101,28 @@ 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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.cluster.factory;
|
||||
|
||||
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvokerFactory;
|
||||
import org.apache.dubbo.rpc.cluster.Directory;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.rpc.cluster.Cluster.getCluster;
|
||||
|
||||
public class DefaultClusterInvokerFactory implements ClusterInvokerFactory {
|
||||
|
||||
private final List<DirectoryStrategy> strategies;
|
||||
|
||||
public DefaultClusterInvokerFactory(ScopeModel scopeModel) {
|
||||
this.strategies = scopeModel.getBeanFactory().getBeansOfType(DirectoryStrategy.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an Invoker with StaticDirectory.
|
||||
*
|
||||
* @param config config
|
||||
* @return ClusterInvoker
|
||||
*/
|
||||
@Override
|
||||
public Invoker<?> getInvoker(ClusterInvokerConfig config) {
|
||||
Directory<?> directory = null;
|
||||
for (DirectoryStrategy strategy : strategies) {
|
||||
if (strategy.name().equals(config.getDirectoryName())) {
|
||||
directory = strategy.createDirectory(config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return getCluster(config.getScopeModel(), config.getClusterName(), config.isWrappedCluster())
|
||||
.join(directory,config.isWrappedInvoker());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,16 +14,14 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.bootstrap.rest;
|
||||
package org.apache.dubbo.rpc.cluster.factory;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvokerFactory;
|
||||
import org.apache.dubbo.rpc.cluster.Directory;
|
||||
|
||||
public class UserServiceImpl implements UserService {
|
||||
public interface DirectoryStrategy {
|
||||
|
||||
private final AtomicLong idGen = new AtomicLong();
|
||||
ClusterInvokerFactory.DirectoryNames name();
|
||||
|
||||
@Override
|
||||
public User getUser(Long id) {
|
||||
return new User(id, "username" + id);
|
||||
}
|
||||
<T> Directory<T> createDirectory(ClusterInvokerFactory.ClusterInvokerConfig clusterInvokerConfig);
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.cluster.factory;
|
||||
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvokerFactory;
|
||||
import org.apache.dubbo.rpc.cluster.Directory;
|
||||
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
|
||||
|
||||
public class StaticDirectoryStrategy implements DirectoryStrategy {
|
||||
|
||||
@Override
|
||||
public ClusterInvokerFactory.DirectoryNames name() {
|
||||
return ClusterInvokerFactory.DirectoryNames.STATIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Directory<T> createDirectory(ClusterInvokerFactory.ClusterInvokerConfig clusterInvokerConfig) {
|
||||
return new StaticDirectory(clusterInvokerConfig.getServiceUrl(),clusterInvokerConfig.getInvokersToJoin());
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,8 +92,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 +159,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 +182,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 +223,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 +264,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 +293,10 @@ 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);
|
||||
private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(CopyOfFilterChainNode.class);
|
||||
TYPE originalInvoker;
|
||||
Invoker<T> nextNode;
|
||||
FILTER filter;
|
||||
|
|
@ -344,14 +330,11 @@ 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() + ".";
|
||||
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);
|
||||
}
|
||||
|
|
@ -389,14 +372,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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,10 @@ 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)
|
||||
@Activate(group = {CONSUMER}, order = Integer.MIN_VALUE + 100)
|
||||
public class MetricsConsumerFilter extends MetricsFilter implements ClusterFilter, BaseFilter.Listener {
|
||||
public MetricsConsumerFilter() {}
|
||||
public MetricsConsumerFilter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
|
|
|
|||
|
|
@ -56,4 +56,5 @@ public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleReposi
|
|||
private DynamicConfiguration getDynamicConfiguration() {
|
||||
return moduleModel.modelEnvironment().getDynamicConfiguration().orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public interface GovernanceRuleRepository {
|
|||
addListener(key, DEFAULT_GROUP, listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link #removeListener(String, String, ConfigurationListener)}
|
||||
*
|
||||
|
|
|
|||
|
|
@ -47,7 +47,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 +64,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
|
||||
|
|
@ -93,7 +94,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,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 +74,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 +96,14 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
}
|
||||
|
||||
public Invoker<T> select(Invocation invocation) {
|
||||
String key = toKey(RpcUtils.getArguments(invocation));
|
||||
|
||||
byte[] digest = Bytes.getMD5(key);
|
||||
byte[] digest = Bytes.getMD5(RpcUtils.getMethodName(invocation));
|
||||
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 +124,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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,18 +56,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(), RpcUtils.getMethodName(invocation)).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;
|
||||
|
|
|
|||
|
|
@ -78,8 +78,7 @@ public class RandomLoadBalance extends AbstractLoadBalance {
|
|||
}
|
||||
}
|
||||
if (totalWeight > 0 && !sameWeight) {
|
||||
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on
|
||||
// totalWeight.
|
||||
// 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 +92,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++;
|
||||
|
|
|
|||
|
|
@ -37,8 +37,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;
|
||||
|
|
@ -92,8 +91,7 @@ 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<>());
|
||||
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 +107,7 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
});
|
||||
|
||||
if (weight != weightedRoundRobin.getWeight()) {
|
||||
// weight changed
|
||||
//weight changed
|
||||
weightedRoundRobin.setWeight(weight);
|
||||
}
|
||||
long cur = weightedRoundRobin.increaseCurrent();
|
||||
|
|
@ -131,4 +129,5 @@ public class RoundRobinLoadBalance extends AbstractLoadBalance {
|
|||
// should not happen here
|
||||
return invokers.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,15 +59,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.modelEnvironment().getConfiguration().getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
|
||||
executorService = applicationModel.getFrameworkModel().getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class).getSharedExecutor();
|
||||
}
|
||||
|
||||
protected static class SlideWindowData {
|
||||
|
|
@ -124,11 +118,9 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance implements
|
|||
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);
|
||||
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 +135,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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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("...");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -62,14 +62,7 @@ public class AddressMatch {
|
|||
try {
|
||||
return input.equals(getCird()) || matchIpExpression(getCird(), input);
|
||||
} catch (UnknownHostException e) {
|
||||
logger.error(
|
||||
CLUSTER_FAILED_EXEC_CONDITION_ROUTER,
|
||||
"Executing routing rule match expression error.",
|
||||
"",
|
||||
String.format(
|
||||
"Error trying to match cird formatted address %s with input %s in AddressMatch.",
|
||||
getCird(), input),
|
||||
e);
|
||||
logger.error(CLUSTER_FAILED_EXEC_CONDITION_ROUTER, "Executing routing rule match expression error.", "", String.format("Error trying to match cird formatted address %s with input %s in AddressMatch.", getCird(), input), e);
|
||||
}
|
||||
}
|
||||
if (getWildcard() != null && input != null) {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
public class BoolMatch {
|
||||
private Boolean exact;
|
||||
|
||||
|
|
@ -27,8 +29,8 @@ public class BoolMatch {
|
|||
this.exact = exact;
|
||||
}
|
||||
|
||||
public boolean isMatch(boolean input) {
|
||||
if (exact != null) {
|
||||
public boolean isMatch(boolean input){
|
||||
if (exact != null){
|
||||
return input == exact;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
public class DoubleMatch {
|
||||
private Double exact;
|
||||
private DoubleRangeMatch range;
|
||||
|
|
@ -45,6 +47,7 @@ public class DoubleMatch {
|
|||
this.mod = mod;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMatch(Double input) {
|
||||
if (exact != null && mod == null) {
|
||||
return input.equals(exact);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh.rule.virtualservice.match;
|
||||
|
||||
|
||||
public class DoubleRangeMatch {
|
||||
private Double start;
|
||||
private Double end;
|
||||
|
|
@ -36,6 +38,7 @@ public class DoubleRangeMatch {
|
|||
this.end = end;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMatch(Double input) {
|
||||
if (start != null && end != null) {
|
||||
return input.compareTo(start) >= 0 && input.compareTo(end) < 0;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue