Compare commits
7 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
c80b94bdd9 | |
|
|
9362181d12 | |
|
|
84aa7d8140 | |
|
|
8021bb0a8c | |
|
|
430fb4c6c7 | |
|
|
b3a8f1c296 | |
|
|
4f34540024 |
117
.artifacts
117
.artifacts
|
|
@ -1,117 +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.
|
||||
#
|
||||
|
||||
# Please add new modules to the end of the list.
|
||||
|
||||
dubbo
|
||||
dubbo-auth
|
||||
dubbo-apache-release
|
||||
dubbo-bom
|
||||
dubbo-build-tools
|
||||
dubbo-cluster
|
||||
dubbo-common
|
||||
dubbo-compatible
|
||||
dubbo-compiler
|
||||
dubbo-config
|
||||
dubbo-config-api
|
||||
dubbo-config-spring
|
||||
dubbo-configcenter
|
||||
dubbo-configcenter-apollo
|
||||
dubbo-configcenter-nacos
|
||||
dubbo-configcenter-zookeeper
|
||||
dubbo-container
|
||||
dubbo-container-api
|
||||
dubbo-container-spring
|
||||
dubbo-core-spi
|
||||
dubbo-dependencies
|
||||
dubbo-dependencies-all
|
||||
dubbo-dependencies-bom
|
||||
dubbo-dependencies-zookeeper
|
||||
dubbo-dependencies-zookeeper-curator5
|
||||
dubbo-distribution
|
||||
dubbo-filter
|
||||
dubbo-filter-cache
|
||||
dubbo-filter-validation
|
||||
dubbo-kubernetes
|
||||
dubbo-maven-plugin
|
||||
dubbo-metadata
|
||||
dubbo-metadata-api
|
||||
dubbo-metadata-definition-protobuf
|
||||
dubbo-metadata-processor
|
||||
dubbo-metadata-report-nacos
|
||||
dubbo-metadata-report-redis
|
||||
dubbo-metadata-report-zookeeper
|
||||
dubbo-metrics
|
||||
dubbo-metrics-api
|
||||
dubbo-metrics-default
|
||||
dubbo-metrics-metadata
|
||||
dubbo-metrics-prometheus
|
||||
dubbo-metrics-registry
|
||||
dubbo-metrics-config-center
|
||||
dubbo-monitor
|
||||
dubbo-monitor-api
|
||||
dubbo-monitor-default
|
||||
dubbo-native
|
||||
dubbo-native-plugin
|
||||
dubbo-parent
|
||||
dubbo-plugin
|
||||
dubbo-qos
|
||||
dubbo-qos-api
|
||||
dubbo-reactive
|
||||
dubbo-registry
|
||||
dubbo-registry-api
|
||||
dubbo-registry-multicast
|
||||
dubbo-registry-multiple
|
||||
dubbo-registry-nacos
|
||||
dubbo-registry-zookeeper
|
||||
dubbo-remoting
|
||||
dubbo-remoting-api
|
||||
dubbo-remoting-http
|
||||
dubbo-remoting-netty
|
||||
dubbo-remoting-netty4
|
||||
dubbo-remoting-zookeeper
|
||||
dubbo-remoting-zookeeper-curator5
|
||||
dubbo-rpc
|
||||
dubbo-rpc-api
|
||||
dubbo-rpc-dubbo
|
||||
dubbo-rpc-injvm
|
||||
dubbo-rpc-rest
|
||||
dubbo-rpc-triple
|
||||
dubbo-security
|
||||
dubbo-serialization
|
||||
dubbo-serialization-api
|
||||
dubbo-serialization-fastjson2
|
||||
dubbo-serialization-hessian2
|
||||
dubbo-serialization-jdk
|
||||
dubbo-spring-boot
|
||||
dubbo-spring-boot-actuator
|
||||
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-spring-boot-starter
|
||||
dubbo-spring-boot-starters
|
||||
dubbo-nacos-spring-boot-starter
|
||||
dubbo-zookeeper-spring-boot-starter
|
||||
dubbo-zookeeper-curator5-spring-boot-starter
|
||||
dubbo-spring-security
|
||||
dubbo-xds
|
||||
59
.asf.yaml
59
.asf.yaml
|
|
@ -1,59 +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.
|
||||
#
|
||||
#
|
||||
|
||||
notifications:
|
||||
commits: commits@dubbo.apache.org
|
||||
issues: notifications@dubbo.apache.org
|
||||
pullrequests: notifications@dubbo.apache.org
|
||||
jira_options: link label link label
|
||||
|
||||
github:
|
||||
homepage: https://dubbo.apache.org/
|
||||
description: "The java implementation of Apache Dubbo. An RPC and microservice framework."
|
||||
features:
|
||||
# Enable wiki for documentation
|
||||
wiki: true
|
||||
# Enable issue management
|
||||
issues: true
|
||||
# Enable projects for project management boards
|
||||
projects: true
|
||||
protected_branches:
|
||||
master:
|
||||
# only disable force push
|
||||
foo: bar
|
||||
3.0:
|
||||
# only disable force push
|
||||
foo: bar
|
||||
3.1:
|
||||
# only disable force push
|
||||
foo: bar
|
||||
labels:
|
||||
- java
|
||||
- rpc
|
||||
- microservices
|
||||
- framework
|
||||
- restful
|
||||
- distributed-systems
|
||||
- dubbo
|
||||
- service-mesh
|
||||
- http
|
||||
- grpc
|
||||
- web
|
||||
collaborators:
|
||||
- oxsean
|
||||
|
|
@ -1,73 +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.
|
||||
#
|
||||
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
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
|
||||
|
|
@ -1,20 +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.
|
||||
#
|
||||
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
*.java text eol=lf
|
||||
|
|
@ -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!"
|
||||
|
|
@ -1,22 +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.
|
||||
#
|
||||
|
||||
blank_issues_enabled: false
|
||||
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.
|
||||
|
|
@ -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).
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
version: 2
|
||||
updates:
|
||||
|
||||
- package-ecosystem: "maven"
|
||||
directory: "/"
|
||||
open-pull-requests-limit: 20
|
||||
# Ignore major version updates
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major"]
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "03:00"
|
||||
timezone: "US/Eastern"
|
||||
|
|
@ -1,604 +0,0 @@
|
|||
name: Build and Test For PR
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORK_COUNT: 2
|
||||
FAIL_FAST: 0
|
||||
SHOW_ERROR_DETAIL: 1
|
||||
#multi-version size limit
|
||||
VERSIONS_LIMIT: 4
|
||||
JACOCO_ENABLE: true
|
||||
CANDIDATE_VERSIONS: '
|
||||
spring.version:5.3.24;
|
||||
spring-boot.version:2.7.6;
|
||||
'
|
||||
|
||||
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
|
||||
- name: Check License
|
||||
uses: apache/skywalking-eyes@e1a02359b239bd28de3f6d35fdc870250fa513d5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: "Set up JDK 21"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
- 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
|
||||
- name: Check Dependencies' License
|
||||
uses: apache/skywalking-eyes/dependency@e1a02359b239bd28de3f6d35fdc870250fa513d5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
config: .licenserc.yaml
|
||||
mode: check
|
||||
|
||||
build-source:
|
||||
name: "Build Dubbo"
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.dubbo-version.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
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 class result"
|
||||
run: |
|
||||
shopt -s globstar
|
||||
zip ${{ github.workspace }}/class.zip **/target/classes/* -r
|
||||
- name: "Upload class result"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "class-file"
|
||||
path: ${{ github.workspace }}/class.zip
|
||||
- name: "Pack checkstyle file if failure"
|
||||
if: failure()
|
||||
run: zip ${{ 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"
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
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"
|
||||
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
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache secret key"
|
||||
id: "cache-secret-cert"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/rsa
|
||||
key: secret-rsa-${{ runner.os }}-${{ github.run_id }}
|
||||
- name: "Create Secret"
|
||||
run: |
|
||||
mkdir -p ${{ github.workspace }}/.tmp/rsa
|
||||
cd ${{ github.workspace }}/.tmp/rsa
|
||||
openssl genrsa -out rsa_private.pem 1024
|
||||
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem
|
||||
echo "Current workflow run id: ${{ github.run_id }}"
|
||||
echo "Start Print Rsa Public Key ---"
|
||||
cat rsa_public.pem
|
||||
echo "--- End Print Rsa Public Key"
|
||||
|
||||
unit-test:
|
||||
needs: [check-format, build-source, unit-test-prepare]
|
||||
name: "Unit Test On ubuntu-latest"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
CURRENT_ROLE: ${{ matrix.case-role }}
|
||||
DUBBO_DEFAULT_SERIALIZATION: fastjson2
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
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-
|
||||
- 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 }}-
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache secret key"
|
||||
id: "cache-secret-cert"
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/rsa
|
||||
key: secret-rsa-${{ runner.os }}-${{ github.run_id }}
|
||||
- name: "Get sonarcloud token"
|
||||
if: ${{ github.repository == 'apache/dubbo' }}
|
||||
run: |
|
||||
curl "http://dubbo-vm.apache.org:8000/token?workflow_id=${{ github.run_id }}" -o ${{ github.workspace }}/.tmp/encrypted-sonarcloud-token
|
||||
openssl rsautl -decrypt -in ${{ github.workspace }}/.tmp/encrypted-sonarcloud-token -out ${{ github.workspace }}/.tmp/decrypted-sonarcloud-token -inkey ${{ github.workspace }}/.tmp/rsa/rsa_private.pem
|
||||
- name: "Test with Maven with SonarCloud Scan"
|
||||
if: ${{ github.repository == 'apache/dubbo' }}
|
||||
timeout-minutes: 70
|
||||
env:
|
||||
# Needed to get some information about the pull request, if any
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
source ${{ github.workspace }}/.tmp/decrypted-sonarcloud-token
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Pjacoco,jdk15ge-simple,'!jdk15ge',jacoco089 -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=apache -Dsonar.projectKey=apache_dubbo -DtrimStackTrace=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper -Dsonar.coverage.jacoco.xmlReportPaths=dubbo-test/dubbo-dependencies-all/target/site/jacoco-aggregate/jacoco.xml -Dsonar.login=${SONAR_TOKEN}
|
||||
- name: "Test with Maven without SonarCloud Scan"
|
||||
if: ${{ github.repository != 'apache/dubbo' }}
|
||||
timeout-minutes: 70
|
||||
run: |
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Pjacoco,jdk15ge-simple,'!jdk15ge',jacoco089 -DtrimStackTrace=false -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Upload coverage result"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
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
|
||||
- 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: [check-format, build-source, integration-test-prepare]
|
||||
name: "Integration 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-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: 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: jacoco-result
|
||||
path: target/jacoco*.exec
|
||||
- name: "Upload test result"
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-result
|
||||
path: test/jobs/*-result*
|
||||
integration-test-result:
|
||||
needs: [check-format, integration-test-job]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
JAVA_VER: 8
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'apache/dubbo-integration-cases'
|
||||
ref: main
|
||||
- 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
|
||||
|
||||
jacoco-result-merge:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-format, integration-test-result, samples-test-result, unit-test]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
path: "./dubbo"
|
||||
- uses: actions/checkout@v3
|
||||
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"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
- name: "Restore class result"
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: "class-file"
|
||||
path: ${{ github.workspace }}
|
||||
- name: "Unpack class result"
|
||||
run: |
|
||||
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/
|
||||
- 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:
|
||||
name: coverage-result
|
||||
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
|
||||
with:
|
||||
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:
|
||||
needs: check-format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
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
|
||||
|
|
@ -1,502 +0,0 @@
|
|||
name: Build and Test Scheduled On 3.1
|
||||
|
||||
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.1"
|
||||
- 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.1"
|
||||
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, 21 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
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"
|
||||
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 ]
|
||||
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
|
||||
|
||||
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 ]
|
||||
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 ]
|
||||
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.1"
|
||||
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.1"
|
||||
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
|
||||
|
|
@ -1,502 +0,0 @@
|
|||
name: Build and Test Scheduled On 3.2
|
||||
|
||||
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.2"
|
||||
- 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.2"
|
||||
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, 21 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
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"
|
||||
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.2"
|
||||
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.2"
|
||||
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
|
||||
|
|
@ -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
|
||||
|
|
@ -1,497 +0,0 @@
|
|||
name: Release Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**-release'
|
||||
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
|
||||
- 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:
|
||||
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, 21 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Set up JDK ${{ matrix.jdk }}"
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
distribution: 'zulu'
|
||||
- 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:
|
||||
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:
|
||||
java-version: 21
|
||||
distribution: 'zulu'
|
||||
|
||||
- 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:
|
||||
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
|
||||
|
|
@ -1,18 +1,16 @@
|
|||
# maven ignore
|
||||
target/
|
||||
*.jar
|
||||
!.mvn/wrapper/*
|
||||
*.war
|
||||
*.zip
|
||||
*.tar
|
||||
*.tar.gz
|
||||
.flattened-pom.xml
|
||||
|
||||
# eclipse ignore
|
||||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
.externalToolBuilders
|
||||
maven-eclipse.xml
|
||||
|
||||
# idea ignore
|
||||
.idea/
|
||||
|
|
@ -20,9 +18,6 @@ maven-eclipse.xml
|
|||
*.iml
|
||||
*.iws
|
||||
|
||||
# visual-studio-code ignore
|
||||
.vscode/
|
||||
|
||||
# temp ignore
|
||||
*.log
|
||||
*.cache
|
||||
|
|
@ -33,25 +28,3 @@ maven-eclipse.xml
|
|||
# system ignore
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
*.orig
|
||||
|
||||
# license check result
|
||||
license-list
|
||||
|
||||
# grpc compiler
|
||||
compiler/gradle.properties
|
||||
compiler/build/*
|
||||
compiler/.gradle/*
|
||||
|
||||
# protobuf
|
||||
dubbo-serialization/dubbo-serialization-protobuf/build/*
|
||||
dubbo-demo/dubbo-demo-triple/build/*
|
||||
|
||||
# global registry center
|
||||
.tmp
|
||||
|
||||
.git.exec.error
|
||||
|
||||
# log files generated by testcase.
|
||||
dubbo-rpc/dubbo-rpc-api/custom-access.log*
|
||||
|
||||
|
|
|
|||
235
.licenserc.yaml
235
.licenserc.yaml
|
|
@ -1,235 +0,0 @@
|
|||
header:
|
||||
license:
|
||||
spdx-id: Apache-2.0
|
||||
content: |
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
paths-ignore:
|
||||
- '**/*.versionsBackup'
|
||||
- '**/.idea/'
|
||||
- '**/*.iml'
|
||||
- '**/.settings/*'
|
||||
- '**/.classpath'
|
||||
- '**/.project'
|
||||
- '**/target/**'
|
||||
- '**/generated/**'
|
||||
- '**/*.log'
|
||||
- '**/codestyle/*'
|
||||
- '**/resources/META-INF/**'
|
||||
- '**/resources/mockito-extensions/**'
|
||||
- '**/*.proto'
|
||||
- '**/*.cache'
|
||||
- '**/*.txt'
|
||||
- '**/*.load'
|
||||
- '**/*.flex'
|
||||
- '**/*.fc'
|
||||
- '**/*.javascript'
|
||||
- '**/*.properties'
|
||||
- '**/*.sh'
|
||||
- '**/*.bat'
|
||||
- '**/*.md'
|
||||
- '**/*.svg'
|
||||
- '**/*.png'
|
||||
- '**/*.json'
|
||||
- '**/*.conf'
|
||||
- '**/*.ftl'
|
||||
- '**/*.tpl'
|
||||
- '**/*.factories'
|
||||
- '**/*.handlers'
|
||||
- '**/*.schemas'
|
||||
- '**/*.nojekyll'
|
||||
- '.git/'
|
||||
- '.github/**'
|
||||
- '**/.gitignore'
|
||||
- '**/.helmignore'
|
||||
- '.repository/'
|
||||
- 'compiler/**'
|
||||
- '.gitmodules'
|
||||
- '.mvn'
|
||||
- 'mvnw'
|
||||
- 'mvnw.cmd'
|
||||
- 'LICENSE'
|
||||
- 'NOTICE'
|
||||
- 'CNAME'
|
||||
- 'Jenkinsfile'
|
||||
- '**/vendor/**'
|
||||
- '**/src/test/resources/certs/**'
|
||||
- '**/src/test/resources/definition/**'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocalMap.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/timer/HashedWheelTimer.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/timer/Timeout.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/timer/Timer.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/timer/TimerTask.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/utils/CIDRUtils.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/utils/Utf8Utils.java'
|
||||
- 'dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/EmbeddedZooKeeper.java'
|
||||
- 'dubbo-test/dubbo-test-common/src/main/java/org/apache/dubbo/test/common/utils/TestSocketUtils.java'
|
||||
- 'dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriHttp2RemoteFlowController.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/serial/SerializingExecutor.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractAotMojo.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/AbstractDependencyFilterMojo.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/CommandLineBuilder.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/DependencyFilter.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Exclude.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/ExcludeFilter.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/FilterableDependency.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/Include.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/IncludeFilter.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaCompilerPluginConfiguration.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaExecutable.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/JavaProcessExecutor.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java'
|
||||
- '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-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'
|
||||
|
||||
comment: on-failure
|
||||
|
||||
license-location-threshold: 130
|
||||
|
||||
dependency:
|
||||
files:
|
||||
- pom.xml
|
||||
- dubbo-dependencies-bom/pom.xml
|
||||
licenses:
|
||||
- name: com.alibaba.spring:spring-context-support
|
||||
license: Apache-2.0
|
||||
- name: com.fasterxml.jackson.core:jackson-annotations
|
||||
license: Apache-2.0
|
||||
- name: com.fasterxml.jackson.core:jackson-core
|
||||
license: Apache-2.0
|
||||
- name: com.fasterxml.jackson.core:jackson-databind
|
||||
license: Apache-2.0
|
||||
- name: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml
|
||||
license: Apache-2.0
|
||||
- name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310
|
||||
license: Apache-2.0
|
||||
- name: com.google.code.gson:gson
|
||||
license: Apache-2.0
|
||||
- name: com.google.guava:listenablefuture
|
||||
license: Apache-2.0
|
||||
- name: com.salesforce.servicelibs:grpc-contrib
|
||||
license: BSD 3-clause
|
||||
- name: com.squareup.okhttp3:logging-interceptor
|
||||
license: Apache-2.0
|
||||
- name: com.squareup.okhttp3:okhttp
|
||||
license: Apache-2.0
|
||||
- name: com.squareup.okio:okio
|
||||
license: Apache-2.0
|
||||
- name: com.sun.xml.fastinfoset:FastInfoset
|
||||
license: Apache-2.0
|
||||
- name: io.envoyproxy.controlplane:api
|
||||
license: Apache-2.0
|
||||
- name: io.swagger:swagger-annotations
|
||||
license: Apache-2.0
|
||||
- name: io.swagger:swagger-models
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-actuator
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-autoconfigure
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-configuration-processor
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-starter
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-starter-actuator
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-starter-logging
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-starter-tomcat
|
||||
license: Apache-2.0
|
||||
- name: org.springframework.boot:spring-boot-starter-web
|
||||
license: Apache-2.0
|
||||
- name: org.slf4j:slf4j-api
|
||||
license: MIT
|
||||
- name: org.slf4j:slf4j-log4j12
|
||||
license: MIT
|
||||
- name: org.jboss.resteasy:resteasy-jaxrs
|
||||
license: Apache-2.0
|
||||
- name: org.jboss.resteasy:resteasy-client
|
||||
license: Apache-2.0
|
||||
- name: org.jboss.resteasy:resteasy-netty4
|
||||
license: Apache-2.0
|
||||
- name: org.jboss.resteasy:resteasy-jdk-http
|
||||
license: Apache-2.0
|
||||
- name: org.jboss.resteasy:resteasy-jackson-provider
|
||||
license: Apache-2.0
|
||||
- name: org.jboss.resteasy:resteasy-jaxb-provider
|
||||
license: Apache-2.0
|
||||
- name: net.jcip:jcip-annotations
|
||||
license: Apache-2.0
|
||||
- name: org.apache.zookeeper:zookeeper
|
||||
license: Apache-2.0
|
||||
- name: org.apache.zookeeper:zookeeper-jute
|
||||
license: Apache-2.0
|
||||
- name: net.bytebuddy:byte-buddy
|
||||
license: Apache-2.0
|
||||
- name: javax.enterprise:cdi-api
|
||||
license: Apache-2.0
|
||||
- name: org.codehaus.plexus:plexus-component-annotations
|
||||
license: Apache-2.0
|
||||
- name: org.slf4j:jcl-over-slf4j
|
||||
license: Apache-2.0
|
||||
- name: org.slf4j:jul-to-slf4j
|
||||
license: Apache-2.0
|
||||
- name: org.codehaus.plexus:plexus-interpolation
|
||||
license: Apache-2.0
|
||||
- name: org.sonatype.plexus:plexus-sec-dispatcher
|
||||
license: Apache-2.0
|
||||
- name: org.sonatype.plexus:plexus-cipher
|
||||
license: Apache-2.0
|
||||
- name: com.google.protobuf:protobuf-java
|
||||
license: BSD 3-clause
|
||||
- name: com.google.protobuf:protobuf-java-util
|
||||
license: BSD 3-clause
|
||||
# multi license
|
||||
- name: org.javassist:javassist
|
||||
license: Apache-2.0
|
||||
- name: javax.annotation:javax.annotation-api
|
||||
license: CDDL-1.0
|
||||
- name: com.salesforce.servicelibs:jprotoc
|
||||
license: CDDL-1.0
|
||||
- name: org.checkerframework:checker-compat-qual
|
||||
license: MIT
|
||||
- name: ch.qos.logback:logback-classic
|
||||
license: EPL-1.0
|
||||
- name: ch.qos.logback:logback-core
|
||||
license: EPL-1.0
|
||||
- name: javax.servlet:javax.servlet-api
|
||||
license: CDDL-1.1
|
||||
- name: com.sun.activation:javax.activation
|
||||
license: CDDL-1.1
|
||||
- name: javax.activation:activation
|
||||
license: CDDL-1.1
|
||||
- name: jakarta.annotation:jakarta.annotation-api
|
||||
license: EPL-2.0
|
||||
- name: org.glassfish:jakarta.el
|
||||
license: EPL-2.0
|
||||
- name: org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec
|
||||
license: CDDL-1.1
|
||||
- name: org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.1_spec
|
||||
license: EPL-2.0
|
||||
- name: org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec
|
||||
license: EPL-2.0
|
||||
excludes:
|
||||
- name: javax.xml.bind:jsr173_api
|
||||
Binary file not shown.
|
|
@ -1,18 +1 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
|
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
language: java
|
||||
sudo: false # faster builds
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- openjdk7
|
||||
|
||||
script:
|
||||
- mvn clean package
|
||||
- mvn cobertura:cobertura
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
513
CHANGES.md
513
CHANGES.md
|
|
@ -1,513 +0,0 @@
|
|||
# Release Notes
|
||||
|
||||
Please refer to https://github.com/apache/dubbo/releases for notes of future releases.
|
||||
|
||||
## 2.7.6
|
||||
|
||||
### Features
|
||||
* Support Service Authentication https://github.com/apache/dubbo/issues/5461
|
||||
|
||||
### Enhancement
|
||||
* Removing the internal JDK API from FileSystemDynamicConfiguration
|
||||
* Refactor the APT test-cases implementation of dubbo-metadata-processor in Java 9+
|
||||
* Remove feature envy
|
||||
* JsonRpcProtocol support Generalization
|
||||
* Reduce object allocation for ProtocolUtils.serviceKey
|
||||
* Reduce object allocation for ContextFilter.invoke
|
||||
|
||||
### Bugfixes
|
||||
* Fixed bugs reported from 2.7.5 or lower versions, check [2.7.6 milestone](https://github.com/apache/dubbo/milestone/30) for details.
|
||||
|
||||
### Compatibility
|
||||
1. Filter refactor, the callback method `onResponse` annotated as @Deprecated has been removed, users of lower versions that
|
||||
have extended Filter implementations and enabled Filter callbacks should be careful of this change.
|
||||
2. RpcContext added some experimental APIs to support generic Object transmission.
|
||||
|
||||
## 2.7.5
|
||||
|
||||
### Features
|
||||
* Support HTTP/2 through gRPC, offers all features supported by HTTP/2 and gRPC
|
||||
* Stream communication: client stream, server stream and bi-stream.
|
||||
* Reactive stream style RPC call.
|
||||
* Back pressure based on HTTP/2 flow-control mechanism.
|
||||
* TLS secure transport layer.
|
||||
* Define service using IDL
|
||||
* Protobuf support for native Dubbo
|
||||
* Define service using IDL
|
||||
* Protobuf serialization
|
||||
* TLS for netty4 server
|
||||
* New SPI for dynamically adding extra parameters into provider URL, especially env parameters.
|
||||
* **[BETA]** Brand new Service Discovery mechanism: Service Reflection - instance (application) level service discovery.
|
||||
* **[BETA]** Brand new API for bootstraping Dubbo projects
|
||||
|
||||
### Performance Tuning
|
||||
* Overall performance improved by nearly 30% compared to v2.7.3 (by QPS in certain circumstances)
|
||||
* Improved consumer side thread model to avoid thread allocation and context switch, especially useful for services serving big traffic.
|
||||
|
||||
### Enhancement
|
||||
* Load balance strategy among multiple registries:
|
||||
* Preferred
|
||||
* Same zone first
|
||||
* Weighted LB
|
||||
* The first one available
|
||||
* New callback SPI for receiving address change notifications
|
||||
* Refactoring of config module
|
||||
|
||||
### Bugfixes
|
||||
check 2.7.5 milestone for details.
|
||||
|
||||
## 2.7.4.1
|
||||
|
||||
### Enhancement
|
||||
|
||||
* Enhance ProtobufTypeBuilder support generate type definition which contains Bytes List or Bytes Map. #5083
|
||||
* Using the ID of Dubbo Config as the alias of Bean. #5094
|
||||
* tag router supports anyhost. #4431
|
||||
* optimize generic invoke. #4076
|
||||
* dubbo zookeeper registry too slow #4828
|
||||
* use consul with group and version. #4755
|
||||
* qos support host config. #4720
|
||||
* migrate http protocol #4781
|
||||
* Some unit test optimization. #5026 #4803 #4687
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Apollo namespace optimization. #5105
|
||||
* Simplify dubbo-common transitive dependencies. #5107
|
||||
* Delete 'config.' prefix for url generated from ConfigCenterConfig. #5001
|
||||
* fix set generic method error. #5079
|
||||
* Add support for overriding Map properties in AbstractConfig.refresh. #4882
|
||||
* Fix travis javax.ex dependency issue. (unit test)
|
||||
* Fix: ExtensionLoader load duplicate filter,no log or exception. #4340
|
||||
* When the provider interrupts abnormally, the consumer cannot return quickly and still waits for the timeout to end. #4694
|
||||
* Fix register config not take effect because of url simplified。 #4397
|
||||
* Don't support metadata for generic service. #4641
|
||||
* Avoid resize in ClassUtils.java. #5009
|
||||
* default attribute in <dubbo:registry> doesn't work as expected. #4412
|
||||
* make RegistryDirectory can refresh the invokers when providers number become 0 when using nacos registry. #4793
|
||||
* Multiple @Reference annotations only have one effect #4674
|
||||
* Fix RpcContext.getContext().getRemoteApplicationName() returns null #4351
|
||||
* Security issue: upgrade fastjson version to 1.2.60. #5018
|
||||
* nacos-registry:serviceName split error #4974
|
||||
* AbstractConfig.java-getMetaData set default depend on getmethod sequence #4678
|
||||
* fix protocol register set false not work. #4776
|
||||
* Fix: In Rest protocol, the limitation of Dubbo-Attachments. #4898
|
||||
* The logic of org.apache.dubbo.config.MonitorConfig#isValid is incorrect #4892
|
||||
* protostuff return stackoverflow and other error msg #4861
|
||||
* fix method parameter bean generation. #3796
|
||||
* replace hardcode with regex pattern #4810
|
||||
* Fix warm up issue when provider's timestamp is bigger than local machine's timestamp. #4870
|
||||
* Fix use generic invocation via API , lost #4238 ion" value #4784
|
||||
* In consumer side the app cannot catch the exception from provider that is configured serialization="kryo". #4238
|
||||
* fix StringUtils#isBlank #4725
|
||||
* when the interfaceName of the Reference annotation has duplicated,the exception is puzzled #4160
|
||||
* when anonymity bean is defined in spring context,dubbo throw npe #
|
||||
* add Thread ContextClassLoader #4712
|
||||
* Fix judgment ipv4 address #4729
|
||||
* The compilation of static methods should be excluded when generating the proxy. #4647
|
||||
* check EOF of inputstream in IOUtils.write #4648
|
||||
|
||||
|
||||
## 2.7.3
|
||||
|
||||
### Change List
|
||||
|
||||
1. Asynchronous support
|
||||
* Unified asynchronous and synchronous callback process, exception scenario triggers onError callback, #4401
|
||||
* Performance degradation caused by CompletableFuture.get() in JDK1.8 environment, #4279
|
||||
|
||||
2. Configuration Center
|
||||
* ConfigCenter custom namespace does not take effect, #4411
|
||||
* Unify the models implemented by several configuration centers such as Zookeeper, Nacos, and Etcd. Please refer to the description for possible incompatibility issues, #4388
|
||||
* Adjust Override Coverage Rule Center Priority: Service Level > Application Level, #4175
|
||||
|
||||
3. 2.6.x compatibility
|
||||
* Support Zipkin tracing feature provided by Zipkin officially, #3728, #4471
|
||||
* DubboComponentScan supports simultaneous scanning of annotations under the `com.alibaba.*` and `org.apache.*` packages, #4330
|
||||
|
||||
4. The Nacos Registration Center only subscribes to the address list and no longer subscribes to configuration information, #4454.
|
||||
|
||||
5. Support to read the environment configuration from the specified location, which can be specified by -D or OS VARIABLE. Please refer to [automatically loading environment variables](http://dubbo.apache.org/en-us/docs/user/configuration/environment-variables.html)
|
||||
|
||||
6. Fix consumer cannot downgrade to providers with no tags when there's no tagged providers can match, #4525
|
||||
|
||||
7. Some other bugfixes, #4346 #4338 #4349 #4377
|
||||
|
||||
### Change List
|
||||
|
||||
1. 异步支持相关
|
||||
|
||||
- 统一异步和同步的回调流程,异常场景触发onError回调 #4401
|
||||
- CompletableFuture.get()在JDK1.8环境下带来的性能下降问题 #4279
|
||||
|
||||
2. 配置中心相关
|
||||
|
||||
- ConfigCenter自定义namespace不生效的问题 #4411
|
||||
- 统一Zookeeper、Nacos、Etcd等几个配置中心实现的模型,可能带来的不兼容性问题请参见说明。相关修改:#4388
|
||||
- 调整Override覆盖规则中心优先级:服务级别 > 应用级别 #4175
|
||||
|
||||
3. 2.6.x兼容性
|
||||
|
||||
- 兼容zipkin官方提供的基于Dubbo-2.6 API的集成 #3728, #4471
|
||||
- DubboComponentScan支持同时扫描 `com.alibaba.*` 和 `org.apache.*` 两个包下的注解 #4330
|
||||
|
||||
4. Nacos注册中心只订阅地址列表,不再订阅配置信息 #4454
|
||||
|
||||
5. 支持从指定位置读取环境配置,可通过-D或OS VARIABLE指定,具体请参见[使用说明](http://dubbo.apache.org/zh-cn/docs/user/configuration/environment-variables.html)
|
||||
|
||||
6. 标签路由在消费端使用静态打标方式时,无法实现自动降级以消费无标签提供者 #4525
|
||||
|
||||
7. 其他一些bugfix,#4346 #4338 #4349 #4377
|
||||
|
||||
## 2.7.2
|
||||
|
||||
### New Features
|
||||
|
||||
- nacos config center / metadata center support. [#3846](https://github.com/apache/dubbo/issues/3846)
|
||||
- Etcd support as config center and metadata center [#3653](https://github.com/apache/dubbo/issues/3653)
|
||||
- Support Redis cluster in Metadata Report. [#3817](https://github.com/apache/dubbo/issues/3817)
|
||||
- add new module for Dubbo Event. [#4096](https://github.com/apache/dubbo/issues/4096)
|
||||
- Support multiple registry that including some effective registry, such as zk, redis [#3599](https://github.com/apache/dubbo/issues/3599)
|
||||
- support nacos metadata [#4025](https://github.com/apache/dubbo/issues/4025)
|
||||
- Dubbo support Google Protobuf generic reference [#3829](https://github.com/apache/dubbo/issues/3829)
|
||||
- Merge serialization-native-hessian-for-apache-dubbo into incubator-dubbo [#3961](https://github.com/apache/dubbo/issues/3961)
|
||||
- Merge rpc-native-thrift-for-apache-dubbo into incubator-dubbo [#3960](https://github.com/apache/dubbo/issues/3960)
|
||||
- add socks5 proxy support [#3624](https://github.com/apache/dubbo/issues/3624)
|
||||
- Integrate with SOFARegistry [#3874](https://github.com/apache/dubbo/issues/3874)
|
||||
- Introduce CompletableFuture $invokeAsync for GenericService, now, for generic call, you can use:
|
||||
$invoke for sync method call with normal return type.
|
||||
$invokeAsync for async method call with CompletableFuture<T> signature. [#3163](https://github.com/apache/dubbo/issues/3163)
|
||||
|
||||
### Enhancement
|
||||
|
||||
- Performance tuning for TimeoutTask in DefaultFuture. [#4129](https://github.com/apache/dubbo/issues/4129)
|
||||
- Add a script to check dependencies license. [#3840](https://github.com/apache/dubbo/issues/3840)
|
||||
- Change DynamicConfiguration definition to better adapt to Apollo's namespace storage model.[#3266](https://github.com/apache/dubbo/issues/3266)
|
||||
- use equal explicit class to replace anonymous class [#4027](https://github.com/apache/dubbo/issues/4027)
|
||||
- Separate Constants.java into some SubConstants Class [#3137](https://github.com/apache/dubbo/issues/3137)
|
||||
- Need to enhance DecodeableRpcResult error message [#3994](https://github.com/apache/dubbo/issues/3994)
|
||||
- Provide more meaningful binary releases. [#2491](https://github.com/apache/dubbo/issues/2491)
|
||||
- remove useless module-dubbo-test-integration [#3573](https://github.com/apache/dubbo/issues/3573)
|
||||
- complete lookup method of consul registry and add integration test [#3890](https://github.com/apache/dubbo/issues/3890)
|
||||
- Metrics Service [#3702](https://github.com/apache/dubbo/issues/3702)
|
||||
- Update nacos-client to 1.0.0 [#3804](https://github.com/apache/dubbo/issues/3804)
|
||||
- Fluent style builder API support [#3431](https://github.com/apache/dubbo/issues/3431)
|
||||
- Update readme to remove the incubator prefix [#4159](https://github.com/apache/dubbo/issues/4159)
|
||||
- update erlang link [#4100](https://github.com/apache/dubbo/issues/4100)
|
||||
- optimize array code style [#4031](https://github.com/apache/dubbo/issues/4031)
|
||||
- optimize some code style [#4006](https://github.com/apache/dubbo/issues/4006)
|
||||
- remove useless module-dubbo-test-integration [#3989](https://github.com/apache/dubbo/issues/3989)
|
||||
- optimize constant naming style [#3970](https://github.com/apache/dubbo/issues/3970)
|
||||
- Use maven CI friendly versions: revision. [#3851](https://github.com/apache/dubbo/issues/3851)
|
||||
- remove-parse-error-log [#3862](https://github.com/apache/dubbo/issues/3862)
|
||||
- Complete xsd definition for ConfigCenterConfig. [#3854](https://github.com/apache/dubbo/issues/3854)
|
||||
- add remoteApplicationName field in RpcContext [#3816](https://github.com/apache/dubbo/issues/3816)
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- @Reference can't match the local @Service beans. [#4071](https://github.com/apache/dubbo/issues/4071)
|
||||
- remove some illegal licence: jcip-annotations, jsr173_api. [#3790](https://github.com/apache/dubbo/issues/3790)
|
||||
- Qos port can't be disabled by externalized property. [#3958](https://github.com/apache/dubbo/issues/3958)
|
||||
- Fix consumer will generate wrong stackTrace. [#4137](https://github.com/apache/dubbo/issues/4137)
|
||||
- nacos registry serviceName may conflict. [#4111](https://github.com/apache/dubbo/issues/4111)
|
||||
- The client loses the listener when the network is reconnected. [#4115](https://github.com/apache/dubbo/issues/4115)
|
||||
- fix registry urls increase forever when recreate reference proxy. [#4109](https://github.com/apache/dubbo/issues/4109)
|
||||
- In dubbo 2.7.1,the watcher processor of zookeeper client throw Nullpointexception. [#3866](https://github.com/apache/dubbo/issues/3866)
|
||||
- ReferenceConfig initialized not changed to false once subscribe throws exception [#4068](https://github.com/apache/dubbo/issues/4068)
|
||||
- dubbo registry extension compatibility with dubbo 2.6.x. [#3882](https://github.com/apache/dubbo/issues/3882)
|
||||
- Annotation mode cannot set service parameters in 2.7.0. [#3778](https://github.com/apache/dubbo/issues/3778)
|
||||
- compatibility with Zipkin. [#3728](https://github.com/apache/dubbo/issues/3728)
|
||||
- do local export before register any listener. [#3669](https://github.com/apache/dubbo/issues/3669)
|
||||
- Cannot recognize 2.6.x compatible rules from dubbo-admin. [#4059](https://github.com/apache/dubbo/issues/4059)
|
||||
- In Dubbo 2.7.0, the provider can't be configured to async [#3650](https://github.com/apache/dubbo/issues/3650)
|
||||
- dubbox compatibility [#3991](https://github.com/apache/dubbo/issues/3991)
|
||||
- dubbo-2.7.1 providers repeat register [#3785](https://github.com/apache/dubbo/issues/3785)
|
||||
- consul registry: NullPointerException [#3923](https://github.com/apache/dubbo/issues/3923)
|
||||
- cannot publish local ip address when local ip and public ip exist at the same time [#3802](https://github.com/apache/dubbo/issues/3802)
|
||||
- roll back change made by 3520. [#3935](https://github.com/apache/dubbo/issues/3935)
|
||||
- dubbo-registry-nacos module is not bundled into Apache Dubbo 2.7.1 [#3797](https://github.com/apache/dubbo/issues/3797)
|
||||
- switch from CopyOnWriteArrayList to regular list in order to avoid potential UnsupportedOperationException [#3242](https://github.com/apache/dubbo/issues/3242)
|
||||
- Serialization ContentTypeId conflict between avro protocol and protocoluff protocol [#3926](https://github.com/apache/dubbo/issues/3926)
|
||||
- delay export function doesn't work. [#3952](https://github.com/apache/dubbo/issues/3952)
|
||||
- org.apache.dubbo.rpc.support.MockInvoker#getInterface should not return null [#3713](https://github.com/apache/dubbo/issues/3713)
|
||||
- dubbo TagRouter does not work with dubbo:parameter [#3875](https://github.com/apache/dubbo/issues/3875)
|
||||
- make protocols a mutable list (a concrete ArrayList) [#3841](https://github.com/apache/dubbo/issues/3841)
|
||||
- javadoc lint issue [#3646](https://github.com/apache/dubbo/issues/3646)
|
||||
- The etcd3 lease should be recycled correctly [#3684](https://github.com/apache/dubbo/issues/3684)
|
||||
- telnet can't work when parameter has no nullary constructor and some fields is primitive [#4007](https://github.com/apache/dubbo/issues/4007)
|
||||
- Sort added router list before set the 'routers' field of the RouterChain [#3969](https://github.com/apache/dubbo/issues/3969)
|
||||
- fix injvm and local call [#3638](https://github.com/apache/dubbo/issues/3638)
|
||||
- spelling error in org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator#generateReturnAndInovation [#3933](https://github.com/apache/dubbo/issues/3933)
|
||||
- metadata report doesn't support redis with password [#3826](https://github.com/apache/dubbo/issues/3826)
|
||||
- The dubbo protostuff protocol serializes the bug of java.sql.Timestamp [#3914](https://github.com/apache/dubbo/issues/3914)
|
||||
- do not filter thread pool by port [#3919](https://github.com/apache/dubbo/issues/3919)
|
||||
- 'dubbo-serialization-gson' maven package error [#3903](https://github.com/apache/dubbo/issues/3903)
|
||||
- AbstractRegistry will be endless loop, when doSaveProperties method have no permission to save the file [#3746](https://github.com/apache/dubbo/issues/3746)
|
||||
- fix fastjson serialization with generic return type [#3771](https://github.com/apache/dubbo/issues/3771)
|
||||
- The dubbo-serialization -api modules should not dependency on third-party jar packages [#3762](https://github.com/apache/dubbo/issues/3762)
|
||||
- when using protostuff to serialize, there is not to check whether the data is null [#3727](https://github.com/apache/dubbo/issues/3727)
|
||||
- bugfix and enhancement for async [#3287](https://github.com/apache/dubbo/issues/3287)
|
||||
|
||||
## 2.7.1
|
||||
|
||||
### Notice
|
||||
|
||||
'zkclient' extension for 'org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter' is removed from Dubbo 2.7.1, and 'curator' extension becomes the default extension. If you happen to config your application to use 'zkclient' explicitly, pls. switch to use 'curator' instead.
|
||||
|
||||
### New Features
|
||||
|
||||
- service register support on nacos [#3582](https://github.com/apache/dubbo/issues/3582)
|
||||
- support consul as registry center, config center and metadata center [#983](https://github.com/apache/dubbo/issues/983)
|
||||
- service registry support/config center support on etcd [#808](https://github.com/apache/dubbo/issues/808)
|
||||
- metrics support in dubbo 2.7.1 [#3598](https://github.com/apache/dubbo/issues/3598)
|
||||
- @Argument @Method support [#2405](https://github.com/apache/dubbo/issues/2045)
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [Enhancement] @EnableDubboConfigBinding annotates @Repeatable [#1770](https://github.com/apache/dubbo/issues/1770)
|
||||
- [Enhancement] Change the default behavior of @EnableDubboConfig.multiple() [#3193](https://github.com/apache/dubbo/issues/3193)
|
||||
- Should make annotation easier to use in multiple items circumstance [#3039](https://github.com/apache/dubbo/issues/3039)
|
||||
- NoSuchMethodError are thrown when add custom Filter using dubbo2.6.5 and JDK1.6 and upgrade to dubbo2.7.0 [#3570](https://github.com/apache/dubbo/issues/3570)
|
||||
- introduce dubbo-dependencies-zookeeper [#3607](https://github.com/apache/dubbo/pull/3607)
|
||||
- Zookeeper ConfigCenter reuse the client abstraction and connection session [#3288](https://github.com/apache/dubbo/issues/3288)
|
||||
- [Survey] Is it necessary to continue to maintain zkclient in dubbo project? [#3569](https://github.com/apache/dubbo/issues/3569)
|
||||
- Start to use IdleStateHandler in Netty4 [#3341](https://github.com/apache/dubbo/pull/3341)
|
||||
- Support multiple shared links [#2457](https://github.com/apache/dubbo/pull/2457)
|
||||
- Optimize heartbeat [#3299](https://github.com/apache/dubbo/pull/3299)
|
||||
- AccessLogFilter simple date format reduce instance creation [#3026](https://github.com/apache/dubbo/issues/3026)
|
||||
- Support wildcard ip for tag router rule. [#3289](https://github.com/apache/dubbo/issues/3289)
|
||||
- ScriptRouter should cache CompiledScript [#390](https://github.com/apache/dubbo/issues/390)
|
||||
- Optimize compareTo in Router to guarantee consistent behaviour. [#3302](https://github.com/apache/dubbo/issues/3302)
|
||||
- RMI protocol doesn't support generic invocation [#2779](https://github.com/apache/dubbo/issues/2779)
|
||||
- a more elegant way to enhance HashedWheelTimer [#3567](https://github.com/apache/dubbo/pull/3567)
|
||||
- obtain local address incorrectly sometimes in dubbo [#538](https://github.com/apache/dubbo/issues/538)
|
||||
- implement pull request #3412 on master branch [#3418](https://github.com/apache/dubbo/pull/3418)
|
||||
- enhancement for event of response (follow up for pull request #3043) [#3244](https://github.com/apache/dubbo/issues/3244)
|
||||
- bump up hessian-lite version #3423 [#3513](https://github.com/apache/dubbo/pull/3513)
|
||||
- [Dubbo-3610]make snakeyaml transitive, should we do this? [#3659](https://github.com/apache/dubbo/pull/3659)
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- cannot register REST service in 2.7 due to the changes in RestProtoco#getContextPath [#3445](https://github.com/apache/dubbo/issues/3445)
|
||||
- Conflict between curator client and dubbo [#3574](https://github.com/apache/dubbo/issues/3574)
|
||||
- is there a problem in NettyBackedChannelBuffer.setBytes(...)? [#2619](https://github.com/apache/dubbo/issues/2619)
|
||||
- [Dubbo - client always reconnect offline provider] Dubbo client bug [#3158](https://github.com/apache/dubbo/issues/3158)
|
||||
- fix heartbeat internal [#3579](https://github.com/apache/dubbo/pull/3579)
|
||||
- logic issue in RedisRegistry leads to services cannot be discovered. [#3291](https://github.com/apache/dubbo/pull/3291)
|
||||
- Multicast demo fails with message "Can't assign requested address" [#2423](https://github.com/apache/dubbo/issues/2423)
|
||||
- Fix thrift protocol, use path to locate exporter. [#3331](https://github.com/apache/dubbo/pull/3331)
|
||||
- cannot use override to modify provider's configuration when hessian protocol is used [#900](https://github.com/apache/dubbo/issues/900)
|
||||
- Condition is not properly used ? [#1917](https://github.com/apache/dubbo/issues/1917)
|
||||
- connectionMonitor in RestProtocol seems not work [#3237](https://github.com/apache/dubbo/issues/3237)
|
||||
- fail to parse config text with white space [#3367](https://github.com/apache/dubbo/issues/3367)
|
||||
- @Reference check=false doesn't take effect [#195](https://github.com/apache/dubbo/issues/195)
|
||||
- [Issue] SpringStatusChecker execute errors on non-XML Spring configuration [#3615](https://github.com/apache/dubbo/issues/3615)
|
||||
- monitor's cluster config is set to failsafe and set to failsafe only [#274](https://github.com/apache/dubbo/issues/274)
|
||||
- A question for ReferenceConfigCache. [#1293](https://github.com/apache/dubbo/issues/1293)
|
||||
- referenceconfig#destroy never invoke unregister [#3294](https://github.com/apache/dubbo/issues/3294)
|
||||
- Fix when qos is disable,log will print every time [#3397](https://github.com/apache/dubbo/pull/3397)
|
||||
- service group is not supported in generic direct invocation [#3555](https://github.com/apache/dubbo/issues/3555)
|
||||
- setOnreturn doesn't take effect in async generic invocation [#208](https://github.com/apache/dubbo/issues/208)
|
||||
- Fix timeout filter not work in async way [#3174](https://github.com/apache/dubbo/pull/3174)
|
||||
- java.lang.NumberFormatException: For input string: "" [#3069](https://github.com/apache/dubbo/issues/3069)
|
||||
- NPE occurred when the configuration was deleted [#3533](https://github.com/apache/dubbo/issues/3533)
|
||||
- NPE when package of interface is empty [#3556](https://github.com/apache/dubbo/issues/3556)
|
||||
- NPE when exporting rest service using a given path. [#3477](https://github.com/apache/dubbo/issues/3477)
|
||||
- NullPointerException happened when using SpringContainer.getContext() [#3476](https://github.com/apache/dubbo/issues/3476)
|
||||
- Why does not tomcat throw an exception when `server.start` failed with a socket binding error. [#3236](https://github.com/apache/dubbo/issues/3236)
|
||||
- No such extension org.apache.dubbo.metadata.store.MetadataReportFactory by name redis [#3514](https://github.com/apache/dubbo/issues/3514)
|
||||
- dubbo 2.7.1-SNAPSHOT NoClassDefFoundError when use springboot [#3426](https://github.com/apache/dubbo/issues/3426)
|
||||
- NPE occurs when use @Reference in junit in spring boot application [#3429](https://github.com/apache/dubbo/issues/3429)
|
||||
- When refer the same service with more than one @References(with different configs) on consumer side, only one take effect [#1306](https://github.com/apache/dubbo/issues/1306)
|
||||
- consumer always catch java.lang.reflect.UndeclaredThrowableException for the exception thrown from provider [#3386](https://github.com/apache/dubbo/issues/3386)
|
||||
- dubbo2.7.0 com.alibaba.com.caucho.hessian.io.HessianProtocolException: 'com.alibaba.dubbo.common.URL' could not be instantiated [#3342](https://github.com/apache/dubbo/issues/3342)
|
||||
- Close Resources Properly [#3473](https://github.com/apache/dubbo/issues/3473)
|
||||
- SPI entires dup by 3 times. [#2842](https://github.com/apache/dubbo/issues/2842)
|
||||
- provider gets wrong interface name from attachment when use generic invocation in 2.6.3 [#2981](https://github.com/apache/dubbo/issues/2981)
|
||||
- HashedWheelTimer's queue gets full [#3449](https://github.com/apache/dubbo/issues/3449)
|
||||
- Modify MetadataReportRetry ThreadName [#3550](https://github.com/apache/dubbo/pull/3550)
|
||||
- Keep interface key in the URL in simplify mode when it's different from path. [#3478](https://github.com/apache/dubbo/issues/3478)
|
||||
- nc is not stable in dubbo's bootstrap script [#936](https://github.com/apache/dubbo/issues/936)
|
||||
|
||||
## 2.7.0
|
||||
|
||||
Requirements: **Java 8+** required
|
||||
|
||||
Please check [here](https://github.com/apache/dubbo/blob/2.7.0-release/CHANGES.md#upgrading-and-compatibility-notifications) for notes and possible compatibility issues for upgrading from 2.6.x or lower to 2.7.0.
|
||||
|
||||
### New Features
|
||||
|
||||
- Enhancement of service governance rules.
|
||||
- Enriched Routing Rules.
|
||||
1. Conditional Routing. Supports both application-level and service-level conditions.
|
||||
2. Tag Routing. Newly introduced to better support traffic isolation, such as grey deployment.
|
||||
- Decoupling governance rules with the registry, making it easier to extend. Apollo and Zookeeper are available in this version. Nacos support is on the way...
|
||||
- Application-level Dynamic Configuration support.
|
||||
- Use YAML as the configuration language, which is more friendly to read and use.
|
||||
|
||||
- Externalized Configuration. Supports reading `dubbo.properties` hosted in remote centralized configuration center - centralized configuration.
|
||||
|
||||
- Simplified registry URL. With lower Registry memory use and less notification pressure from Service Directory, separates Configuration notification from Service Discovery.
|
||||
|
||||
- Metadata Center. A totally new concept since 2.7.0, used to store service metadata including static configuration, service definition, method signature, etc.. By default, Zookeeper and Redis are supported as the backend storage. Will work as the basis of service testing, mock and other service governance features going to be supported in [Dubbo-Admin](https://github.com/apache/dubbo-admin).
|
||||
|
||||
- Asynchronous Programming Model (only works for Dubbo protocol now)
|
||||
- Built-in support for the method with CompletableFuture<T> signature.
|
||||
- Server-side asynchronous support, with an AsyncContext API works like Servlet 3.0.
|
||||
- Asynchronous filter chain callback.
|
||||
|
||||
- Serialization Extension: Protobuf.
|
||||
|
||||
- Caching Policy Extension: Expiring Cache.
|
||||
|
||||
### Enhancements / Bugfixes
|
||||
|
||||
- Load Balancing strategy enhancement: ConsitentHash #2190, LeastActive #2171, Random #2597, RoundRobin #2650.
|
||||
|
||||
- Third-party dependency upgrading.
|
||||
- Switch default remoting to Netty 4.
|
||||
- Switch default Zookeeper client to Curator.
|
||||
- Upgrade Jetty to 9.x.
|
||||
|
||||
- IPV6 support #2079.
|
||||
|
||||
- Performance tuning, check hanging requests on a closed channel, make them return directly #2185.
|
||||
|
||||
- Fixed the serialization problem of JDK primitive types in Kryo #2178.
|
||||
|
||||
- Fixed the problem of failing to notify Consumer as early as possible after the Provider side deserialization failed #1903.
|
||||
|
||||
### Upgrading and Compatibility Notifications
|
||||
|
||||
We have always keep compatibility in mind during the whole process of 2.7.0. We even want old users to upgrade with only on pom version upgrade, but it's hard to achieve that, especially when considering that we have the package renamed in this version, so we had some tradeoffs. If you only used the Dubbo's most basic features, you may have little problems of upgrading, but if you have used some advanced features or have some SPI extensions inside, you'd better read the upgrade notifications carefully. The compatibility issues can be classified into the following 5 categories, for each part, there will have detailed dos and don'ts published later in the official website.
|
||||
|
||||
1. Interoperability between 2.7.0 and lower versions
|
||||
|
||||
2. Package renaming
|
||||
|
||||
com.alibaba.dubbo -> org.apache.dubbo
|
||||
|
||||
3. Simplification of registered URLs
|
||||
|
||||
4. Service Governance Rules
|
||||
|
||||
5. Configuration
|
||||
|
||||
## 2.6.6
|
||||
|
||||
Enhancement / New feature:
|
||||
|
||||
* tag route. #3065
|
||||
* Use Netty4 as default Netty version. #3029
|
||||
* upporting Java 8 Date/Time type when serializing with Kryo #3519
|
||||
* support config telnet #3511
|
||||
* add annotation driven in MethodConfig and ArgumentConfig #2603
|
||||
* add nacos-registry module #3296
|
||||
* add `protocol` attribute in `@Rerefence` #3555
|
||||
*support the hierarchical interface in @Service #3251
|
||||
* change the default behavior in `@EnableDubboConfig.multiple()` #3193
|
||||
* inline source code of `spring-context-support` #3192
|
||||
* Simplify externalized configuration of Dubbo Protocol name #3189
|
||||
|
||||
BugFix:
|
||||
|
||||
* update hessian-lite to 2.3.5, fix unnecessary class load #3538
|
||||
* Fix unregister when client destroyed(referenceconfig#destroy) #3502
|
||||
* SPI entires dup by 3 times #3315
|
||||
* fix Consumer throws RpcException after RegistryDirectory notify in high QPS #2016
|
||||
* fix NPE in @Reference when using Junit to test dubbo service #3429
|
||||
* fix consumer always catch java.lang.reflect.UndeclaredThrowableException for any exception throws in provider #3386
|
||||
* fix the priority of `DubboConfigConfigurationSelector ` #2897
|
||||
* fix `@Rerefence#parameters()` not work #2301
|
||||
|
||||
## 2.6.5
|
||||
|
||||
Enhancements / Features:
|
||||
|
||||
- Reactor the generation rule for @Service Bean name [#2235](https://github.com/apache/dubbo/issues/2235)
|
||||
- Introduce a new Spring ApplicationEvent for ServiceBean exporting [#2251](https://github.com/apache/dubbo/issues/2251)
|
||||
- [Enhancement] the algorithm of load issue on Windows. [#1641](https://github.com/apache/dubbo/issues/1641)
|
||||
- add javadoc to dubbo-all module good first issue. [#2600](https://github.com/apache/dubbo/issues/2600)
|
||||
- [Enhancement] Reactor the generation rule for @Service Bean name type/enhancement [#2235](https://github.com/apache/dubbo/issues/2235)
|
||||
- Optimize LeastActiveLoadBalance and add weight test case. [#2540](https://github.com/apache/dubbo/issues/2540)
|
||||
- Smooth Round Robin selection. [#2578](https://github.com/apache/dubbo/issues/2578) [#2647](https://github.com/apache/dubbo/pull/2647)
|
||||
- [Enhancement] Resolve the placeholders for sub-properties. [#2297](https://github.com/apache/dubbo/issues/2297)
|
||||
- Add ability to turn off SPI auto injection, special support for generic Object type injection. [#2681](https://github.com/apache/dubbo/pull/2681)
|
||||
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- @Service(register=false) is not work. [#2063](https://github.com/apache/dubbo/issues/2063)
|
||||
- Our customized serialization id exceeds the maximum limit, now it cannot work on 2.6.2 anymore. [#1903](https://github.com/apache/dubbo/issues/1903)
|
||||
- Consumer throws RpcException after RegistryDirectory notify in high QPS. [#2016](https://github.com/apache/dubbo/issues/2016)
|
||||
- Annotation @Reference can't support to export a service with a sync one and an async one . [#2194](https://github.com/apache/dubbo/issues/2194)
|
||||
- `org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#generateReferenceBeanCacheKey` has a bug. [#2522](https://github.com/apache/dubbo/issues/2522)
|
||||
- 2.6.x Spring Event & Bugfix. [#2256](https://github.com/apache/dubbo/issues/2256)
|
||||
- Fix incorrect descriptions for dubbo-serialization module. [#2665](https://github.com/apache/dubbo/issues/2665)
|
||||
- A empty directory dubbo-config/dubbo-config-spring/src/test/resources/work after package source tgz. [#2560](https://github.com/apache/dubbo/issues/2560)
|
||||
- Fixed 2.6.x branch a minor issue with doConnect not using getConnectTimeout() in NettyClient. (*No issue*). [#2622](https://github.com/apache/dubbo/pull/2622)
|
||||
- Bean name of @service annotated class does not resolve placeholder. [#1755](https://github.com/apache/dubbo/issues/1755)
|
||||
|
||||
|
||||
|
||||
Issues and Pull Requests, check [milestone-2.6.5](https://github.com/apache/dubbo/milestone/21).
|
||||
|
||||
## 2.6.4
|
||||
|
||||
Enhancements / Features
|
||||
|
||||
- Support access Redis with password, [#2146](https://github.com/apache/dubbo/pull/2146)
|
||||
- Support char array for GenericService, [#2137](https://github.com/apache/dubbo/pull/2137)
|
||||
- Direct return when the server goes down abnormally, [#2451](https://github.com/apache/dubbo/pull/2451)
|
||||
- Add log for trouble-shooting when qos start failed, [#2455](https://github.com/apache/dubbo/pull/2455)
|
||||
- PojoUtil support subclasses of java.util.Date, [#2502](https://github.com/apache/dubbo/pull/2502)
|
||||
- Add ip and application name for MonitorService, [#2166](https://github.com/apache/dubbo/pull/2166)
|
||||
- New ASCII logo, [#2402](https://github.com/apache/dubbo/pull/2402)
|
||||
|
||||
Bugfixes
|
||||
|
||||
- Change consumer retries default value from 0 to 2, [#2303](https://github.com/apache/dubbo/pull/2303)
|
||||
- Fix the problem that attachment is lost when retry, [#2024](https://github.com/apache/dubbo/pull/2024)
|
||||
- Fix NPE when telnet get a null parameter, [#2453](https://github.com/apache/dubbo/pull/2453)
|
||||
|
||||
UT stability
|
||||
|
||||
- Improve the stability by changing different port, setting timeout to 3000ms, [#2501](https://github.com/apache/dubbo/pull/2501)
|
||||
|
||||
Issues and Pull Requests, check [milestone-2.6.4](https://github.com/apache/dubbo/milestone/19).
|
||||
|
||||
## 2.6.3
|
||||
|
||||
Enhancements / Features
|
||||
|
||||
- Support implicit delivery of attachments from provider to consumer, #889
|
||||
- Support inject Spring bean to SPI by bean type, #1837
|
||||
- Add generic invoke and attachments support for http&hessian protocol, #1827
|
||||
- Get the real methodname to support consistenthash for generic invoke, #1872
|
||||
- Remove validation key from provider url on Consumer side, config depedently, #1386
|
||||
- Introducing the Bootstrap module as a unified entry for Dubbo startup and resource destruction, #1820
|
||||
- Open TCP_NODELAY on Netty 3, #1746
|
||||
- Support specify proxy type on provider side, #1873
|
||||
- Support dbindex in redis, #1831
|
||||
- Upgrade tomcat to 8.5.31, #1781
|
||||
|
||||
Bugfixes
|
||||
|
||||
- ExecutionDispatcher meet with user docs, #1089
|
||||
- Remove side effects of Dubbo custom loggers on Netty logger, #1717
|
||||
- Fix isShutdown() judge of Dubbo biz threadpool always return true, #1426
|
||||
- Selection of invoker node under the critical condition of only two nodes, #1759
|
||||
- Listener cann't be removed during unsubscribe when use ZK as registry, #1792
|
||||
- URL parsing problem when user filed contains '@', #1808
|
||||
- Check null in CacheFilter to avoid NPE, #1828
|
||||
- Fix potential deadlock in DubboProtocol, #1836
|
||||
- Restore the bug that attachment has not been updated in the RpcContext when the Dubbo built-in retry mechanism is triggered, #1453
|
||||
- Some other small bugfixes
|
||||
|
||||
Performance Tuning
|
||||
|
||||
- ChannelState branch prediction optimization. #1643
|
||||
- Optimize AtomicPositiveInteger, less memory and compute cost, #348
|
||||
- Introduce embedded Threadlocal to replace the JDK implementation, #1745
|
||||
|
||||
Hessian-lite
|
||||
|
|
@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
|||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dev@dubbo.apache.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dubbo@googlegroups.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,76 +1,25 @@
|
|||
|
||||
## Contributing to Dubbo
|
||||
Dubbo is released under the non-restrictive Apache 2.0 licenses and follows a very standard Github development process, using Github tracker for issues and merging pull requests into master. Contributions of all form to this repository is acceptable, as long as it follows the prescribed community guidelines enumerated below.
|
||||
|
||||
## Contributing to dubbo
|
||||
Dubbo is released under the non-restrictive Apache 2.0 license, and follows a very standard Github development process, using Github tracker for issues and merging pull requests into master. If you want to contribute even something trivial please do not hesitate, but follow the guidelines below.
|
||||
### Sign the Contributor License Agreement
|
||||
Before we accept a non-trivial patch or pull request (PRs), we will need you to sign the Contributor License Agreement. Signing the contributors' agreement does not grant anyone commits rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors may get invited to join the core team that will grant them privileges to merge existing PRs.
|
||||
|
||||
### Contact
|
||||
|
||||
#### Mailing list
|
||||
|
||||
The mailing list is the recommended way of pursuing a discussion on almost anything related to Dubbo. Please refer to this [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide) for detailed documentation on how to subscribe.
|
||||
|
||||
- [dev@dubbo.apache.org](mailto:dev-subscribe@dubbo.apache.org): the developer mailing list where you can ask questions about an issue you may have encountered while working with Dubbo.
|
||||
- [commits@dubbo.apache.org](mailto:commits-subscribe@dubbo.apache.org): the commit updates will get broadcasted on this mailing list. You can subscribe to it, should you be interested in following Dubbo's development.
|
||||
- [notifications@dubbo.apache.org](mailto:notifications-subscribe@dubbo.apache.org): all the Github [issue](https://github.com/apache/dubbo/issues) updates and [pull request](https://github.com/apache/dubbo/pulls) updates will be sent to this mailing list.
|
||||
|
||||
### Reporting issue
|
||||
|
||||
Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
|
||||
|
||||
Before we accept a non-trivial patch or pull request we will need you to sign the Contributor License Agreement. Signing the contributor’s agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.
|
||||
### Code Conventions
|
||||
Our code style is almost in line with the standard java conventions (Popular IDE's default setting satisfy this), with the following additional restricts:
|
||||
* If there are more than 120 characters in the current line, begin a new line.
|
||||
Our code style is almost in line with the standard java conventions(Popular IDE's default setting satisfy this), only changed the following two restricts:
|
||||
1. Classes under 'com.alibaba.*' and 'com.taobao.*' package are grouped separately, and put on top of all other 'imports'.
|
||||
2. If there are more than 120 characters in current line, start a new line.
|
||||
|
||||
* Make sure all new .java files to have a simple Javadoc class comment with at least a @date tag identifying birth, and preferably at least a paragraph on the intended purpose of the class.
|
||||
We provide a template file [dubbo_codestyle_for_idea.xml](https://github.com/alibaba/dubbo/tree/master/codestyle/dubbo_codestyle_for_idea.xml) for IntelliJ idea, you can import it to you IDE. If you use Eclipse you can config manually by referencing the same file.
|
||||
|
||||
* Make sure all new .java files to have a simple Javadoc class comment with at least an @author tag identifying you, and a @date tag identifying birth, and preferably at least a paragraph on what the class is for.
|
||||
|
||||
* Add the ASF license header comment to all new .java files (copy from existing files in the project)
|
||||
|
||||
* Make sure no @author tag gets appended to the file you contribute to as the @author tag is incompatible with Apache. Rest assured, other ways, including CVS, will ensure transparency, fairness in recording your contributions.
|
||||
* Add yourself as an @author to the .java files that you modify substantially (more than cosmetic changes).
|
||||
|
||||
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
|
||||
|
||||
* Sufficient unit-tests should accompany new feature development or non-trivial bug fixes.
|
||||
* A few unit tests should be added for a new feature or an important bugfix.
|
||||
|
||||
* If no-one else is using your branch, please rebase it against the current master (or another target branch in the main project).
|
||||
|
||||
* When writing a commit message, please follow the following conventions: should your commit address an open issue, please add Fixes #XXX at the end of the commit message (where XXX is the issue number).
|
||||
|
||||
### Contribution flow
|
||||
|
||||
A rough outline of an ideal contributors' workflow is as follows:
|
||||
|
||||
* Fork the current repository
|
||||
* Create a topic branch from where to base the contribution. Mostly, it's the master branch.
|
||||
* Make commits of logical units.
|
||||
* Make sure the commit messages are in the proper format (see below).
|
||||
* Push changes in a topic branch to your forked repository.
|
||||
* Follow the checklist in the [pull request template](https://github.com/apache/dubbo/blob/master/PULL_REQUEST_TEMPLATE.md)
|
||||
* Before sending out the pull request, please sync your forked repository with the remote repository to ensure that your PR is elegant, concise. Reference the guide below:
|
||||
```
|
||||
git remote add upstream git@github.com:apache/dubbo.git
|
||||
git fetch upstream
|
||||
git rebase upstream/master
|
||||
git checkout -b your_awesome_patch
|
||||
... add some work
|
||||
git push origin your_awesome_patch
|
||||
```
|
||||
* Submit a pull request to apache/dubbo and wait for the reply.
|
||||
|
||||
Thanks for contributing!
|
||||
|
||||
### Code style
|
||||
|
||||
We provide a template file [dubbo_codestyle_for_idea.xml](https://github.com/apache/dubbo/tree/master/codestyle/dubbo_codestyle_for_idea.xml) for IntelliJ idea that you can import it to your workplace.
|
||||
If you use Eclipse, you can use the IntelliJ Idea template for manually configuring your file.
|
||||
|
||||
**NOTICE**
|
||||
|
||||
It's critical to set the dubbo_codestyle_for_idea.xml to avoid the failure of your Travis CI builds. Steps to configure the code styles are as follows:
|
||||
|
||||
1. Enter `Editor > Code Style`
|
||||
2. To manage a code style scheme, in the Code Style page, select the desired scheme from the drop-down list, and click on .
|
||||
From the drop-down list, select `Import Scheme`, then choose the option `IntelliJ IDEA code style XML` to import the scheme.
|
||||
3. In the Scheme field, type the name of the new scheme and press ⏎ to save the changes.
|
||||
* If no-one else is using your branch, please rebase it against the current master (or other target branch in the main project).
|
||||
|
||||
* When writing a commit message please follow these conventions, if you are fixing an existing issue please add Fixes #XXX at the end of the commit message (where XXX is the issue number).
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
import groovy.json.JsonSlurper
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
node {
|
||||
label 'ubuntu'
|
||||
}
|
||||
}
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(daysToKeepStr: '14', artifactNumToKeepStr: '10'))
|
||||
}
|
||||
|
||||
environment {
|
||||
JAVA_HOME = "${tool 'JDK 1.8 (latest)'}"
|
||||
}
|
||||
|
||||
tools {
|
||||
maven 'Maven 3 (latest)'
|
||||
jdk 'JDK 1.8 (latest)'
|
||||
}
|
||||
|
||||
triggers {
|
||||
cron '''TZ=Asia/Shanghai
|
||||
H 2,14 * * *'''
|
||||
pollSCM '''TZ=Asia/Shanghai
|
||||
H H/2 * * *'''
|
||||
}
|
||||
|
||||
|
||||
stages {
|
||||
stage('Clone') {
|
||||
steps {
|
||||
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', noTags: true, reference: '', shallow: true]], gitTool: 'Default', submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/apache/dubbo.git']]])
|
||||
}
|
||||
}
|
||||
|
||||
stage('Duplicate deploy check') {
|
||||
steps {
|
||||
script {
|
||||
def deployedCommitId = sh(returnStdout: true, script: "curl --silent https://builds.apache.org/job/Apache%20Dubbo/job/${env.JOB_BASE_NAME}/lastSuccessfulBuild/artifact/DEPLOY_COMMIT_ID || true").trim()
|
||||
env.DEPLOYED_COMMIT_ID = deployedCommitId
|
||||
def commitId = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
|
||||
env.COMMIT_ID = commitId
|
||||
|
||||
if (commitId == deployedCommitId) {
|
||||
env.STATUS_CHECK = "false"
|
||||
println "Latest deployed commit id is $deployedCommitId, Skip deployment this time"
|
||||
} else {
|
||||
env.STATUS_CHECK = "true"
|
||||
println "Current commit id hasn't been deployed, continue"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Commit status check') {
|
||||
when {
|
||||
expression {
|
||||
return env.STATUS_CHECK == "true";
|
||||
}
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
def commitId = env.COMMIT_ID
|
||||
println "Current commit id: $commitId"
|
||||
|
||||
def commitStatusJson = sh(script: "curl --silent https://api.github.com/repos/apache/dubbo/commits/$commitId/status", returnStdout: true).trim()
|
||||
println "Commit status: \r\n$commitStatusJson"
|
||||
|
||||
def jsonSlurper = new JsonSlurper()
|
||||
def jsonObject = jsonSlurper.parseText(commitStatusJson)
|
||||
|
||||
def status = jsonObject.state
|
||||
|
||||
println "Current commit status is $status"
|
||||
|
||||
if (status == "success") {
|
||||
env.STATUS_CHECK = "true"
|
||||
println "Continue to deploy snapshot"
|
||||
} else {
|
||||
env.STATUS_CHECK = "false"
|
||||
println "Current commit status not allow to deploy snapshot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Snapshot version check') {
|
||||
when {
|
||||
expression {
|
||||
return env.STATUS_CHECK == "true";
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'env'
|
||||
sh 'java -version'
|
||||
sh './mvnw clean install -pl "dubbo-dependencies-bom" && ./mvnw clean install -DskipTests=true && ./mvnw clean validate -Psnapshot-ci-deploy -pl "dubbo-all"'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy snapshot') {
|
||||
when {
|
||||
expression {
|
||||
return env.STATUS_CHECK == "true";
|
||||
}
|
||||
}
|
||||
steps {
|
||||
timeout(40) {
|
||||
sh './mvnw --version'
|
||||
sh './mvnw clean package deploy -pl dubbo-dependencies-bom && ./mvnw clean source:jar javadoc:jar package deploy -DskipTests=true'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Save deployed commit id') {
|
||||
steps {
|
||||
script {
|
||||
if (env.STATUS_CHECK != "true") {
|
||||
println "Not pass status check"
|
||||
env.COMMIT_ID = env.DEPLOYED_COMMIT_ID
|
||||
}
|
||||
}
|
||||
writeFile file: 'DEPLOY_COMMIT_ID', text: "${env.COMMIT_ID}"
|
||||
archiveArtifacts 'DEPLOY_COMMIT_ID'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
failure {
|
||||
mail bcc: '', body: '''Project: ${env.JOB_NAME}
|
||||
Build Number: ${env.BUILD_NUMBER}
|
||||
URL: ${env.BUILD_URL}''', cc: '', from: '', replyTo: '', subject: 'Apache Dubbo snapshot deployment fail', to: 'dev@dubbo.apache.org'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,51 +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.
|
||||
*
|
||||
*/
|
||||
pipeline {
|
||||
agent {
|
||||
label 'ubuntu'
|
||||
}
|
||||
|
||||
tools {
|
||||
maven 'maven_3_latest'
|
||||
jdk 'jdk_11_latest'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Code Quality') {
|
||||
steps {
|
||||
echo 'Checking Code Quality on SonarCloud'
|
||||
script {
|
||||
// Main parameters
|
||||
def sonarcloudParams=""
|
||||
if ( env.BRANCH_NAME.startsWith("PR-") ) {
|
||||
// this is a pull request
|
||||
withCredentials([string(credentialsId: 'sonarcloud-token', variable: 'SONAR_TOKEN')]) {
|
||||
sh './mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean verify sonar:sonar -Dmaven.test.skip=true -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=apache -Dsonar.projectKey=apache_dubbo -Dsonar.coverage.jacoco.xmlReportPaths=dubbo-test/dubbo-dependencies-all/target/site/jacoco-aggregate/jacoco.xml -Dsonar.pullrequest.branch=${CHANGE_BRANCH} -Dsonar.pullrequest.base=${CHANGE_TARGET} -Dsonar.pullrequest.key=${CHANGE_ID} -Dsonar.login=${SONAR_TOKEN}'
|
||||
}
|
||||
} else {
|
||||
// this is just a branch
|
||||
withCredentials([string(credentialsId: 'sonarcloud-token', variable: 'SONAR_TOKEN')]) {
|
||||
sh './mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean verify sonar:sonar -Dmaven.test.skip=true -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=apache -Dsonar.projectKey=apache_dubbo -Dsonar.coverage.jacoco.xmlReportPaths=dubbo-test/dubbo-dependencies-all/target/site/jacoco-aggregate/jacoco.xml -Dsonar.branch.name=${BRANCH_NAME} -Dsonar.login=${SONAR_TOKEN}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
LICENSE
89
LICENSE
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
|
@ -186,7 +187,6 @@
|
|||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
@ -200,90 +200,3 @@
|
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
Apache Dubbo Submodules:
|
||||
|
||||
Apache Dubbo includes a number of submodules with separate copyright notices
|
||||
and license terms. Your use of these submodules is subject to the terms and
|
||||
conditions of the following licenses.
|
||||
|
||||
For the package org.apache.dubbo.common.threadlocal and org.apache.dubbo.common.timer:
|
||||
|
||||
This product contains a modified portion of 'Netty', an event-driven asynchronous network application framework also
|
||||
under a "Apache License 2.0" license, see https://github.com/netty/netty/blob/4.1/LICENSE.txt:
|
||||
|
||||
* io.netty.util.concurrent.FastThreadLocal
|
||||
* io.netty.util.internal.InternalThreadLocalMap
|
||||
* io.netty.util.Timer
|
||||
* io.netty.util.TimerTask
|
||||
* io.netty.util.Timeout
|
||||
* io.netty.util.HashedWheelTimer
|
||||
|
||||
For the org.apache.dubbo.common.utils.CIDRUtils :
|
||||
|
||||
This product contains a modified portion of 'edazdarevic.commons.net.CIDRUtils' published at
|
||||
https://github.com/edazdarevic/CIDRUtils. The project is licensed under a MIT License:
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2013 Edin Dazdarevic (edin.dazdarevic@gmail.com)
|
||||
* 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.
|
||||
|
||||
For the file org.apache.dubbo.common.utils.Utf8Utils.java:
|
||||
|
||||
This product contains a portion of the Protocol Buffers project, which is published at
|
||||
https://developers.google.com/protocol-buffers/ and is licensed under the following License:
|
||||
|
||||
Copyright 2008 Google Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Code generated by the Protocol Buffer compiler is owned by the owner
|
||||
of the input file used when generating it. This code is not
|
||||
standalone and requires a support library to be linked with it. This
|
||||
support library is itself covered by the above license.
|
||||
|
||||
For the ca.proto in dubbo-registry-xds:
|
||||
|
||||
This product contains a modified portion of 'Istio', an open platform to connect, manage, and secure microservices also
|
||||
under a "Apache License 2.0" license, see https://github.com/istio/api/blob/master/LICENSE:
|
||||
|
||||
* security/v1alpha1/ca.proto
|
||||
|
|
|
|||
287
NOTICE
287
NOTICE
|
|
@ -1,18 +1,269 @@
|
|||
Apache Dubbo
|
||||
Copyright 2018-2024 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:
|
||||
|
||||
The Netty Project
|
||||
=================
|
||||
Please visit the Netty web site for more information:
|
||||
* http://netty.io/
|
||||
|
||||
Copyright 2014 The Netty Project
|
||||
|
||||
This product contains code form the t-digest Project:
|
||||
The code for the t-digest was originally authored by Ted Dunning
|
||||
Adrien Grand contributed the heart of the AVLTreeDigest (https://github.com/jpountz)
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
================================================================
|
||||
Dependencies:
|
||||
|
||||
Spring:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://www.springsource.org
|
||||
|
||||
Javassist:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://www.jboss.org/javassist
|
||||
|
||||
Netty:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://netty.io
|
||||
|
||||
Mina:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://mina.apache.org
|
||||
|
||||
Grizzly:
|
||||
|
||||
* LICENSE:
|
||||
* https://opensource.org/licenses/cddl-1.0 (CDDL 1.1)
|
||||
* HOMEPAGE:
|
||||
* https://javaee.github.io/grizzly/
|
||||
|
||||
HttpClient:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://hc.apache.org
|
||||
|
||||
Hessian:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://hessian.caucho.com
|
||||
|
||||
XStream:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://xstream.codehaus.org
|
||||
|
||||
FastJson:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* https://github.com/alibaba/fastjson
|
||||
|
||||
Zookeeper:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://zookeeper.apache.org
|
||||
|
||||
Jedis:
|
||||
|
||||
* LICENSE:
|
||||
* https://opensource.org/licenses/MIT (MIT)
|
||||
* HOMEPAGE:
|
||||
* https://github.com/xetorthio/jedis
|
||||
|
||||
XMemcached:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://code.google.com/p/xmemcached
|
||||
|
||||
Jetty:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://jetty.mortbay.org
|
||||
|
||||
Thrift:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://thrift.apache.org
|
||||
|
||||
CXF:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://cxf.apache.org
|
||||
|
||||
ZKClient:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* https://github.com/sgroschupf/zkclient
|
||||
|
||||
Curator
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* https://github.com/Netflix/curator
|
||||
|
||||
JFreeChart:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://www.jfree.org
|
||||
|
||||
validation-api:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://beanvalidation.org
|
||||
|
||||
HibernateValidator:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://www.hibernate.org/subprojects/validator.html
|
||||
|
||||
CommonsLogging:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://commons.apache.org/logging
|
||||
|
||||
SLF4J:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://www.slf4j.org
|
||||
|
||||
Log4j:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://log4j.apache.org
|
||||
|
||||
Tomcat:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://tomcat.apache.org
|
||||
|
||||
cache-api:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* https://github.com/jsr107/jsr107spec
|
||||
|
||||
easymock
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://easymock.org
|
||||
|
||||
cglib-nodep
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* https://sourceforge.net/projects/cglib/
|
||||
|
||||
resteasy
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://resteasy.jboss.org/
|
||||
|
||||
fst
|
||||
|
||||
* LICENSE:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
|
||||
* HOMEPAGE:
|
||||
* http://ruedigermoeller.github.io/fast-serialization
|
||||
|
||||
jmockit
|
||||
|
||||
* LICENSE:
|
||||
* https://opensource.org/licenses/MIT (MIT)
|
||||
* HOMEPAGE:
|
||||
* http://www.jmockit.org
|
||||
|
||||
jedis
|
||||
|
||||
* LICENSE:
|
||||
* https://opensource.org/licenses/MIT (MIT)
|
||||
* HOMEPAGE:
|
||||
* http://www.jmockit.org
|
||||
|
||||
javax.servlet-api:
|
||||
|
||||
* LICENSE:
|
||||
* https://opensource.org/licenses/cddl-1.0 (CDDL 1.1)
|
||||
* HOMEPAGE:
|
||||
* http://servlet-spec.java.net
|
||||
|
||||
javax.el:
|
||||
|
||||
* LICENSE:
|
||||
* https://opensource.org/licenses/cddl-1.0 (CDDL 1.1)
|
||||
* HOMEPAGE:
|
||||
* https://javaee.github.io/uel-ri/
|
||||
|
||||
logback-classic:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.eclipse.org/legal/epl-v10.html (EPL 1.0)
|
||||
* HOMEPAGE:
|
||||
* https://logback.qos.ch/
|
||||
|
||||
junit:
|
||||
|
||||
* LICENSE:
|
||||
* http://www.eclipse.org/legal/epl-v10.html (EPL 1.0)
|
||||
* HOMEPAGE:
|
||||
* http://www.junit.org
|
||||
|
||||
kryo:
|
||||
|
||||
* LICENSE:
|
||||
* https://opensource.org/licenses/BSD-3-Clause (BSD 3-clause)
|
||||
* HOMEPAGE:
|
||||
* https://github.com/EsotericSoftware/kryo
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
## What is the purpose of the change
|
||||
|
||||
XXXXX
|
||||
|
||||
## Brief changelog
|
||||
|
||||
XX
|
||||
|
||||
## Verifying this change
|
||||
|
||||
XXXX
|
||||
|
||||
Follow this checklist to help us incorporate your contribution quickly and easily:
|
||||
|
||||
- [x] Make sure there is a [GITHUB_issue](https://github.com/alibaba/dubbo/issues) filed 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.
|
||||
- [ ] Format the pull request title like `[Dubbo-XXX] Fix UnknownException when host config not exist`. 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.
|
||||
- [ ] 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 integration-test in [test module](https://github.com/alibaba/dubbo/tree/master/dubbo-test).
|
||||
- [ ] Run `mvn clean install -DskipITs` to make sure unit-test pass. Run `mvn clean test-compile failsafe:integration-test` to make sure integration-test pass.
|
||||
- [ ] If this contribution is large, please file an [Apache Individual Contributor License Agreement](http://www.apache.org/licenses/#clas).
|
||||
282
README.md
282
README.md
|
|
@ -1,272 +1,18 @@
|
|||
# Apache Dubbo Project
|
||||
# Dubbo Project
|
||||
|
||||
[](https://github.com/apache/dubbo/actions/workflows/build-and-test-pr.yml)
|
||||
[](https://codecov.io/gh/apache/dubbo)
|
||||

|
||||

|
||||
[](http://isitmaintained.com/project/apache/dubbo "Average time to resolve an issue")
|
||||
[](http://isitmaintained.com/project/apache/dubbo "Percentage of issues still open")
|
||||
[](https://travis-ci.org/apache/incubator-dubbo)
|
||||
[](https://codecov.io/gh/apache/incubator-dubbo)
|
||||
[](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.
|
||||
This version has been announced as EOF, it's no longer maintained by the official team. We recommend use the latest [2.7.x](https://github.com/apache/dubbo) version
|
||||
|
||||
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 :)
|
||||
## Links
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Transparent interface based RPC
|
||||
* Intelligent load balancing
|
||||
* Automatic service registration and discovery
|
||||
* High extensibility
|
||||
* Runtime traffic routing
|
||||
* Visualized service governance
|
||||
|
||||
## Getting started
|
||||
|
||||
The following code snippet comes from [Dubbo Samples](https://github.com/apache/dubbo-samples.git). You may clone the sample project and step into the `dubbo-samples-api` subdirectory before proceeding.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/apache/dubbo-samples.git
|
||||
cd dubbo-samples/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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
|
||||
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();
|
||||
|
||||
System.out.println("dubbo service started");
|
||||
new CountDownLatch(1).await();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*See [provider/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-spring-xml/src/main/java/org/apache/dubbo/samples/provider/Application.java) on GitHub.*
|
||||
|
||||
### Build and run the provider
|
||||
|
||||
```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.
|
||||
|
||||
## Contact
|
||||
|
||||
* Mailing list:
|
||||
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
|
||||
|
||||
* Bugs: [Issues](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md)
|
||||
* Gitter: [Gitter channel](https://gitter.im/alibaba/dubbo)
|
||||
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
|
||||
|
||||
## 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)
|
||||
|
||||
## 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.
|
||||
* [Side projects](http://github.com/dubbo)
|
||||
* [Gitter channel](https://gitter.im/alibaba/dubbo)
|
||||
* [Mailing list](https://groups.google.com/forum/#!forum/dubbo)
|
||||
* [Dubbo user manual](http://dubbo.io/books/dubbo-user-book/)
|
||||
* [Dubbo developer guide](http://dubbo.io/books/dubbo-dev-book/)
|
||||
* [Dubbo admin manual](http://dubbo.io/books/dubbo-admin-book/)
|
||||
|
|
|
|||
34
SECURITY.md
34
SECURITY.md
|
|
@ -1,34 +0,0 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
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: |
|
||||
| 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.
|
||||
|
||||
If you have apprehensions regarding Dubbo's security or you discover vulnerability or potential threat, don’t hesitate to get in touch with the Apache Dubbo Security Team by dropping a mail at security@dubbo.apache.org. In the email, specify the description of the issue or potential threat. You are also urged to recommend the way to reproduce and replicate the issue. The Dubbo community will get back to you after assessing and analysing the findings.
|
||||
|
||||
PLEASE PAY ATTENTION to report the security issue on the security email before disclosing it on public domain.
|
||||
|
||||
## Vulnerability Handling
|
||||
|
||||
An overview of the vulnerability handling process is:
|
||||
|
||||
* The reporter reports the vulnerability privately to Apache.
|
||||
* The appropriate project's security team works privately with the reporter to resolve the vulnerability.
|
||||
* A new release of the Apache product concerned is made that includes the fix.
|
||||
* The vulnerability is publicly announced.
|
||||
|
||||
A more detailed description of the process can be found [here](https://www.apache.org/security/committers.html).
|
||||
34
codecov.yml
34
codecov.yml
|
|
@ -1,34 +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.
|
||||
#
|
||||
codecov:
|
||||
require_ci_to_pass: false
|
||||
notify:
|
||||
wait_for_ci: false
|
||||
coverage:
|
||||
status:
|
||||
# pull-requests only
|
||||
patch:
|
||||
default:
|
||||
threshold: 0.1%
|
||||
ignore:
|
||||
- "**/dubbo-demo/**"
|
||||
- "**/dubbo-compiler/**"
|
||||
- "**/dubbo-test/**"
|
||||
- "**/dubbo-compatible/**"
|
||||
- "**/dubbo-native/**"
|
||||
- "**/dubbo-native-plugin/**"
|
||||
- "**/dubbo-common/src/main/java/org/apache/dubbo/common/json/*.java" # internal JSON impl is deprecate, ignore test coverage for them
|
||||
- "**/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java" # Deprecated
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
||||
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
||||
<suppressions>
|
||||
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]com[\\/]alibaba[\\/]com[\\/]caucho[\\/]hessian" checks=".*"/>
|
||||
<suppress files="[\\/]build[\\/]generated[\\/]source[\\/]proto" checks=".*"/>
|
||||
<suppress files="[\\/]target[\\/]generated-sources[\\/]protobuf" checks=".*"/>
|
||||
<suppress files="Yylex\.java" checks="AvoidEscapedUnicodeCharacters"/>
|
||||
</suppressions>
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
|
||||
|
||||
<module name="Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
|
||||
<module name="Header">
|
||||
<property name="headerFile" value="/checkstyle-header.txt"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
</module>
|
||||
|
||||
<module name="FileTabCharacter">
|
||||
<property name="fileExtensions" value="java,xml"/>
|
||||
</module>
|
||||
|
||||
<!-- TreeWalker Checks -->
|
||||
<module name="TreeWalker">
|
||||
<module name="SuppressWarningsHolder"/>
|
||||
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="AvoidEscapedUnicodeCharacters">
|
||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||
<property name="allowByTailComment" value="true"/>
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
</module>
|
||||
<module name="NoLineWrap"/>
|
||||
<module name="OuterTypeFilename"/>
|
||||
<module name="UnusedImports"/>
|
||||
<module name="RedundantImport"/>
|
||||
|
||||
<module name="EqualsHashCode"/>
|
||||
|
||||
<!--<module name="CustomImportOrder">-->
|
||||
<!--<property name="specialImportsRegExp" value="org.apache.dubbo.*"/>-->
|
||||
<!--<property name="sortImportsInGroupAlphabetically" value="false"/>-->
|
||||
<!--<property name="customImportOrderRules" value="SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC"/>-->
|
||||
<!--</module>-->
|
||||
</module>
|
||||
</module>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
|
||||
|
||||
<module name="Checker">
|
||||
<module name="NewlineAtEndOfFile">
|
||||
<property name="lineSeparator" value="lf" />
|
||||
</module>
|
||||
</module>
|
||||
|
|
@ -3,7 +3,9 @@
|
|||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99"/>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="org.apache.dubbo" withSubpackages="true" static="false"/>
|
||||
<package name="com.alibaba" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="com.taobao" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 430 B |
|
|
@ -0,0 +1,170 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT 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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-parent</artifactId>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
<artifactId>dubbo-admin</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>The admin module of dubbo project</description>
|
||||
<properties>
|
||||
<wtpversion>1.5</wtpversion>
|
||||
<wtpContextName>/</wtpContextName>
|
||||
<eclipse.useProjectReferences>false</eclipse.useProjectReferences>
|
||||
<skip_maven_deploy>false</skip_maven_deploy>
|
||||
</properties>
|
||||
<!-- Fix webx 3.x not compatible with spring 4.x or higher -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>3.2.16.RELEASE</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.citrus</groupId>
|
||||
<artifactId>citrus-webx-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.netty</groupId>
|
||||
<artifactId>netty</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.mina</groupId>
|
||||
<artifactId>mina-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.grizzly</groupId>
|
||||
<artifactId>grizzly-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.bsf</groupId>
|
||||
<artifactId>bsf-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.101tec</groupId>
|
||||
<artifactId>zkclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-framework</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.xmemcached</groupId>
|
||||
<artifactId>xmemcached</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.thrift</groupId>
|
||||
<artifactId>libthrift</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.caucho</groupId>
|
||||
<artifactId>hessian</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.cache</groupId>
|
||||
<artifactId>cache-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<configuration>
|
||||
<contextPath>/</contextPath>
|
||||
<scanIntervalSeconds>10</scanIntervalSeconds>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8080</port>
|
||||
<maxIdleTime>60000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Context
|
||||
*
|
||||
*/
|
||||
public interface PageContext {
|
||||
|
||||
public String get(String key);
|
||||
|
||||
public String[] gets(String key);
|
||||
|
||||
public Map<String, String[]> getAll();
|
||||
|
||||
public void put(String key, Object value);
|
||||
|
||||
public String getMessage(String key, Object... args);
|
||||
|
||||
public String getClientAddress();
|
||||
|
||||
public String getOperateAddress();
|
||||
|
||||
public String getRegistryAddress();
|
||||
|
||||
public String getURI();
|
||||
|
||||
public String getURL();
|
||||
|
||||
public String getReferer();
|
||||
|
||||
public User getLoginUser();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.biz.common.i18n;
|
||||
|
||||
public interface MessageResourceService {
|
||||
|
||||
public String get(String key, Object... args);
|
||||
|
||||
public String getMessage(String key, Object... args);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.biz.common.i18n.impl;
|
||||
|
||||
import com.alibaba.dubbo.governance.biz.common.i18n.MessageResourceService;
|
||||
import com.alibaba.dubbo.governance.web.common.i18n.LocaleUtil;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
|
||||
public class MessageResourceServiceImpl implements MessageResourceService {
|
||||
|
||||
@Autowired
|
||||
private MessageSource messageSource;
|
||||
|
||||
public void setMessageSource(MessageSource messageSource) {
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
public String get(String key, Object... args) {
|
||||
try {
|
||||
if (messageSource != null) {
|
||||
return messageSource.getMessage(key, args, key, LocaleUtil.getLocale());
|
||||
}
|
||||
return key;
|
||||
} catch (NoSuchMessageException e) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage(String key, Object... args) {
|
||||
return get(key, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 com.alibaba.dubbo.governance.service;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.Config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TODO Comment of ConfigDAO
|
||||
*
|
||||
*/
|
||||
public interface ConfigService {
|
||||
|
||||
void update(List<Config> configs);
|
||||
|
||||
Map<String, String> findAllConfigsMap();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.Consumer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Query service for consumer info
|
||||
*
|
||||
*/
|
||||
public interface ConsumerService {
|
||||
|
||||
List<Consumer> findByService(String serviceName);
|
||||
|
||||
Consumer findConsumer(Long id);
|
||||
|
||||
List<Consumer> findAll();
|
||||
|
||||
/**
|
||||
* query for all consumer addresses
|
||||
*/
|
||||
List<String> findAddresses();
|
||||
|
||||
List<String> findAddressesByApplication(String application);
|
||||
|
||||
List<String> findAddressesByService(String serviceName);
|
||||
|
||||
List<Consumer> findByAddress(String consumerAddress);
|
||||
|
||||
List<String> findServicesByAddress(String consumerAddress);
|
||||
|
||||
List<String> findApplications();
|
||||
|
||||
List<String> findApplicationsByServiceName(String serviceName);
|
||||
|
||||
List<Consumer> findByApplication(String application);
|
||||
|
||||
List<String> findServicesByApplication(String application);
|
||||
|
||||
List<String> findServices();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OverrideService {
|
||||
|
||||
void saveOverride(Override override);
|
||||
|
||||
void updateOverride(Override override);
|
||||
|
||||
void deleteOverride(Long id);
|
||||
|
||||
void enableOverride(Long id);
|
||||
|
||||
void disableOverride(Long id);
|
||||
|
||||
List<Override> findByService(String service);
|
||||
|
||||
List<Override> findByAddress(String address);
|
||||
|
||||
List<Override> findByServiceAndAddress(String service, String address);
|
||||
|
||||
List<Override> findByApplication(String application);
|
||||
|
||||
List<Override> findByServiceAndApplication(String service, String application);
|
||||
|
||||
List<Override> findAll();
|
||||
|
||||
Override findById(Long id);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.Owner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface OwnerService {
|
||||
|
||||
List<String> findAllServiceNames();
|
||||
|
||||
List<String> findServiceNamesByUsername(String username);
|
||||
|
||||
List<String> findUsernamesByServiceName(String serviceName);
|
||||
|
||||
List<Owner> findByService(String serviceName);
|
||||
|
||||
List<Owner> findAll();
|
||||
|
||||
Owner findById(Long id);
|
||||
|
||||
void saveOwner(Owner owner);
|
||||
|
||||
void deleteOwner(Owner owner);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ProviderService
|
||||
*
|
||||
*/
|
||||
public interface ProviderService {
|
||||
|
||||
void create(Provider provider);
|
||||
|
||||
void enableProvider(Long id);
|
||||
|
||||
void disableProvider(Long id);
|
||||
|
||||
void doublingProvider(Long id);
|
||||
|
||||
void halvingProvider(Long id);
|
||||
|
||||
void deleteStaticProvider(Long id);
|
||||
|
||||
void updateProvider(Provider provider);
|
||||
|
||||
Provider findProvider(Long id);
|
||||
|
||||
List<String> findServices();
|
||||
|
||||
List<String> findAddresses();
|
||||
|
||||
List<String> findAddressesByApplication(String application);
|
||||
|
||||
List<String> findAddressesByService(String serviceName);
|
||||
|
||||
List<String> findApplicationsByServiceName(String serviceName);
|
||||
|
||||
List<Provider> findByService(String serviceName);
|
||||
|
||||
List<Provider> findAll();
|
||||
|
||||
List<Provider> findByAddress(String providerAddress);
|
||||
|
||||
List<String> findServicesByAddress(String providerAddress);
|
||||
|
||||
List<String> findApplications();
|
||||
|
||||
List<Provider> findByApplication(String application);
|
||||
|
||||
List<String> findServicesByApplication(String application);
|
||||
|
||||
List<String> findMethodsByService(String serviceName);
|
||||
|
||||
Provider findByServiceAndAddress(String service, String address);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.Route;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* RouteService
|
||||
*
|
||||
*/
|
||||
public interface RouteService {
|
||||
|
||||
void createRoute(Route route);
|
||||
|
||||
void updateRoute(Route route);
|
||||
|
||||
void deleteRoute(Long id);
|
||||
|
||||
void enableRoute(Long id);
|
||||
|
||||
void disableRoute(Long id);
|
||||
|
||||
Route findRoute(Long id);
|
||||
|
||||
List<Route> findAll();
|
||||
|
||||
List<Route> findByService(String serviceName);
|
||||
|
||||
List<Route> findByAddress(String address);
|
||||
|
||||
List<Route> findByServiceAndAddress(String service, String address);
|
||||
|
||||
List<Route> findForceRouteByService(String service);
|
||||
|
||||
List<Route> findForceRouteByAddress(String address);
|
||||
|
||||
List<Route> findForceRouteByServiceAndAddress(String service, String address);
|
||||
|
||||
List<Route> findAllForceRoute();
|
||||
|
||||
}
|
||||
|
|
@ -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 com.alibaba.dubbo.governance.service;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* UserService
|
||||
*
|
||||
*/
|
||||
public interface UserService {
|
||||
|
||||
List<User> findAllUsers();
|
||||
|
||||
User findUser(String username);
|
||||
|
||||
User findById(Long id);
|
||||
|
||||
void createUser(User user);
|
||||
|
||||
void updateUser(User user);
|
||||
|
||||
void modifyUser(User user);
|
||||
|
||||
boolean updatePassword(User user, String oldPassword);
|
||||
|
||||
void resetPassword(User user);
|
||||
|
||||
void enableUser(User user);
|
||||
|
||||
void disableUser(User user);
|
||||
|
||||
void deleteUser(User user);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.governance.sync.RegistryServerSync;
|
||||
import com.alibaba.dubbo.registry.RegistryService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* IbatisDAO
|
||||
*
|
||||
*/
|
||||
public class AbstractService {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(AbstractService.class);
|
||||
@Autowired
|
||||
protected RegistryService registryService;
|
||||
@Autowired
|
||||
private RegistryServerSync sync;
|
||||
|
||||
public ConcurrentMap<String, ConcurrentMap<String, Map<Long, URL>>> getRegistryCache() {
|
||||
return sync.getRegistryCache();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.governance.service.ConfigService;
|
||||
import com.alibaba.dubbo.registry.common.domain.Config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TODO Comment of IbatisConfigDAO
|
||||
*
|
||||
*/
|
||||
public class ConfigServiceImpl extends AbstractService implements ConfigService {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.alibaba.dubbo.governance.service.ConfigService#update(java.util.List)
|
||||
*/
|
||||
public void update(List<Config> configs) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.alibaba.dubbo.governance.service.ConfigService#findAllConfigsMap()
|
||||
*/
|
||||
public Map<String, String> findAllConfigsMap() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.sync.util.Pair;
|
||||
import com.alibaba.dubbo.governance.sync.util.SyncUtils;
|
||||
import com.alibaba.dubbo.registry.common.domain.Consumer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class ConsumerServiceImpl extends AbstractService implements ConsumerService {
|
||||
|
||||
public List<Consumer> findByService(String service) {
|
||||
return SyncUtils.url2ConsumerList(findConsumerUrlByService(service));
|
||||
}
|
||||
|
||||
public Consumer findConsumer(Long id) {
|
||||
return SyncUtils.url2Consumer(findConsumerUrl(id));
|
||||
}
|
||||
|
||||
private Pair<Long, URL> findConsumerUrl(Long id) {
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), Constants.CONSUMERS_CATEGORY, id);
|
||||
}
|
||||
|
||||
public List<Consumer> findAll() {
|
||||
return SyncUtils.url2ConsumerList(findAllConsumerUrl());
|
||||
}
|
||||
|
||||
private Map<Long, URL> findAllConsumerUrl() {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<String> findAddresses() {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
if (null == consumerUrls) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : consumerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getAddress();
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findAddressesByApplication(String application) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
|
||||
if(consumerUrls == null)
|
||||
return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : consumerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) {
|
||||
String addr = u.getAddress();
|
||||
if (addr != null) ret.add(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findAddressesByService(String service) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
if (null == consumerUrls) return ret;
|
||||
|
||||
for (Map.Entry<Long, URL> e2 : consumerUrls.get(service).entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getAddress();
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Consumer> findByAddress(String consumerAddress) {
|
||||
return SyncUtils.url2ConsumerList(findConsumerUrlByAddress(consumerAddress));
|
||||
}
|
||||
|
||||
public List<String> findServicesByAddress(String address) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
if (consumerUrls == null || address == null || address.length() == 0) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : consumerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
if (address.equals(u.getAddress())) {
|
||||
ret.add(e1.getKey());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Map<Long, URL> findConsumerUrlByAddress(String address) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
|
||||
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
|
||||
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<String> findApplications() {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
if (consumerUrls == null) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : consumerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getParameter(Constants.APPLICATION_KEY);
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findApplicationsByServiceName(String service) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
if (consumerUrls == null) return ret;
|
||||
|
||||
Map<Long, URL> value = consumerUrls.get(service);
|
||||
if (value == null) {
|
||||
return ret;
|
||||
}
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getParameter(Constants.APPLICATION_KEY);
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Consumer> findByApplication(String application) {
|
||||
return SyncUtils.url2ConsumerList(findConsumerUrlByApplication(application));
|
||||
}
|
||||
|
||||
private Map<Long, URL> findConsumerUrlByApplication(String application) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
|
||||
filter.put(Constants.APPLICATION_KEY, application);
|
||||
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<String> findServicesByApplication(String application) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
if (consumerUrls == null || application == null || application.length() == 0) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : consumerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) {
|
||||
ret.add(e1.getKey());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findServices() {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY);
|
||||
if (consumerUrls != null) ret.addAll(consumerUrls.keySet());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Map<Long, URL> findConsumerUrlByService(String service) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY);
|
||||
filter.put(SyncUtils.SERVICE_FILTER_KEY, service);
|
||||
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.sync.util.Pair;
|
||||
import com.alibaba.dubbo.governance.sync.util.SyncUtils;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IbatisOverrideDAO.java
|
||||
*
|
||||
*/
|
||||
public class OverrideServiceImpl extends AbstractService implements OverrideService {
|
||||
|
||||
public void saveOverride(Override override) {
|
||||
URL url = getUrlFromOverride(override);
|
||||
registryService.register(url);
|
||||
}
|
||||
|
||||
public void updateOverride(Override override) {
|
||||
Long id = override.getId();
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no override id");
|
||||
}
|
||||
URL oldOverride = findOverrideUrl(id);
|
||||
if (oldOverride == null) {
|
||||
throw new IllegalStateException("Route was changed!");
|
||||
}
|
||||
URL newOverride = getUrlFromOverride(override);
|
||||
|
||||
registryService.unregister(oldOverride);
|
||||
registryService.register(newOverride);
|
||||
|
||||
}
|
||||
|
||||
public void deleteOverride(Long id) {
|
||||
URL oldOverride = findOverrideUrl(id);
|
||||
if (oldOverride == null) {
|
||||
throw new IllegalStateException("Route was changed!");
|
||||
}
|
||||
registryService.unregister(oldOverride);
|
||||
}
|
||||
|
||||
public void enableOverride(Long id) {
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no override id");
|
||||
}
|
||||
|
||||
URL oldOverride = findOverrideUrl(id);
|
||||
if (oldOverride == null) {
|
||||
throw new IllegalStateException("Override was changed!");
|
||||
}
|
||||
if (oldOverride.getParameter("enabled", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
URL newOverride = oldOverride.addParameter("enabled", true);
|
||||
registryService.unregister(oldOverride);
|
||||
registryService.register(newOverride);
|
||||
|
||||
}
|
||||
|
||||
public void disableOverride(Long id) {
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no override id");
|
||||
}
|
||||
|
||||
URL oldProvider = findOverrideUrl(id);
|
||||
if (oldProvider == null) {
|
||||
throw new IllegalStateException("Override was changed!");
|
||||
}
|
||||
if (!oldProvider.getParameter("enabled", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
URL newProvider = oldProvider.addParameter("enabled", false);
|
||||
registryService.unregister(oldProvider);
|
||||
registryService.register(newProvider);
|
||||
|
||||
}
|
||||
|
||||
private Map<Long, URL> findOverrideUrl(String service, String address, String application) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.CONFIGURATORS_CATEGORY);
|
||||
if (service != null && service.length() > 0) {
|
||||
filter.put(SyncUtils.SERVICE_FILTER_KEY, service);
|
||||
}
|
||||
if (address != null && address.length() > 0) {
|
||||
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
|
||||
}
|
||||
if (application != null && application.length() > 0) {
|
||||
filter.put(Constants.APPLICATION_KEY, application);
|
||||
}
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<Override> findByAddress(String address) {
|
||||
return SyncUtils.url2OverrideList(findOverrideUrl(null, address, null));
|
||||
}
|
||||
|
||||
public List<Override> findByServiceAndAddress(String service, String address) {
|
||||
return SyncUtils.url2OverrideList(findOverrideUrl(service, address, null));
|
||||
}
|
||||
|
||||
public List<Override> findByApplication(String application) {
|
||||
return SyncUtils.url2OverrideList(findOverrideUrl(null, null, application));
|
||||
}
|
||||
|
||||
public List<Override> findByService(String service) {
|
||||
return SyncUtils.url2OverrideList(findOverrideUrl(service, null, null));
|
||||
}
|
||||
|
||||
public List<Override> findByServiceAndApplication(String service, String application) {
|
||||
return SyncUtils.url2OverrideList(findOverrideUrl(service, null, application));
|
||||
}
|
||||
|
||||
public List<Override> findAll() {
|
||||
return SyncUtils.url2OverrideList(findOverrideUrl(null, null, null));
|
||||
}
|
||||
|
||||
private Pair<Long, URL> findOverrideUrlPair(Long id) {
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), Constants.CONFIGURATORS_CATEGORY, id);
|
||||
}
|
||||
|
||||
public Override findById(Long id) {
|
||||
return SyncUtils.url2Override(findOverrideUrlPair(id));
|
||||
}
|
||||
|
||||
private URL getUrlFromOverride(Override override) {
|
||||
return override.toUrl();
|
||||
/*Map<String, String> params = ConvertUtil.serviceName2Map(override.getService());
|
||||
if(!params.containsKey(Constants.INTERFACE_KEY)) {
|
||||
throw new IllegalArgumentException("No interface info");
|
||||
}
|
||||
if(!params.containsKey(Constants.VERSION_KEY)) {
|
||||
throw new IllegalArgumentException("No version info");
|
||||
}
|
||||
|
||||
boolean enabled = override.isEnabled();
|
||||
if(!enabled) {
|
||||
params.put("enabled", "false");
|
||||
}
|
||||
String application = override.getApplication();
|
||||
if(!StringUtils.isEmpty(application)) {
|
||||
params.put("application", application);
|
||||
}
|
||||
String address = override.getAddress();
|
||||
if(!StringUtils.isEmpty(address)) {
|
||||
params.put("address", address);
|
||||
}
|
||||
|
||||
String overrideAddress = override.getOverrideAddress();
|
||||
if(StringUtils.isEmpty(overrideAddress)) {
|
||||
overrideAddress = "0.0.0.0";
|
||||
}
|
||||
params.put(Constants.CATEGORY_KEY, Constants.CONFIGURATORS_CATEGORY);
|
||||
|
||||
URL url = new URL("override", overrideAddress, -1, params);
|
||||
url = url.addParameterString(override.getParams());
|
||||
return url;*/
|
||||
}
|
||||
|
||||
URL findOverrideUrl(Long id) {
|
||||
return getUrlFromOverride(findById(id));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.OwnerService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
import com.alibaba.dubbo.registry.common.domain.Owner;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OwnerServiceImpl extends AbstractService implements OwnerService {
|
||||
|
||||
@Autowired
|
||||
ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
OverrideService overrideService;
|
||||
|
||||
public List<String> findAllServiceNames() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> findServiceNamesByUsername(String username) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> findUsernamesByServiceName(String serviceName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Owner> findByService(String serviceName) {
|
||||
List<Provider> pList = providerService.findByService(serviceName);
|
||||
List<Override> cList = overrideService.findByServiceAndAddress(serviceName, Constants.ANYHOST_VALUE);
|
||||
return toOverrideLiset(pList, cList);
|
||||
}
|
||||
|
||||
public List<Owner> findAll() {
|
||||
List<Provider> pList = providerService.findAll();
|
||||
List<Override> cList = overrideService.findAll();
|
||||
return toOverrideLiset(pList, cList);
|
||||
}
|
||||
|
||||
public Owner findById(Long id) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Owner> toOverrideLiset(List<Provider> pList, List<Override> cList) {
|
||||
Map<String, Owner> oList = new HashMap<String, Owner>();
|
||||
for (Provider p : pList) {
|
||||
if (p.getUsername() != null) {
|
||||
for (String username : Constants.COMMA_SPLIT_PATTERN.split(p.getUsername())) {
|
||||
Owner o = new Owner();
|
||||
o.setService(p.getService());
|
||||
o.setUsername(username);
|
||||
oList.put(o.getService() + "/" + o.getUsername(), o);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Override c : cList) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(c.getParams());
|
||||
String usernames = params.get("owner");
|
||||
if (usernames != null && usernames.length() > 0) {
|
||||
for (String username : Constants.COMMA_SPLIT_PATTERN.split(usernames)) {
|
||||
Owner o = new Owner();
|
||||
o.setService(c.getService());
|
||||
o.setUsername(username);
|
||||
oList.put(o.getService() + "/" + o.getUsername(), o);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<Owner>(oList.values());
|
||||
}
|
||||
|
||||
public void saveOwner(Owner owner) {
|
||||
List<Override> overrides = overrideService.findByServiceAndAddress(owner.getService(), Constants.ANYHOST_VALUE);
|
||||
if (overrides == null || overrides.size() == 0) {
|
||||
Override override = new Override();
|
||||
override.setAddress(Constants.ANYHOST_VALUE);
|
||||
override.setService(owner.getService());
|
||||
override.setEnabled(true);
|
||||
override.setParams("owner=" + owner.getUsername());
|
||||
overrideService.saveOverride(override);
|
||||
} else {
|
||||
for (Override override : overrides) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(override.getParams());
|
||||
String usernames = params.get("owner");
|
||||
if (usernames == null || usernames.length() == 0) {
|
||||
usernames = owner.getUsername();
|
||||
} else {
|
||||
usernames = usernames + "," + owner.getUsername();
|
||||
}
|
||||
params.put("owner", usernames);
|
||||
override.setParams(StringUtils.toQueryString(params));
|
||||
overrideService.updateOverride(override);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteOwner(Owner owner) {
|
||||
List<Override> overrides = overrideService.findByServiceAndAddress(owner.getService(), Constants.ANYHOST_VALUE);
|
||||
if (overrides == null || overrides.size() == 0) {
|
||||
Override override = new Override();
|
||||
override.setAddress(Constants.ANYHOST_VALUE);
|
||||
override.setService(owner.getService());
|
||||
override.setEnabled(true);
|
||||
override.setParams("owner=" + owner.getUsername());
|
||||
overrideService.saveOverride(override);
|
||||
} else {
|
||||
for (Override override : overrides) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(override.getParams());
|
||||
String usernames = params.get("owner");
|
||||
if (usernames != null && usernames.length() > 0) {
|
||||
if (usernames.equals(owner.getUsername())) {
|
||||
params.remove("owner");
|
||||
} else {
|
||||
usernames = usernames.replace(owner.getUsername() + ",", "").replace("," + owner.getUsername(), "");
|
||||
params.put("owner", usernames);
|
||||
}
|
||||
if (params.size() > 0) {
|
||||
override.setParams(StringUtils.toQueryString(params));
|
||||
overrideService.updateOverride(override);
|
||||
} else {
|
||||
overrideService.deleteOverride(override.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.sync.util.Pair;
|
||||
import com.alibaba.dubbo.governance.sync.util.SyncUtils;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.route.ParseUtils;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* IbatisProviderService
|
||||
*
|
||||
*/
|
||||
public class ProviderServiceImpl extends AbstractService implements ProviderService {
|
||||
|
||||
@Autowired
|
||||
OverrideService overrideService;
|
||||
|
||||
public void create(Provider provider) {
|
||||
URL url = provider.toUrl();
|
||||
registryService.register(url);
|
||||
}
|
||||
|
||||
public void enableProvider(Long id) {
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no provider id");
|
||||
}
|
||||
|
||||
Provider oldProvider = findProvider(id);
|
||||
|
||||
if (oldProvider == null) {
|
||||
throw new IllegalStateException("Provider was changed!");
|
||||
}
|
||||
if (oldProvider.isDynamic()) {
|
||||
// Make sure we only have one override configured disable property.
|
||||
if (!oldProvider.isEnabled()) {
|
||||
Override override = new Override();
|
||||
override.setAddress(oldProvider.getAddress());
|
||||
override.setService(oldProvider.getService());
|
||||
override.setEnabled(true);
|
||||
override.setParams(Constants.DISABLED_KEY + "=false");
|
||||
overrideService.saveOverride(override);
|
||||
return;
|
||||
}
|
||||
List<Override> oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress());
|
||||
|
||||
for (Override o : oList) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(o.getParams());
|
||||
if (params.containsKey(Constants.DISABLED_KEY)) {
|
||||
if (params.get(Constants.DISABLED_KEY).equals("true")) {
|
||||
overrideService.deleteOverride(o.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
oldProvider.setEnabled(true);
|
||||
updateProvider(oldProvider);
|
||||
}
|
||||
}
|
||||
|
||||
public void disableProvider(Long id) {
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no provider id");
|
||||
}
|
||||
|
||||
Provider oldProvider = findProvider(id);
|
||||
if (oldProvider == null) {
|
||||
throw new IllegalStateException("Provider was changed!");
|
||||
}
|
||||
|
||||
if (oldProvider.isDynamic()) {
|
||||
// Make sure we only have one override configured disable property.
|
||||
if (oldProvider.isEnabled()) {
|
||||
Override override = new Override();
|
||||
override.setAddress(oldProvider.getAddress());
|
||||
override.setService(oldProvider.getService());
|
||||
override.setEnabled(true);
|
||||
override.setParams(Constants.DISABLED_KEY + "=true");
|
||||
overrideService.saveOverride(override);
|
||||
return;
|
||||
}
|
||||
List<Override> oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress());
|
||||
|
||||
for (Override o : oList) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(o.getParams());
|
||||
if (params.containsKey(Constants.DISABLED_KEY)) {
|
||||
if (params.get(Constants.DISABLED_KEY).equals("false")) {
|
||||
overrideService.deleteOverride(o.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
oldProvider.setEnabled(false);
|
||||
updateProvider(oldProvider);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void doublingProvider(Long id) {
|
||||
setWeight(id, 2F);
|
||||
}
|
||||
|
||||
public void halvingProvider(Long id) {
|
||||
setWeight(id, 0.5F);
|
||||
}
|
||||
|
||||
public void setWeight(Long id, float factor) {
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no provider id");
|
||||
}
|
||||
Provider oldProvider = findProvider(id);
|
||||
if (oldProvider == null) {
|
||||
throw new IllegalStateException("Provider was changed!");
|
||||
}
|
||||
Map<String, String> map = StringUtils.parseQueryString(oldProvider.getParameters());
|
||||
String weight = map.get(Constants.WEIGHT_KEY);
|
||||
if (oldProvider.isDynamic()) {
|
||||
// Make sure we only have one override configured disable property.
|
||||
List<Override> overrides = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress());
|
||||
if (overrides == null || overrides.size() == 0) {
|
||||
int value = getWeight(weight, factor);
|
||||
if (value != Constants.DEFAULT_WEIGHT) {
|
||||
Override override = new Override();
|
||||
override.setAddress(oldProvider.getAddress());
|
||||
override.setService(oldProvider.getService());
|
||||
override.setEnabled(true);
|
||||
override.setParams(Constants.WEIGHT_KEY + "=" + String.valueOf(value));
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
} else {
|
||||
for (Override override : overrides) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(override.getParams());
|
||||
String overrideWeight = params.get(Constants.WEIGHT_KEY);
|
||||
if (overrideWeight == null || overrideWeight.length() == 0) {
|
||||
overrideWeight = weight;
|
||||
}
|
||||
int value = getWeight(overrideWeight, factor);
|
||||
if (value == getWeight(weight, 1)) {
|
||||
params.remove(Constants.WEIGHT_KEY);
|
||||
} else {
|
||||
params.put(Constants.WEIGHT_KEY, String.valueOf(value));
|
||||
}
|
||||
if (params.size() > 0) {
|
||||
override.setParams(StringUtils.toQueryString(params));
|
||||
overrideService.updateOverride(override);
|
||||
} else {
|
||||
overrideService.deleteOverride(override.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int value = getWeight(weight, factor);
|
||||
if (value == Constants.DEFAULT_WEIGHT) {
|
||||
map.remove(Constants.WEIGHT_KEY);
|
||||
} else {
|
||||
map.put(Constants.WEIGHT_KEY, String.valueOf(value));
|
||||
}
|
||||
oldProvider.setParameters(StringUtils.toQueryString(map));
|
||||
updateProvider(oldProvider);
|
||||
}
|
||||
}
|
||||
|
||||
private int getWeight(String value, float factor) {
|
||||
int weight = 100;
|
||||
if (value != null && value.length() > 0) {
|
||||
weight = Integer.parseInt(value);
|
||||
}
|
||||
weight = (int) (weight * factor);
|
||||
if (weight < 1) weight = 1;
|
||||
if (weight == 2) weight = 3;
|
||||
if (weight == 24) weight = 25;
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void deleteStaticProvider(Long id) {
|
||||
URL oldProvider = findProviderUrl(id);
|
||||
if (oldProvider == null) {
|
||||
throw new IllegalStateException("Provider was changed!");
|
||||
}
|
||||
registryService.unregister(oldProvider);
|
||||
}
|
||||
|
||||
public void updateProvider(Provider provider) {
|
||||
Long id = provider.getId();
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no provider id");
|
||||
}
|
||||
|
||||
URL oldProvider = findProviderUrl(id);
|
||||
if (oldProvider == null) {
|
||||
throw new IllegalStateException("Provider was changed!");
|
||||
}
|
||||
URL newProvider = provider.toUrl();
|
||||
|
||||
registryService.unregister(oldProvider);
|
||||
registryService.register(newProvider);
|
||||
}
|
||||
|
||||
public Provider findProvider(Long id) {
|
||||
return SyncUtils.url2Provider(findProviderUrlPair(id));
|
||||
}
|
||||
|
||||
public Pair<Long, URL> findProviderUrlPair(Long id) {
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), Constants.PROVIDERS_CATEGORY, id);
|
||||
}
|
||||
|
||||
public List<String> findServices() {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (providerUrls != null) ret.addAll(providerUrls.keySet());
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findAddresses() {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (null == providerUrls) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getAddress();
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findAddressesByApplication(String application) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) {
|
||||
String addr = u.getAddress();
|
||||
if (addr != null) ret.add(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findAddressesByService(String service) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (null == providerUrls) return ret;
|
||||
|
||||
for (Map.Entry<Long, URL> e2 : providerUrls.get(service).entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getAddress();
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findApplicationsByServiceName(String service) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (null == providerUrls) return ret;
|
||||
|
||||
Map<Long, URL> value = providerUrls.get(service);
|
||||
if (value == null) {
|
||||
return ret;
|
||||
}
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getParameter(Constants.APPLICATION_KEY);
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Provider> findByService(String serviceName) {
|
||||
return SyncUtils.url2ProviderList(findProviderUrlByService(serviceName));
|
||||
}
|
||||
|
||||
private Map<Long, URL> findProviderUrlByService(String service) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
|
||||
filter.put(SyncUtils.SERVICE_FILTER_KEY, service);
|
||||
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<Provider> findAll() {
|
||||
return SyncUtils.url2ProviderList(findAllProviderUrl());
|
||||
}
|
||||
|
||||
private Map<Long, URL> findAllProviderUrl() {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<Provider> findByAddress(String providerAddress) {
|
||||
return SyncUtils.url2ProviderList(findProviderUrlByAddress(providerAddress));
|
||||
}
|
||||
|
||||
public Map<Long, URL> findProviderUrlByAddress(String address) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
|
||||
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
|
||||
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<String> findServicesByAddress(String address) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (providerUrls == null || address == null || address.length() == 0) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
if (address.equals(u.getAddress())) {
|
||||
ret.add(e1.getKey());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findApplications() {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (providerUrls == null) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
String app = u.getParameter(Constants.APPLICATION_KEY);
|
||||
if (app != null) ret.add(app);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Provider> findByApplication(String application) {
|
||||
return SyncUtils.url2ProviderList(findProviderUrlByApplication(application));
|
||||
}
|
||||
|
||||
private Map<Long, URL> findProviderUrlByApplication(String application) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
|
||||
filter.put(Constants.APPLICATION_KEY, application);
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<String> findServicesByApplication(String application) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (providerUrls == null || application == null || application.length() == 0) return ret;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : providerUrls.entrySet()) {
|
||||
Map<Long, URL> value = e1.getValue();
|
||||
for (Map.Entry<Long, URL> e2 : value.entrySet()) {
|
||||
URL u = e2.getValue();
|
||||
if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) {
|
||||
ret.add(e1.getKey());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<String> findMethodsByService(String service) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
|
||||
ConcurrentMap<String, Map<Long, URL>> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY);
|
||||
if (providerUrls == null || service == null || service.length() == 0) return ret;
|
||||
|
||||
Map<Long, URL> providers = providerUrls.get(service);
|
||||
if (null == providers || providers.isEmpty()) return ret;
|
||||
|
||||
Entry<Long, URL> p = providers.entrySet().iterator().next();
|
||||
String value = p.getValue().getParameter("methods");
|
||||
if (value == null || value.length() == 0) {
|
||||
return ret;
|
||||
}
|
||||
String[] methods = value.split(ParseUtils.METHOD_SPLIT);
|
||||
if (methods == null || methods.length == 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (String m : methods) {
|
||||
ret.add(m);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private URL findProviderUrl(Long id) {
|
||||
return findProvider(id).toUrl();
|
||||
}
|
||||
|
||||
public Provider findByServiceAndAddress(String service, String address) {
|
||||
return SyncUtils.url2Provider(findProviderUrl(service, address));
|
||||
}
|
||||
|
||||
private Pair<Long, URL> findProviderUrl(String service, String address) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
|
||||
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
|
||||
|
||||
Map<Long, URL> ret = SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
if (ret.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
Long key = ret.entrySet().iterator().next().getKey();
|
||||
return new Pair<Long, URL>(key, ret.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.governance.service.RouteService;
|
||||
import com.alibaba.dubbo.governance.sync.util.Pair;
|
||||
import com.alibaba.dubbo.governance.sync.util.SyncUtils;
|
||||
import com.alibaba.dubbo.registry.common.domain.Route;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IbatisRouteService
|
||||
*
|
||||
*/
|
||||
public class RouteServiceImpl extends AbstractService implements RouteService {
|
||||
|
||||
public void createRoute(Route route) {
|
||||
registryService.register(route.toUrl());
|
||||
}
|
||||
|
||||
public void updateRoute(Route route) {
|
||||
Long id = route.getId();
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no route id");
|
||||
}
|
||||
URL oldRoute = findRouteUrl(id);
|
||||
if (oldRoute == null) {
|
||||
throw new IllegalStateException("Route was changed!");
|
||||
}
|
||||
|
||||
registryService.unregister(oldRoute);
|
||||
registryService.register(route.toUrl());
|
||||
}
|
||||
|
||||
public void deleteRoute(Long id) {
|
||||
URL oldRoute = findRouteUrl(id);
|
||||
if (oldRoute == null) {
|
||||
throw new IllegalStateException("Route was changed!");
|
||||
}
|
||||
registryService.unregister(oldRoute);
|
||||
}
|
||||
|
||||
public void enableRoute(Long id) {
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no route id");
|
||||
}
|
||||
|
||||
URL oldRoute = findRouteUrl(id);
|
||||
if (oldRoute == null) {
|
||||
throw new IllegalStateException("Route was changed!");
|
||||
}
|
||||
if (oldRoute.getParameter("enabled", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
registryService.unregister(oldRoute);
|
||||
URL newRoute = oldRoute.addParameter("enabled", true);
|
||||
registryService.register(newRoute);
|
||||
|
||||
}
|
||||
|
||||
public void disableRoute(Long id) {
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("no route id");
|
||||
}
|
||||
|
||||
URL oldRoute = findRouteUrl(id);
|
||||
if (oldRoute == null) {
|
||||
throw new IllegalStateException("Route was changed!");
|
||||
}
|
||||
if (!oldRoute.getParameter("enabled", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
URL newRoute = oldRoute.addParameter("enabled", false);
|
||||
registryService.unregister(oldRoute);
|
||||
registryService.register(newRoute);
|
||||
|
||||
}
|
||||
|
||||
public List<Route> findAll() {
|
||||
return SyncUtils.url2RouteList(findAllUrl());
|
||||
}
|
||||
|
||||
private Map<Long, URL> findAllUrl() {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.ROUTERS_CATEGORY);
|
||||
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public Route findRoute(Long id) {
|
||||
return SyncUtils.url2Route(findRouteUrlPair(id));
|
||||
}
|
||||
|
||||
public Pair<Long, URL> findRouteUrlPair(Long id) {
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), Constants.ROUTERS_CATEGORY, id);
|
||||
}
|
||||
|
||||
private URL findRouteUrl(Long id) {
|
||||
return findRoute(id).toUrl();
|
||||
}
|
||||
|
||||
private Map<Long, URL> findRouteUrl(String service, String address, boolean force) {
|
||||
Map<String, String> filter = new HashMap<String, String>();
|
||||
filter.put(Constants.CATEGORY_KEY, Constants.ROUTERS_CATEGORY);
|
||||
if (service != null && service.length() > 0) {
|
||||
filter.put(SyncUtils.SERVICE_FILTER_KEY, service);
|
||||
}
|
||||
if (address != null && address.length() > 0) {
|
||||
filter.put(SyncUtils.ADDRESS_FILTER_KEY, address);
|
||||
}
|
||||
if (force) {
|
||||
filter.put("force", "true");
|
||||
}
|
||||
return SyncUtils.filterFromCategory(getRegistryCache(), filter);
|
||||
}
|
||||
|
||||
public List<Route> findByService(String serviceName) {
|
||||
return SyncUtils.url2RouteList(findRouteUrl(serviceName, null, false));
|
||||
}
|
||||
|
||||
public List<Route> findByAddress(String address) {
|
||||
return SyncUtils.url2RouteList(findRouteUrl(null, address, false));
|
||||
}
|
||||
|
||||
public List<Route> findByServiceAndAddress(String service, String address) {
|
||||
return SyncUtils.url2RouteList(findRouteUrl(service, address, false));
|
||||
}
|
||||
|
||||
public List<Route> findForceRouteByService(String service) {
|
||||
return SyncUtils.url2RouteList(findRouteUrl(service, null, true));
|
||||
}
|
||||
|
||||
public List<Route> findForceRouteByAddress(String address) {
|
||||
return SyncUtils.url2RouteList(findRouteUrl(null, address, true));
|
||||
}
|
||||
|
||||
public List<Route> findForceRouteByServiceAndAddress(String service, String address) {
|
||||
return SyncUtils.url2RouteList(findRouteUrl(service, address, true));
|
||||
}
|
||||
|
||||
public List<Route> findAllForceRoute() {
|
||||
return SyncUtils.url2RouteList(findRouteUrl(null, null, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.service.impl;
|
||||
|
||||
import com.alibaba.dubbo.governance.service.UserService;
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
import com.alibaba.dubbo.registry.common.util.Coder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IBatisUserService
|
||||
*
|
||||
*/
|
||||
public class UserServiceImpl extends AbstractService implements UserService {
|
||||
|
||||
private String rootPassword;
|
||||
private String guestPassword;
|
||||
|
||||
public void setRootPassword(String password) {
|
||||
this.rootPassword = (password == null ? "" : password);
|
||||
}
|
||||
|
||||
public void setGuestPassword(String password) {
|
||||
this.guestPassword = (password == null ? "" : password);
|
||||
}
|
||||
|
||||
public User findUser(String username) {
|
||||
if ("guest".equals(username)) {
|
||||
User user = new User();
|
||||
user.setUsername(username);
|
||||
user.setPassword(Coder.encodeMd5(username + ":" + User.REALM + ":" + guestPassword));
|
||||
user.setName(username);
|
||||
user.setRole(User.GUEST);
|
||||
user.setEnabled(true);
|
||||
user.setLocale("zh");
|
||||
user.setServicePrivilege("");
|
||||
return user;
|
||||
} else if ("root".equals(username)) {
|
||||
User user = new User();
|
||||
user.setUsername(username);
|
||||
user.setPassword(Coder.encodeMd5(username + ":" + User.REALM + ":" + rootPassword));
|
||||
user.setName(username);
|
||||
user.setRole(User.ROOT);
|
||||
user.setEnabled(true);
|
||||
user.setLocale("zh");
|
||||
user.setServicePrivilege("*");
|
||||
return user;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<User> findAllUsers() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String, User> findAllUsersMap() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public User findById(Long id) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void createUser(User user) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void updateUser(User user) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void modifyUser(User user) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public boolean updatePassword(User user, String oldPassword) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public void resetPassword(User user) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void enableUser(User user) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void disableUser(User user) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void deleteUser(User user) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public List<User> findUsersByServiceName(String serviceName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.status;
|
||||
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.status.Status;
|
||||
import com.alibaba.dubbo.common.status.StatusChecker;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
/**
|
||||
* DatabaseStatus
|
||||
*
|
||||
*/
|
||||
public class DatabaseStatusChecker implements StatusChecker {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DatabaseStatusChecker.class);
|
||||
|
||||
private int version;
|
||||
|
||||
private String message;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
check(); // init
|
||||
}
|
||||
|
||||
public Status check() {
|
||||
boolean ok;
|
||||
try {
|
||||
Connection connection = dataSource.getConnection();
|
||||
try {
|
||||
DatabaseMetaData metaData = connection.getMetaData();
|
||||
ResultSet resultSet = metaData.getTypeInfo();
|
||||
try {
|
||||
ok = resultSet.next();
|
||||
} finally {
|
||||
resultSet.close();
|
||||
}
|
||||
if (message == null) {
|
||||
message = metaData.getURL()
|
||||
+ " (" + metaData.getDatabaseProductName()
|
||||
+ " " + metaData.getDatabaseProductVersion()
|
||||
+ ", " + getIsolation(metaData.getDefaultTransactionIsolation()) + ")";
|
||||
}
|
||||
if (version == 0) {
|
||||
version = metaData.getDatabaseMajorVersion();
|
||||
}
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
ok = false;
|
||||
}
|
||||
return new Status(!ok ? Status.Level.ERROR : (version < 5 ? Status.Level.WARN : Status.Level.OK), message);
|
||||
}
|
||||
|
||||
private String getIsolation(int i) {
|
||||
if (i == Connection.TRANSACTION_READ_COMMITTED) {
|
||||
return "READ_COMMITTED";
|
||||
}
|
||||
if (i == Connection.TRANSACTION_READ_UNCOMMITTED) {
|
||||
return "READ_UNCOMMITTED";
|
||||
}
|
||||
if (i == Connection.TRANSACTION_REPEATABLE_READ) {
|
||||
return "REPEATABLE_READ";
|
||||
}
|
||||
if (i == Connection.TRANSACTION_SERIALIZABLE) {
|
||||
return "SERIALIZABLE)";
|
||||
}
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.status;
|
||||
|
||||
import com.alibaba.dubbo.common.status.Status;
|
||||
import com.alibaba.dubbo.common.status.StatusChecker;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Load Status
|
||||
*
|
||||
*/
|
||||
public class LoadStatusChecker implements StatusChecker {
|
||||
|
||||
public Status check() {
|
||||
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
double load;
|
||||
try {
|
||||
Method method = OperatingSystemMXBean.class.getMethod("getSystemLoadAverage", new Class<?>[0]);
|
||||
load = (Double) method.invoke(operatingSystemMXBean, new Object[0]);
|
||||
} catch (Throwable e) {
|
||||
load = -1;
|
||||
}
|
||||
int cpu = operatingSystemMXBean.getAvailableProcessors();
|
||||
return new Status(load < 0 ? Status.Level.UNKNOWN : (load < cpu ? Status.Level.OK : Status.Level.WARN), "Load: " + load + " / CPU: " + cpu);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.status;
|
||||
|
||||
import com.alibaba.dubbo.common.status.Status;
|
||||
import com.alibaba.dubbo.common.status.StatusChecker;
|
||||
|
||||
/**
|
||||
* MemoryStatus
|
||||
*
|
||||
*/
|
||||
public class MemoryStatusChecker implements StatusChecker {
|
||||
|
||||
public Status check() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
long freeMemory = runtime.freeMemory();
|
||||
long totalMemory = runtime.totalMemory();
|
||||
long maxMemory = runtime.maxMemory();
|
||||
boolean ok = (maxMemory - (totalMemory - freeMemory) > 2048); // Alarm when spare memory < 2M
|
||||
String msg = "Max:" + (maxMemory / 1024 / 1024) + "M, Total:"
|
||||
+ (totalMemory / 1024 / 1024) + "M, Free:" + (freeMemory / 1024 / 1024)
|
||||
+ "M, Use:" + ((totalMemory / 1024 / 1024) - (freeMemory / 1024 / 1024)) + "M";
|
||||
return new Status(ok ? Status.Level.OK : Status.Level.WARN, msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.sync;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.utils.NetUtils;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.web.common.pulltool.Tool;
|
||||
import com.alibaba.dubbo.registry.NotifyListener;
|
||||
import com.alibaba.dubbo.registry.RegistryService;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class RegistryServerSync implements InitializingBean, DisposableBean, NotifyListener {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RegistryServerSync.class);
|
||||
|
||||
private static final URL SUBSCRIBE = new URL(Constants.ADMIN_PROTOCOL, NetUtils.getLocalHost(), 0, "",
|
||||
Constants.INTERFACE_KEY, Constants.ANY_VALUE,
|
||||
Constants.GROUP_KEY, Constants.ANY_VALUE,
|
||||
Constants.VERSION_KEY, Constants.ANY_VALUE,
|
||||
Constants.CLASSIFIER_KEY, Constants.ANY_VALUE,
|
||||
Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + ","
|
||||
+ Constants.CONSUMERS_CATEGORY + ","
|
||||
+ Constants.ROUTERS_CATEGORY + ","
|
||||
+ Constants.CONFIGURATORS_CATEGORY,
|
||||
Constants.ENABLED_KEY, Constants.ANY_VALUE,
|
||||
Constants.CHECK_KEY, String.valueOf(false));
|
||||
|
||||
private static final AtomicLong ID = new AtomicLong();
|
||||
|
||||
/**
|
||||
* Make sure ID never changed when the same url notified many times
|
||||
*/
|
||||
private final ConcurrentHashMap<String, Long> URL_IDS_MAPPER = new ConcurrentHashMap<String, Long>();
|
||||
|
||||
// ConcurrentMap<category, ConcurrentMap<servicename, Map<Long, URL>>>
|
||||
private final ConcurrentMap<String, ConcurrentMap<String, Map<Long, URL>>> registryCache = new ConcurrentHashMap<String, ConcurrentMap<String, Map<Long, URL>>>();
|
||||
@Autowired
|
||||
private RegistryService registryService;
|
||||
|
||||
public ConcurrentMap<String, ConcurrentMap<String, Map<Long, URL>>> getRegistryCache() {
|
||||
return registryCache;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
logger.info("Init Dubbo Admin Sync Cache...");
|
||||
registryService.subscribe(SUBSCRIBE, this);
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
registryService.unsubscribe(SUBSCRIBE, this);
|
||||
}
|
||||
|
||||
// Notification of of any service with any type (override、subcribe、route、provider) is full.
|
||||
public void notify(List<URL> urls) {
|
||||
if (urls == null || urls.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Map<category, Map<servicename, Map<Long, URL>>>
|
||||
final Map<String, Map<String, Map<Long, URL>>> categories = new HashMap<String, Map<String, Map<Long, URL>>>();
|
||||
String interfaceName = null;
|
||||
for (URL url : urls) {
|
||||
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY);
|
||||
if (Constants.EMPTY_PROTOCOL.equalsIgnoreCase(url.getProtocol())) { // NOTE: group and version in empty protocol is *
|
||||
ConcurrentMap<String, Map<Long, URL>> services = registryCache.get(category);
|
||||
if (services != null) {
|
||||
String group = url.getParameter(Constants.GROUP_KEY);
|
||||
String version = url.getParameter(Constants.VERSION_KEY);
|
||||
// NOTE: group and version in empty protocol is *
|
||||
if (!Constants.ANY_VALUE.equals(group) && !Constants.ANY_VALUE.equals(version)) {
|
||||
services.remove(url.getServiceKey());
|
||||
} else {
|
||||
for (Map.Entry<String, Map<Long, URL>> serviceEntry : services.entrySet()) {
|
||||
String service = serviceEntry.getKey();
|
||||
if (Tool.getInterface(service).equals(url.getServiceInterface())
|
||||
&& (Constants.ANY_VALUE.equals(group) || StringUtils.isEquals(group, Tool.getGroup(service)))
|
||||
&& (Constants.ANY_VALUE.equals(version) || StringUtils.isEquals(version, Tool.getVersion(service)))) {
|
||||
services.remove(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isEmpty(interfaceName)) {
|
||||
interfaceName = url.getServiceInterface();
|
||||
}
|
||||
Map<String, Map<Long, URL>> services = categories.get(category);
|
||||
if (services == null) {
|
||||
services = new HashMap<String, Map<Long, URL>>();
|
||||
categories.put(category, services);
|
||||
}
|
||||
String service = url.getServiceKey();
|
||||
Map<Long, URL> ids = services.get(service);
|
||||
if (ids == null) {
|
||||
ids = new HashMap<Long, URL>();
|
||||
services.put(service, ids);
|
||||
}
|
||||
|
||||
// Make sure we use the same ID for the same URL
|
||||
if (URL_IDS_MAPPER.containsKey(url.toFullString())) {
|
||||
ids.put(URL_IDS_MAPPER.get(url.toFullString()), url);
|
||||
} else {
|
||||
long currentId = ID.incrementAndGet();
|
||||
ids.put(currentId, url);
|
||||
URL_IDS_MAPPER.putIfAbsent(url.toFullString(), currentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (categories.size() == 0) {
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<String, Map<String, Map<Long, URL>>> categoryEntry : categories.entrySet()) {
|
||||
String category = categoryEntry.getKey();
|
||||
ConcurrentMap<String, Map<Long, URL>> services = registryCache.get(category);
|
||||
if (services == null) {
|
||||
services = new ConcurrentHashMap<String, Map<Long, URL>>();
|
||||
registryCache.put(category, services);
|
||||
} else {// Fix map can not be cleared when service is unregistered: when a unique “group/service:version” service is unregistered, but we still have the same services with different version or group, so empty protocols can not be invoked.
|
||||
Set<String> keys = new HashSet<String>(services.keySet());
|
||||
for (String key : keys) {
|
||||
if (Tool.getInterface(key).equals(interfaceName) && !categoryEntry.getValue().entrySet().contains(key)) {
|
||||
services.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
services.putAll(categoryEntry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.sync.util;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Pair<K, V> implements Map.Entry<K, V> {
|
||||
|
||||
private K key;
|
||||
|
||||
private V value;
|
||||
|
||||
public Pair() {
|
||||
}
|
||||
|
||||
public Pair(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(K key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public V setValue(V value) {
|
||||
V old = this.value;
|
||||
this.value = value;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
||||
result = prime * result + ((value == null) ? 0 : value.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Pair<?, ?> other = (Pair<?, ?>) obj;
|
||||
if (key == null) {
|
||||
if (other.key != null)
|
||||
return false;
|
||||
} else if (!key.equals(other.key))
|
||||
return false;
|
||||
if (value == null) {
|
||||
if (other.value != null)
|
||||
return false;
|
||||
} else if (!value.equals(other.value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.sync.util;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.registry.common.domain.Consumer;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.domain.Route;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SyncUtils {
|
||||
|
||||
public static final String SERVICE_FILTER_KEY = ".service";
|
||||
|
||||
public static final String ADDRESS_FILTER_KEY = ".address";
|
||||
|
||||
public static final String ID_FILTER_KEY = ".id";
|
||||
|
||||
public static Provider url2Provider(Pair<Long, URL> pair) {
|
||||
if (pair == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Long id = pair.getKey();
|
||||
URL url = pair.getValue();
|
||||
|
||||
if (url == null)
|
||||
return null;
|
||||
|
||||
Provider p = new Provider();
|
||||
p.setId(id);
|
||||
p.setService(url.getServiceKey());
|
||||
p.setAddress(url.getAddress());
|
||||
p.setApplication(url.getParameter(Constants.APPLICATION_KEY));
|
||||
p.setUrl(url.toIdentityString());
|
||||
p.setParameters(url.toParameterString());
|
||||
|
||||
p.setDynamic(url.getParameter("dynamic", true));
|
||||
p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
|
||||
p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT));
|
||||
p.setUsername(url.getParameter("owner"));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public static List<Provider> url2ProviderList(Map<Long, URL> ps) {
|
||||
List<Provider> ret = new ArrayList<Provider>();
|
||||
for (Map.Entry<Long, URL> entry : ps.entrySet()) {
|
||||
ret.add(url2Provider(new Pair<Long, URL>(entry.getKey(), entry.getValue())));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Consumer url2Consumer(Pair<Long, URL> pair) {
|
||||
if (pair == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Long id = pair.getKey();
|
||||
URL url = pair.getValue();
|
||||
|
||||
if (null == url)
|
||||
return null;
|
||||
|
||||
Consumer c = new Consumer();
|
||||
c.setId(id);
|
||||
c.setService(url.getServiceKey());
|
||||
c.setAddress(url.getHost());
|
||||
c.setApplication(url.getParameter(Constants.APPLICATION_KEY));
|
||||
c.setParameters(url.toParameterString());
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public static List<Consumer> url2ConsumerList(Map<Long, URL> cs) {
|
||||
List<Consumer> list = new ArrayList<Consumer>();
|
||||
if (cs == null) return list;
|
||||
for (Map.Entry<Long, URL> entry : cs.entrySet()) {
|
||||
list.add(url2Consumer(new Pair<Long, URL>(entry.getKey(), entry.getValue())));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static Route url2Route(Pair<Long, URL> pair) {
|
||||
if (pair == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Long id = pair.getKey();
|
||||
URL url = pair.getValue();
|
||||
|
||||
if (null == url)
|
||||
return null;
|
||||
|
||||
Route r = new Route();
|
||||
r.setId(id);
|
||||
r.setName(url.getParameter("name"));
|
||||
r.setService(url.getServiceKey());
|
||||
r.setPriority(url.getParameter(Constants.PRIORITY_KEY, 0));
|
||||
r.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
|
||||
r.setForce(url.getParameter(Constants.FORCE_KEY, false));
|
||||
r.setRule(url.getParameterAndDecoded(Constants.RULE_KEY));
|
||||
return r;
|
||||
}
|
||||
|
||||
public static List<Route> url2RouteList(Map<Long, URL> cs) {
|
||||
List<Route> list = new ArrayList<Route>();
|
||||
if (cs == null) return list;
|
||||
for (Map.Entry<Long, URL> entry : cs.entrySet()) {
|
||||
list.add(url2Route(new Pair<Long, URL>(entry.getKey(), entry.getValue())));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static com.alibaba.dubbo.registry.common.domain.Override url2Override(Pair<Long, URL> pair) {
|
||||
if (pair == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Long id = pair.getKey();
|
||||
URL url = pair.getValue();
|
||||
|
||||
if (null == url)
|
||||
return null;
|
||||
|
||||
com.alibaba.dubbo.registry.common.domain.Override o = new com.alibaba.dubbo.registry.common.domain.Override();
|
||||
o.setId(id);
|
||||
|
||||
Map<String, String> parameters = new HashMap<String, String>(url.getParameters());
|
||||
|
||||
o.setService(url.getServiceKey());
|
||||
parameters.remove(Constants.INTERFACE_KEY);
|
||||
parameters.remove(Constants.GROUP_KEY);
|
||||
parameters.remove(Constants.VERSION_KEY);
|
||||
parameters.remove(Constants.APPLICATION_KEY);
|
||||
parameters.remove(Constants.CATEGORY_KEY);
|
||||
parameters.remove(Constants.DYNAMIC_KEY);
|
||||
parameters.remove(Constants.ENABLED_KEY);
|
||||
|
||||
o.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
|
||||
|
||||
String host = url.getHost();
|
||||
boolean anyhost = url.getParameter(Constants.ANYHOST_VALUE, false);
|
||||
if (!anyhost || !"0.0.0.0".equals(host)) {
|
||||
o.setAddress(url.getAddress());
|
||||
}
|
||||
|
||||
o.setApplication(url.getParameter(Constants.APPLICATION_KEY, url.getUsername()));
|
||||
parameters.remove(Constants.VERSION_KEY);
|
||||
|
||||
o.setParams(StringUtils.toQueryString(parameters));
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
// Map<category, Map<servicename, Map<Long, URL>>>
|
||||
public static <SM extends Map<String, Map<Long, URL>>> Map<Long, URL> filterFromCategory(Map<String, SM> urls, Map<String, String> filter) {
|
||||
String c = (String) filter.get(Constants.CATEGORY_KEY);
|
||||
if (c == null) throw new IllegalArgumentException("no category");
|
||||
|
||||
filter.remove(Constants.CATEGORY_KEY);
|
||||
return filterFromService(urls.get(c), filter);
|
||||
}
|
||||
|
||||
public static List<com.alibaba.dubbo.registry.common.domain.Override> url2OverrideList(Map<Long, URL> cs) {
|
||||
List<com.alibaba.dubbo.registry.common.domain.Override> list = new ArrayList<com.alibaba.dubbo.registry.common.domain.Override>();
|
||||
if (cs == null) return list;
|
||||
for (Map.Entry<Long, URL> entry : cs.entrySet()) {
|
||||
list.add(url2Override(new Pair<Long, URL>(entry.getKey(), entry.getValue())));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
// Map<servicename, Map<Long, URL>>
|
||||
public static Map<Long, URL> filterFromService(Map<String, Map<Long, URL>> urls, Map<String, String> filter) {
|
||||
Map<Long, URL> ret = new HashMap<Long, URL>();
|
||||
if (urls == null) return ret;
|
||||
|
||||
String s = (String) filter.remove(SERVICE_FILTER_KEY);
|
||||
if (s == null) {
|
||||
for (Map.Entry<String, Map<Long, URL>> entry : urls.entrySet()) {
|
||||
filterFromUrls(entry.getValue(), ret, filter);
|
||||
}
|
||||
} else {
|
||||
Map<Long, URL> map = urls.get(s);
|
||||
filterFromUrls(map, ret, filter);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Map<Long, URL>
|
||||
static void filterFromUrls(Map<Long, URL> from, Map<Long, URL> to, Map<String, String> filter) {
|
||||
if (from == null || from.isEmpty()) return;
|
||||
|
||||
for (Map.Entry<Long, URL> entry : from.entrySet()) {
|
||||
URL url = entry.getValue();
|
||||
|
||||
boolean match = true;
|
||||
for (Map.Entry<String, String> e : filter.entrySet()) {
|
||||
String key = e.getKey();
|
||||
String value = e.getValue();
|
||||
|
||||
if (ADDRESS_FILTER_KEY.equals(key)) {
|
||||
if (!value.equals(url.getAddress())) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!value.equals(url.getParameter(key))) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
to.put(entry.getKey(), url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <SM extends Map<String, Map<Long, URL>>> Pair<Long, URL> filterFromCategory(Map<String, SM> urls, String category, Long id) {
|
||||
SM services = urls.get(category);
|
||||
if (services == null) return null;
|
||||
|
||||
for (Map.Entry<String, Map<Long, URL>> e1 : services.entrySet()) {
|
||||
Map<Long, URL> u = e1.getValue();
|
||||
if (u.containsKey(id)) return new Pair<Long, URL>(id, u.get(id));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.auth;
|
||||
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* MinasUser: DubboUser
|
||||
*
|
||||
*/
|
||||
public class DubboUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final ThreadLocal<User> userHolder = new ThreadLocal<User>();
|
||||
|
||||
private DubboUser() {
|
||||
}
|
||||
|
||||
public static final User getCurrentUser() {
|
||||
return (User) userHolder.get();
|
||||
}
|
||||
|
||||
public static final void setCurrentUser(User user) {
|
||||
userHolder.set(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.i18n;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class LocaleUtil {
|
||||
private static ThreadLocal<Locale> userLocale = new ThreadLocal<Locale>();
|
||||
|
||||
public static void cleanLocale() {
|
||||
userLocale.remove();
|
||||
}
|
||||
|
||||
public static Locale getLocale() {
|
||||
return userLocale.get();
|
||||
}
|
||||
|
||||
public static void setLocale(Locale locale) {
|
||||
userLocale.set(locale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.interceptor;
|
||||
|
||||
import com.alibaba.citrus.service.pipeline.PipelineContext;
|
||||
import com.alibaba.citrus.service.pipeline.support.AbstractValve;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.UserService;
|
||||
import com.alibaba.dubbo.governance.web.util.WebConstants;
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
import com.alibaba.dubbo.registry.common.util.Coder;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AuthorizationValve extends AbstractValve {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuthorizationValve.class);
|
||||
private static final String BASIC_CHALLENGE = "Basic";
|
||||
private static final String DIGEST_CHALLENGE = "Digest";
|
||||
private static final String CHALLENGE = BASIC_CHALLENGE;
|
||||
private static final String REALM = User.REALM;
|
||||
private static Pattern PARAMETER_PATTERN = Pattern.compile("(\\w+)=[\"]?([^,\"]+)[\"]?[,]?\\s*");
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
@Autowired
|
||||
private HttpServletResponse response;
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
private String logout = "/logout";
|
||||
private String logoutCookie = "logout";
|
||||
|
||||
static Map<String, String> parseParameters(String query) {
|
||||
Matcher matcher = PARAMETER_PATTERN.matcher(query);
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
while (matcher.find()) {
|
||||
String key = matcher.group(1);
|
||||
String value = matcher.group(2);
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static byte[] readToBytes(InputStream in) throws IOException {
|
||||
byte[] buf = new byte[in.available()];
|
||||
in.read(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() throws Exception {
|
||||
}
|
||||
|
||||
public void invoke(PipelineContext pipelineContext) throws Exception {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("AuthorizationValve of uri: " + request.getRequestURI());
|
||||
}
|
||||
String uri = request.getRequestURI();
|
||||
String contextPath = request.getContextPath();
|
||||
if (contextPath != null && contextPath.length() > 0 && !"/".equals(contextPath)) {
|
||||
uri = uri.substring(contextPath.length());
|
||||
}
|
||||
if (uri.equals(logout)) {
|
||||
if (!isLogout()) {
|
||||
setLogout(true);
|
||||
showLoginForm();
|
||||
} else {
|
||||
setLogout(false);
|
||||
response.sendRedirect(contextPath == null || contextPath.length() == 0 ? "/" : contextPath);
|
||||
}
|
||||
return;
|
||||
}
|
||||
//FIXME
|
||||
if (!uri.startsWith("/status/")) {
|
||||
User user = null;
|
||||
String authType = null;
|
||||
String authorization = request.getHeader("Authorization");
|
||||
if (authorization != null && authorization.length() > 0) {
|
||||
int i = authorization.indexOf(' ');
|
||||
if (i >= 0) {
|
||||
authType = authorization.substring(0, i);
|
||||
String authPrincipal = authorization.substring(i + 1);
|
||||
if (BASIC_CHALLENGE.equalsIgnoreCase(authType)) {
|
||||
user = loginByBase(authPrincipal);
|
||||
} else if (DIGEST_CHALLENGE.equalsIgnoreCase(authType)) {
|
||||
user = loginByDigest(authPrincipal);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (user == null || user.getUsername() == null || user.getUsername().length() == 0) {
|
||||
showLoginForm();
|
||||
pipelineContext.breakPipeline(1);
|
||||
}
|
||||
if (user != null && StringUtils.isNotEmpty(user.getUsername())) {
|
||||
request.getSession().setAttribute(WebConstants.CURRENT_USER_KEY, user);
|
||||
pipelineContext.invokeNext();
|
||||
}
|
||||
} else {
|
||||
pipelineContext.invokeNext();
|
||||
}
|
||||
}
|
||||
|
||||
private User getUser(String username) {
|
||||
return userService.findUser(username);
|
||||
}
|
||||
|
||||
private void showLoginForm() throws IOException {
|
||||
if (DIGEST_CHALLENGE.equals(CHALLENGE)) {
|
||||
response.setHeader("WWW-Authenticate", CHALLENGE + " realm=\"" + REALM + "\", qop=\"auth\", nonce=\""
|
||||
+ UUID.randomUUID().toString().replace("-", "") + "\", opaque=\""
|
||||
+ Coder.encodeMd5(REALM) + "\"");
|
||||
} else {
|
||||
response.setHeader("WWW-Authenticate", CHALLENGE + " realm=\"" + REALM + "\"");
|
||||
}
|
||||
response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store");
|
||||
response.setHeader("Content-Type", "text/html; charset=iso-8859-1");
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
private User loginByBase(String authorization) {
|
||||
authorization = Coder.decodeBase64(authorization);
|
||||
int i = authorization.indexOf(':');
|
||||
String username = authorization.substring(0, i);
|
||||
if (username != null && username.length() > 0) {
|
||||
String password = authorization.substring(i + 1);
|
||||
if (password != null && password.length() > 0) {
|
||||
String passwordDigest = Coder.encodeMd5(username + ":" + REALM + ":" + password);
|
||||
User user = getUser(username);
|
||||
if (user != null) {
|
||||
String pwd = user.getPassword();
|
||||
if (pwd != null && pwd.length() > 0) {
|
||||
if (passwordDigest.equals(pwd)) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private User loginByDigest(String value) throws IOException {
|
||||
Map<String, String> params = parseParameters(value);
|
||||
String username = params.get("username");
|
||||
if (username != null && username.length() > 0) {
|
||||
String passwordDigest = params.get("response");
|
||||
if (passwordDigest != null && passwordDigest.length() > 0) {
|
||||
User user = getUser(username);
|
||||
if (user != null) {
|
||||
String pwd = user.getPassword();
|
||||
// A valid user, validate password
|
||||
if (pwd != null && pwd.length() > 0) {
|
||||
String uri = params.get("uri");
|
||||
String nonce = params.get("nonce");
|
||||
String nc = params.get("nc");
|
||||
String cnonce = params.get("cnonce");
|
||||
String qop = params.get("qop");
|
||||
String method = request.getMethod();
|
||||
String a1 = pwd;
|
||||
|
||||
String a2 = "auth-int".equals(qop)
|
||||
? Coder.encodeMd5(method + ":" + uri + ":" + Coder.encodeMd5(readToBytes(request.getInputStream())))
|
||||
: Coder.encodeMd5(method + ":" + uri);
|
||||
String digest = "auth".equals(qop) || "auth-int".equals(qop)
|
||||
? Coder.encodeMd5(a1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + a2)
|
||||
: Coder.encodeMd5(a1 + ":" + nonce + ":" + a2);
|
||||
if (digest.equals(passwordDigest)) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isLogout() {
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null && cookies.length > 0) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie != null && logoutCookie.equals(cookie.getName())) {
|
||||
return "true".equals(cookie.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setLogout(boolean logoutValue) {
|
||||
response.addCookie(new Cookie(logoutCookie, String.valueOf(logoutValue)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.interceptor;
|
||||
|
||||
import com.alibaba.citrus.service.pipeline.PipelineContext;
|
||||
import com.alibaba.citrus.service.pipeline.support.AbstractValve;
|
||||
import com.alibaba.citrus.turbine.TurbineRunData;
|
||||
import com.alibaba.dubbo.governance.web.common.i18n.LocaleUtil;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.alibaba.citrus.turbine.util.TurbineUtil.getTurbineRunData;
|
||||
|
||||
public class LocaleValve extends AbstractValve {
|
||||
|
||||
//Add exceptions for interceptors
|
||||
private final static Set<String> TARGET_WITHOUT_CHECK = new HashSet<String>();
|
||||
|
||||
static {
|
||||
TARGET_WITHOUT_CHECK.add("/ok");
|
||||
TARGET_WITHOUT_CHECK.add("/error");
|
||||
TARGET_WITHOUT_CHECK.add("/login");
|
||||
TARGET_WITHOUT_CHECK.add("/logout");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
private boolean ignoreTarget(String target) {
|
||||
return TARGET_WITHOUT_CHECK.contains(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() throws Exception {
|
||||
}
|
||||
|
||||
public void invoke(PipelineContext pipelineContext) throws Exception {
|
||||
TurbineRunData rundata = getTurbineRunData(request);
|
||||
if (ignoreTarget(rundata.getTarget())) {
|
||||
pipelineContext.invokeNext();
|
||||
return;
|
||||
}
|
||||
|
||||
// default chinese
|
||||
String[] temp = rundata.getCookies().getStrings("locale");
|
||||
String locale = null;
|
||||
if (temp != null) {
|
||||
if (temp.length > 1) {
|
||||
locale = temp[temp.length - 1];
|
||||
} else if (temp.length == 1) {
|
||||
locale = temp[0];
|
||||
}
|
||||
}
|
||||
if (locale == null || "".equals(locale)) {
|
||||
locale = "en";
|
||||
}
|
||||
|
||||
Locale newLocale = Locale.SIMPLIFIED_CHINESE;
|
||||
if ("en".equals(locale)) {
|
||||
newLocale = Locale.ENGLISH;
|
||||
} else if ("zh".equals(locale)) {
|
||||
newLocale = Locale.SIMPLIFIED_CHINESE;
|
||||
} else if ("zh_TW".equals(locale)) {
|
||||
newLocale = Locale.TRADITIONAL_CHINESE;
|
||||
}
|
||||
LocaleUtil.setLocale(newLocale);
|
||||
|
||||
pipelineContext.invokeNext();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.interceptor;
|
||||
|
||||
import com.alibaba.citrus.service.requestcontext.rewrite.RewriteSubstitutionContext;
|
||||
import com.alibaba.citrus.service.requestcontext.rewrite.RewriteSubstitutionHandler;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Rewrite: RESTFUL URL -> WebX URL.
|
||||
*
|
||||
*/
|
||||
public class RestfuleUrlRewriter implements RewriteSubstitutionHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RestfuleUrlRewriter.class);
|
||||
|
||||
private static final Map<String, String> pl2single;
|
||||
private static final Set<String> appParameter;
|
||||
private final static String METHOD_KEY = "_method"; // show,
|
||||
private final static String TYPE_KEY = "_type";
|
||||
private final static String ID_KEY = "id";
|
||||
private final static String PAGES_KEY = "currentPage";
|
||||
private final static String PATH_KEY = "_path";
|
||||
private final static Pattern SLASH_PATTERN = Pattern.compile("/+");
|
||||
private final static Pattern NUM_PATTERN = Pattern.compile("\\d+");
|
||||
private final static Pattern MULTI_NUM_PATTERN = Pattern.compile("[+\\d]+");
|
||||
private final static Pattern PAGES_SPLIT_PATTERN = Pattern.compile("/+pages/+");
|
||||
private final static Pattern PAGES_PATTERN = Pattern.compile(".*/+pages/+\\d+$");
|
||||
|
||||
static {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
map.put("services", "service");
|
||||
map.put("users", "user");
|
||||
map.put("addresses", "address");
|
||||
map.put("applications", "application");
|
||||
|
||||
map.put("providers", "provider");
|
||||
map.put("comsumers", "comsumer");
|
||||
|
||||
pl2single = Collections.unmodifiableMap(map);
|
||||
Set<String> set = new HashSet<String>();
|
||||
|
||||
set.add("_path");
|
||||
set.add("currentPage");
|
||||
set.add("_method");
|
||||
set.add("_type");
|
||||
set.add("id");
|
||||
|
||||
appParameter = Collections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
public void postSubstitution(RewriteSubstitutionContext context) {
|
||||
final String oldPath = context.getPath();
|
||||
String path = oldPath;
|
||||
while (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
|
||||
Map<String, String> param = new HashMap<String, String>();
|
||||
|
||||
// Paging
|
||||
if (PAGES_PATTERN.matcher(path).matches()) {
|
||||
String[] page_path = PAGES_SPLIT_PATTERN.split(path);
|
||||
path = page_path[0];
|
||||
param.put(PATH_KEY, page_path[0]);
|
||||
param.put(PAGES_KEY, page_path[1]);
|
||||
} else {
|
||||
param.put(PATH_KEY, path);
|
||||
}
|
||||
List<String> temp = Arrays.asList(SLASH_PATTERN.split(path));
|
||||
//Compatible with 2.0.x registry shell style url, for example: http://root:hello1234@127.0.0.1:8080/status/dubbo.test.api.HelloService:1.1
|
||||
if ("status".equals(temp.get(0)) && temp.size() > 1) {
|
||||
context.setPath("servicestatus");
|
||||
return;
|
||||
}
|
||||
//Compatible with paths containing group
|
||||
String[] split = temp.toArray(new String[temp.size()]);
|
||||
|
||||
if (temp.size() > 2 && temp.contains("services")) {
|
||||
List<String> parts = new ArrayList<String>();
|
||||
parts.addAll(temp);
|
||||
for (int i = 0; i < temp.size(); i++) {
|
||||
if ("services".equals(temp.get(i)) && i < (temp.size() - 1) && (!temp.get(i + 1).contains(".")) && (!temp.get(i + 1).matches("\\d+"))) {
|
||||
String group = parts.get(i + 1);
|
||||
String service = parts.get(i + 2);
|
||||
parts.remove(i + 1);
|
||||
parts.set(i + 1, group + "/" + service);
|
||||
break;
|
||||
}
|
||||
}
|
||||
split = parts.toArray(new String[parts.size()]);
|
||||
}
|
||||
|
||||
int index = split.length;
|
||||
// module/action
|
||||
if (split.length < 2) return;
|
||||
// The last part do not contains '.', like .htm .xsd .css etc.
|
||||
if (split[index - 1].contains(".")) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String type;
|
||||
// Even number
|
||||
// module/k/v/type or module/k/v/type/id/method
|
||||
if (index % 2 == 0) {
|
||||
if (MULTI_NUM_PATTERN.matcher(split[index - 2]).matches()) {
|
||||
// module/k/v/action/id/operate
|
||||
if (index < 4) return;
|
||||
|
||||
param.put(METHOD_KEY, split[index - 1]);
|
||||
param.put(ID_KEY, split[index - 2]);
|
||||
type = split[index - 3];
|
||||
param.put(TYPE_KEY, type);
|
||||
index -= 3;
|
||||
} else {
|
||||
// module/k/v/type
|
||||
type = split[index - 1];
|
||||
param.put(TYPE_KEY, type);
|
||||
--index;
|
||||
}
|
||||
}
|
||||
// Odd number
|
||||
// module/k/v/type/method or module/k/v/type/id
|
||||
else {
|
||||
if (index < 3) return;
|
||||
// module/k/v/type/id
|
||||
if (NUM_PATTERN.matcher(split[index - 1]).matches()) {
|
||||
param.put(ID_KEY, split[index - 1]);
|
||||
}
|
||||
// module/k/v/type/method
|
||||
else {
|
||||
param.put(METHOD_KEY, split[index - 1]);
|
||||
}
|
||||
type = split[index - 2];
|
||||
param.put(TYPE_KEY, type);
|
||||
index -= 2;
|
||||
}
|
||||
|
||||
// Extract KV pair
|
||||
for (int i = 1; i < index; i += 2) {
|
||||
param.put(split[i], split[i + 1]);
|
||||
}
|
||||
|
||||
String method = param.get(METHOD_KEY);
|
||||
|
||||
String defaultRedirect = null;
|
||||
if (method == null || method.equals("index")) {
|
||||
defaultRedirect = oldPath;
|
||||
} else {
|
||||
defaultRedirect = oldPath.split("/" + method)[0];
|
||||
}
|
||||
String id = param.get(ID_KEY);
|
||||
if (id != null) {
|
||||
int i = defaultRedirect.lastIndexOf("/");
|
||||
defaultRedirect = defaultRedirect.substring(0, i);
|
||||
}
|
||||
context.getParameters().setString("defaultRedirect", defaultRedirect);
|
||||
|
||||
final String module = split[0];
|
||||
context.setPath("/" + module + "/" + type + ".htm");
|
||||
|
||||
for (Map.Entry<String, String> entry : param.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (pl2single.containsKey(key)) {
|
||||
key = pl2single.get(key);
|
||||
} else if (appParameter.contains(key)) {
|
||||
// nothing
|
||||
} else {
|
||||
logger.info("key " + key + " is not pl noun!");
|
||||
}
|
||||
context.getParameters().setString(key, entry.getValue());
|
||||
}
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("REWRITE restful uri " + oldPath + " to uri " + module + "/" + type + ".htm?" + param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.interceptor;
|
||||
|
||||
import com.alibaba.citrus.service.pipeline.PipelineContext;
|
||||
import com.alibaba.citrus.service.pipeline.support.AbstractValve;
|
||||
import com.alibaba.citrus.turbine.TurbineRunData;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.governance.web.util.WebConstants;
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.citrus.turbine.util.TurbineUtil.getTurbineRunData;
|
||||
|
||||
public class ServicePrivilegeCheckValve extends AbstractValve {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServicePrivilegeCheckValve.class);
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Override
|
||||
protected void init() throws Exception {
|
||||
}
|
||||
|
||||
public void invoke(PipelineContext pipelineContext) throws Exception {
|
||||
User user = (User) request.getSession().getAttribute(WebConstants.CURRENT_USER_KEY);
|
||||
invokeCheckServicePrivilege(user);
|
||||
pipelineContext.invokeNext();
|
||||
}
|
||||
|
||||
|
||||
private void invokeCheckServicePrivilege(User user) {
|
||||
TurbineRunData rundata = getTurbineRunData(request);
|
||||
HttpSession session = request.getSession();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String[]> requestMapping = request.getParameterMap();
|
||||
|
||||
// record the last operation to request
|
||||
String returnURL = "";
|
||||
if (session.getAttribute("returnURL") == null) {
|
||||
returnURL = request.getContextPath();
|
||||
} else {
|
||||
returnURL = (String) session.getAttribute("returnURL");
|
||||
}
|
||||
|
||||
if (requestMapping.get("service").length > 0) {
|
||||
String service = ((String[]) requestMapping.get("service"))[0];
|
||||
String method = "index";
|
||||
if (requestMapping.get("_method").length > 0) {
|
||||
method = requestMapping.get("_method")[0];
|
||||
}
|
||||
|
||||
boolean exclude = "index".equals(method) || "show".equals(method);
|
||||
if (!exclude) {
|
||||
if (user != null && !user.hasServicePrivilege(service)) {
|
||||
request.setAttribute("returnURL", returnURL);
|
||||
redirectToNoRight(rundata);
|
||||
}
|
||||
}
|
||||
}
|
||||
String type = requestMapping.get("_type").length == 0 ? null : requestMapping.get("_type")[0];
|
||||
if (!"noServicePrivilege".equals(type)) {
|
||||
session.setAttribute("returnURL", request.getRequestURI());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect if in case of no right.
|
||||
* @param rundata
|
||||
*/
|
||||
private void redirectToNoRight(TurbineRunData rundata) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("No right to access: " + request.getRequestURI());
|
||||
}
|
||||
|
||||
rundata.getParameters().setString("returnURL1", (String) rundata.getRequest().getAttribute("returnURL"));
|
||||
rundata.setRedirectLocation("http://localhost:8080/governance/noServicePrivilege?returnURL=" + rundata.getRequest().getAttribute("returnURL"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.governance.web.common.pulltool.RootContextPath;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Error_404 {
|
||||
|
||||
public void execute(Map<String, Object> context) throws Throwable {
|
||||
String contextPath = (String) context.get("request.contextPath");
|
||||
context.put("rootContextPath", new RootContextPath(contextPath));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.governance.web.common.pulltool.RootContextPath;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Error_other {
|
||||
|
||||
public void execute(Map<String, Object> context) throws Throwable {
|
||||
String contextPath = (String) context.get("request.contextPath");
|
||||
context.put("rootContextPath", new RootContextPath(contextPath));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.utils.CompatibleTypeUtils;
|
||||
import com.alibaba.dubbo.governance.biz.common.i18n.MessageResourceService;
|
||||
import com.alibaba.dubbo.governance.web.common.pulltool.RootContextPath;
|
||||
import com.alibaba.dubbo.governance.web.util.WebConstants;
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* BaseScreen
|
||||
*
|
||||
*/
|
||||
public abstract class Restful {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(Restful.class);
|
||||
|
||||
protected static final Pattern SPACE_SPLIT_PATTERN = Pattern.compile("\\s+");
|
||||
//FIXME, to extract these auxiliary methods
|
||||
protected String role = null;
|
||||
protected String operator = null;
|
||||
protected User currentUser = null;
|
||||
protected String operatorAddress = null;
|
||||
protected String currentRegistry = null;
|
||||
@Autowired
|
||||
private MessageResourceService messageResourceService;
|
||||
|
||||
private static boolean isPrimitive(Class<?> cls) {
|
||||
return cls.isPrimitive() || cls == Boolean.class || cls == Byte.class
|
||||
|| cls == Character.class || cls == Short.class || cls == Integer.class
|
||||
|| cls == Long.class || cls == Float.class || cls == Double.class
|
||||
|| cls == String.class;
|
||||
}
|
||||
|
||||
private static Object convertPrimitive(Class<?> cls, String value) {
|
||||
if (cls == boolean.class || cls == Boolean.class) {
|
||||
return value == null || value.length() == 0 ? false : Boolean.valueOf(value);
|
||||
} else if (cls == byte.class || cls == Byte.class) {
|
||||
return value == null || value.length() == 0 ? 0 : Byte.valueOf(value);
|
||||
} else if (cls == char.class || cls == Character.class) {
|
||||
return value == null || value.length() == 0 ? '\0' : value.charAt(0);
|
||||
} else if (cls == short.class || cls == Short.class) {
|
||||
return value == null || value.length() == 0 ? 0 : Short.valueOf(value);
|
||||
} else if (cls == int.class || cls == Integer.class) {
|
||||
return value == null || value.length() == 0 ? 0 : Integer.valueOf(value);
|
||||
} else if (cls == long.class || cls == Long.class) {
|
||||
return value == null || value.length() == 0 ? 0 : Long.valueOf(value);
|
||||
} else if (cls == float.class || cls == Float.class) {
|
||||
return value == null || value.length() == 0 ? 0 : Float.valueOf(value);
|
||||
} else if (cls == double.class || cls == Double.class) {
|
||||
return value == null || value.length() == 0 ? 0 : Double.valueOf(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getMessage(String key, Object... args) {
|
||||
return messageResourceService.getMessage(key, args);
|
||||
}
|
||||
|
||||
public void execute(Map<String, Object> context) throws Throwable {
|
||||
if (context.get(WebConstants.CURRENT_USER_KEY) != null) {
|
||||
User user = (User) context.get(WebConstants.CURRENT_USER_KEY);
|
||||
currentUser = user;
|
||||
operator = user.getUsername();
|
||||
role = user.getRole();
|
||||
context.put(WebConstants.CURRENT_USER_KEY, user);
|
||||
}
|
||||
operatorAddress = (String) context.get("request.remoteHost");
|
||||
context.put("operator", operator);
|
||||
context.put("operatorAddress", operatorAddress);
|
||||
|
||||
context.put("currentRegistry", currentRegistry);
|
||||
|
||||
String httpMethod = (String) context.get("request.method");
|
||||
String method = (String) context.get("_method");
|
||||
String contextPath = (String) context.get("request.contextPath");
|
||||
context.put("rootContextPath", new RootContextPath(contextPath));
|
||||
|
||||
// Analyze Method
|
||||
if (method == null || method.length() == 0) {
|
||||
String id = (String) context.get("id");
|
||||
if (id == null || id.length() == 0) {
|
||||
method = "index";
|
||||
} else {
|
||||
method = "show";
|
||||
}
|
||||
}
|
||||
if ("index".equals(method)) {
|
||||
if ("post".equalsIgnoreCase(httpMethod)) {
|
||||
method = "create";
|
||||
}
|
||||
} else if ("show".equals(method)) {
|
||||
if ("put".equalsIgnoreCase(httpMethod) || "post".equalsIgnoreCase(httpMethod)) { // Instead of submitting a PUT request with a form, use POST instead
|
||||
method = "update";
|
||||
} else if ("delete".equalsIgnoreCase(httpMethod)) { // Instead of submitting a PUT request with a form, use POST instead
|
||||
method = "delete";
|
||||
}
|
||||
}
|
||||
context.put("_method", method);
|
||||
|
||||
try {
|
||||
Method m = null;
|
||||
try {
|
||||
m = getClass().getMethod(method, new Class<?>[]{Map.class});
|
||||
} catch (NoSuchMethodException e) {
|
||||
for (Method mtd : getClass().getMethods()) {
|
||||
if (Modifier.isPublic(mtd.getModifiers())
|
||||
&& mtd.getName().equals(method)) {
|
||||
m = mtd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m == null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if (m.getParameterTypes().length > 2) {
|
||||
throw new IllegalStateException("Unsupport restful method " + m);
|
||||
} else if (m.getParameterTypes().length == 2
|
||||
&& (m.getParameterTypes()[0].equals(Map.class)
|
||||
|| !m.getParameterTypes()[1].equals(Map.class))) {
|
||||
throw new IllegalStateException("Unsupport restful method " + m);
|
||||
}
|
||||
Object r;
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
r = m.invoke(this, new Object[0]);
|
||||
} else {
|
||||
Object value;
|
||||
Class<?> t = m.getParameterTypes()[0];
|
||||
if (Map.class.equals(t)) {
|
||||
value = context;
|
||||
} else if (isPrimitive(t)) {
|
||||
String id = (String) context.get("id");
|
||||
value = convertPrimitive(t, id);
|
||||
} else if (t.isArray() && isPrimitive(t.getComponentType())) {
|
||||
String id = (String) context.get("id");
|
||||
String[] ids = id == null ? new String[0] : id.split("[.+]+");
|
||||
value = Array.newInstance(t.getComponentType(), ids.length);
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
Array.set(value, i, convertPrimitive(t.getComponentType(), ids[i]));
|
||||
}
|
||||
} else {
|
||||
value = t.newInstance();
|
||||
for (Method mtd : t.getMethods()) {
|
||||
if (Modifier.isPublic(mtd.getModifiers())
|
||||
&& mtd.getName().startsWith("set")
|
||||
&& mtd.getParameterTypes().length == 1) {
|
||||
String p = mtd.getName().substring(3, 4).toLowerCase() + mtd.getName().substring(4);
|
||||
Object v = context.get(p);
|
||||
if (v == null) {
|
||||
if ("operator".equals(p)) {
|
||||
v = operator;
|
||||
} else if ("operatorAddress".equals(p)) {
|
||||
v = (String) context.get("request.remoteHost");
|
||||
}
|
||||
}
|
||||
if (v != null) {
|
||||
try {
|
||||
mtd.invoke(value, new Object[]{CompatibleTypeUtils.compatibleTypeConvert(v, mtd.getParameterTypes()[0])});
|
||||
} catch (Throwable e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m.getParameterTypes().length == 1) {
|
||||
r = m.invoke(this, new Object[]{value});
|
||||
} else {
|
||||
r = m.invoke(this, new Object[]{value, context});
|
||||
}
|
||||
}
|
||||
if (m.getReturnType() == boolean.class || m.getReturnType() == Boolean.class) {
|
||||
context.put("rundata.layout", "redirect");
|
||||
context.put("rundata.target", "redirect");
|
||||
context.put("success", r == null || ((Boolean) r).booleanValue());
|
||||
if (context.get("redirect") == null) {
|
||||
context.put("redirect", getDefaultRedirect(context, method));
|
||||
}
|
||||
} else if (m.getReturnType() == String.class) {
|
||||
String redirect = (String) r;
|
||||
if (redirect == null) {
|
||||
redirect = getDefaultRedirect(context, method);
|
||||
}
|
||||
|
||||
if (context.get("chain") != null) {
|
||||
context.put("rundata.layout", "home");
|
||||
context.put("rundata.target", "home");
|
||||
} else {
|
||||
context.put("rundata.redirect", redirect);
|
||||
}
|
||||
} else {
|
||||
context.put("rundata.layout", method);
|
||||
context.put("rundata.target", context.get("rundata.target") + "/" + method);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof InvocationTargetException) {
|
||||
throw ((InvocationTargetException) e).getTargetException();
|
||||
}
|
||||
// if (e instanceof InvocationTargetException) {
|
||||
// e = ((InvocationTargetException) e).getTargetException();
|
||||
// }
|
||||
// logger.warn(e.getMessage(), e);
|
||||
// context.put("rundata.layout", "redirect");
|
||||
// context.put("rundata.target", "redirect");
|
||||
// context.put("success", false);
|
||||
// context.put("exception", e);
|
||||
// context.put("redirect", getDefaultRedirect(context, method));
|
||||
}
|
||||
}
|
||||
|
||||
private String getDefaultRedirect(Map<String, Object> context, String operate) {
|
||||
String defaultRedirect = (String) context.get("defaultRedirect");
|
||||
return defaultRedirect;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
package com.alibaba.dubbo.governance.web.common.pulltool;
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* DateFormat Utility
|
||||
*
|
||||
*/
|
||||
public class DateFormatUtil {
|
||||
|
||||
private static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
private static final ThreadLocal<Map<String, DateFormat>> tl = new ThreadLocal<Map<String, DateFormat>>();
|
||||
|
||||
/**
|
||||
* According to the specified format, Get a DateFormat
|
||||
*
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static DateFormat getDateFormat(String format) {
|
||||
Map<String, DateFormat> map = tl.get();
|
||||
|
||||
if (map == null) {
|
||||
map = new HashMap<String, DateFormat>();
|
||||
tl.set(map);
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(format)) {
|
||||
format = DEFAULT_FORMAT;
|
||||
}
|
||||
|
||||
DateFormat ret = map.get(format);
|
||||
|
||||
if (ret == null) {
|
||||
ret = new SimpleDateFormat(format);
|
||||
map.put(format, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Default DateFormat
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static DateFormat getDateFormat() {
|
||||
return getDateFormat(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.pulltool;
|
||||
|
||||
import com.alibaba.citrus.service.pull.ToolFactory;
|
||||
import com.alibaba.dubbo.governance.biz.common.i18n.MessageResourceService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* PullTool for accessing message bundle.
|
||||
*x
|
||||
*/
|
||||
public class I18nMessageTool implements ToolFactory {
|
||||
|
||||
@Autowired
|
||||
private MessageResourceService messageResourceService;
|
||||
private boolean singleton = true;
|
||||
|
||||
public Object createTool() throws Exception {
|
||||
return messageResourceService;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return this.singleton;
|
||||
}
|
||||
|
||||
public void setSingleton(boolean singleton) {
|
||||
this.singleton = singleton;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.pulltool;
|
||||
|
||||
public class RootContextPath {
|
||||
|
||||
private String contextPath;
|
||||
|
||||
public RootContextPath(String contextPath) {
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
public String getURI(String uri) {
|
||||
String prefix;
|
||||
if (contextPath != null && contextPath.length() > 0 && !"/".equals(contextPath)) {
|
||||
prefix = contextPath;
|
||||
} else {
|
||||
prefix = "";
|
||||
}
|
||||
if (uri.startsWith("/")) {
|
||||
return prefix + uri;
|
||||
} else {
|
||||
return prefix + "/" + uri;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.pulltool;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.NetUtils;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.RouteService;
|
||||
import com.alibaba.dubbo.registry.common.domain.Consumer;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.domain.Route;
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
import com.alibaba.dubbo.registry.common.route.ParseUtils;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteRule;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteRule.MatchPair;
|
||||
import com.alibaba.dubbo.registry.common.util.StringEscapeUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Tool
|
||||
*
|
||||
*/
|
||||
public class Tool {
|
||||
|
||||
private static final Comparator<String> SIMPLE_NAME_COMPARATOR = new Comparator<String>() {
|
||||
public int compare(String s1, String s2) {
|
||||
if (s1 == null && s2 == null) {
|
||||
return 0;
|
||||
}
|
||||
if (s1 == null) {
|
||||
return -1;
|
||||
}
|
||||
if (s2 == null) {
|
||||
return 1;
|
||||
}
|
||||
s1 = getSimpleName(s1);
|
||||
s2 = getSimpleName(s2);
|
||||
return s1.compareToIgnoreCase(s2);
|
||||
}
|
||||
};
|
||||
private OverrideService overrideService;
|
||||
private RouteService routeService;
|
||||
|
||||
public static String toStackTraceString(Throwable t) {
|
||||
StringWriter writer = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(writer);
|
||||
t.printStackTrace(pw);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public static boolean isContains(String[] values, String value) {
|
||||
return StringUtils.isContains(values, value);
|
||||
}
|
||||
|
||||
public static boolean startWith(String value, String prefix) {
|
||||
return value.startsWith(prefix);
|
||||
}
|
||||
|
||||
public static String getHostPrefix(String address) {
|
||||
if (address != null && address.length() > 0) {
|
||||
String hostname = getHostName(address);
|
||||
if (!address.startsWith(hostname)) {
|
||||
return "(" + hostname + ")";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getHostName(String address) {
|
||||
return NetUtils.getHostName(address);
|
||||
}
|
||||
|
||||
public static String getHostAddress(String address) {
|
||||
if (address != null && address.length() > 0) {
|
||||
int i = address.indexOf(':');
|
||||
String port = address.substring(i + 1);
|
||||
String hostname = NetUtils.getHostName(address);
|
||||
if (!address.equals(hostname)) {
|
||||
return hostname + ":" + port;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getPath(String url) {
|
||||
try {
|
||||
return URL.valueOf(url).getPath();
|
||||
} catch (Throwable t) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getAddress(String url) {
|
||||
try {
|
||||
return URL.valueOf(url).getAddress();
|
||||
} catch (Throwable t) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getInterface(String service) {
|
||||
if (service != null && service.length() > 0) {
|
||||
int i = service.indexOf('/');
|
||||
if (i >= 0) {
|
||||
service = service.substring(i + 1);
|
||||
}
|
||||
i = service.lastIndexOf(':');
|
||||
if (i >= 0) {
|
||||
service = service.substring(0, i);
|
||||
}
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
public static String getGroup(String service) {
|
||||
if (service != null && service.length() > 0) {
|
||||
int i = service.indexOf('/');
|
||||
if (i >= 0) {
|
||||
return service.substring(0, i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getVersion(String service) {
|
||||
if (service != null && service.length() > 0) {
|
||||
int i = service.lastIndexOf(':');
|
||||
if (i >= 0) {
|
||||
return service.substring(i + 1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getIP(String address) {
|
||||
if (address != null && address.length() > 0) {
|
||||
int i = address.indexOf("://");
|
||||
if (i >= 0) {
|
||||
address = address.substring(i + 3);
|
||||
}
|
||||
i = address.indexOf('/');
|
||||
if (i >= 0) {
|
||||
address = address.substring(0, i);
|
||||
}
|
||||
i = address.indexOf('@');
|
||||
if (i >= 0) {
|
||||
address = address.substring(i + 1);
|
||||
}
|
||||
i = address.indexOf(':');
|
||||
if (i >= 0) {
|
||||
address = address.substring(0, i);
|
||||
}
|
||||
if (address.matches("[a-zA-Z]+")) {
|
||||
try {
|
||||
address = InetAddress.getByName(address).getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
public static String encode(String url) {
|
||||
try {
|
||||
return URLEncoder.encode(url, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
public static String escape(String html) {
|
||||
return StringEscapeUtils.escapeHtml(html);
|
||||
}
|
||||
|
||||
public static String unescape(String html) {
|
||||
return StringEscapeUtils.unescapeHtml(html);
|
||||
}
|
||||
|
||||
public static String encodeUrl(String url) {
|
||||
return URL.encode(url);
|
||||
}
|
||||
|
||||
public static String decodeUrl(String url) {
|
||||
return URL.decode(url);
|
||||
}
|
||||
|
||||
public static String encodeHtml(String html) {
|
||||
return StringEscapeUtils.escapeHtml(html);
|
||||
}
|
||||
|
||||
public static int countMapValues(Map<?, ?> map) {
|
||||
int total = 0;
|
||||
if (map != null && map.size() > 0) {
|
||||
for (Object value : map.values()) {
|
||||
if (value != null) {
|
||||
if (value instanceof Number) {
|
||||
total += ((Number) value).intValue();
|
||||
} else if (value.getClass().isArray()) {
|
||||
total += Array.getLength(value);
|
||||
} else if (value instanceof Collection) {
|
||||
total += ((Collection<?>) value).size();
|
||||
} else if (value instanceof Map) {
|
||||
total += ((Map<?, ?>) value).size();
|
||||
} else {
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static List<String> sortSimpleName(List<String> list) {
|
||||
if (list != null && list.size() > 0) {
|
||||
Collections.sort(list, SIMPLE_NAME_COMPARATOR);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static String getSimpleName(String name) {
|
||||
if (name != null && name.length() > 0) {
|
||||
final int ip = name.indexOf('/');
|
||||
String v = ip != -1 ? name.substring(0, ip + 1) : "";
|
||||
|
||||
int i = name.lastIndexOf(':');
|
||||
int j = (i >= 0 ? name.lastIndexOf('.', i) : name.lastIndexOf('.'));
|
||||
if (j >= 0) {
|
||||
name = name.substring(j + 1);
|
||||
}
|
||||
name = v + name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String getParameter(String parameters, String key) {
|
||||
String value = "";
|
||||
if (parameters != null && parameters.length() > 0) {
|
||||
String[] pairs = parameters.split("&");
|
||||
for (String pair : pairs) {
|
||||
String[] kv = pair.split("=");
|
||||
if (key.equals(kv[0])) {
|
||||
value = kv[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Map<String, String> toParameterMap(String parameters) {
|
||||
return StringUtils.parseQueryString(parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version value from the paramters parameter of provider
|
||||
*
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
public static String getVersionFromPara(String parameters) {
|
||||
String version = "";
|
||||
if (parameters != null && parameters.length() > 0) {
|
||||
String[] params = parameters.split("&");
|
||||
for (String o : params) {
|
||||
String[] kv = o.split("=");
|
||||
if ("version".equals(kv[0])) {
|
||||
version = kv[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public static boolean isProviderEnabled(Provider provider, List<Override> oList) {
|
||||
for (Override o : oList) {
|
||||
if (o.isMatch(provider)) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(o.getParams());
|
||||
String disbaled = params.get(Constants.DISABLED_KEY);
|
||||
if (disbaled != null && disbaled.length() > 0) {
|
||||
return !"true".equals(disbaled);
|
||||
}
|
||||
}
|
||||
}
|
||||
return provider.isEnabled();
|
||||
}
|
||||
|
||||
public static int getProviderWeight(Provider provider, List<Override> oList) {
|
||||
for (Override o : oList) {
|
||||
if (o.isMatch(provider)) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(o.getParams());
|
||||
String weight = params.get(Constants.WEIGHT_KEY);
|
||||
if (weight != null && weight.length() > 0) {
|
||||
return Integer.parseInt(weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
return provider.getWeight();
|
||||
}
|
||||
|
||||
public void setOverrideService(OverrideService overrideService) {
|
||||
this.overrideService = overrideService;
|
||||
}
|
||||
|
||||
public void setRouteService(RouteService routeService) {
|
||||
this.routeService = routeService;
|
||||
}
|
||||
|
||||
public String formatTimestamp(String timestamp) {
|
||||
if (timestamp == null || timestamp.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
return formatDate(new Date(Long.valueOf(timestamp)));
|
||||
}
|
||||
|
||||
//format date
|
||||
public String formatDate(Date date) {
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
return DateFormatUtil.getDateFormat().format(date);
|
||||
}
|
||||
|
||||
public String formatDate(Date date, String template) {
|
||||
if (date == null || template == null) {
|
||||
return "";
|
||||
}
|
||||
return DateFormatUtil.getDateFormat(template).format(date);
|
||||
}
|
||||
|
||||
public boolean beforeNow(Date date) {
|
||||
Date now = new Date();
|
||||
if (now.after(date)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//minus of date
|
||||
public long dateMinus(Date date1, Date date2) {
|
||||
return (date1.getTime() - date1.getTime()) / 1000;
|
||||
}
|
||||
|
||||
public boolean isProviderEnabled(Provider provider) {
|
||||
List<Override> oList = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress());
|
||||
return isProviderEnabled(provider, oList);
|
||||
}
|
||||
|
||||
public int getProviderWeight(Provider provider) {
|
||||
List<Override> oList = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress());
|
||||
return getProviderWeight(provider, oList);
|
||||
}
|
||||
|
||||
public boolean isInBlackList(Consumer consumer) {
|
||||
String service = consumer.getService();
|
||||
List<Route> routes = routeService.findForceRouteByService(service);
|
||||
if (routes == null || routes.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
String ip = getIP(consumer.getAddress());
|
||||
for (Route route : routes) {
|
||||
try {
|
||||
if (!route.isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
String filterRule = route.getFilterRule();
|
||||
if (filterRule == null || filterRule.length() == 0 || "false".equals(filterRule)) {
|
||||
Map<String, MatchPair> rule = RouteRule.parseRule(route.getMatchRule());
|
||||
MatchPair pair = rule.get("consumer.host");
|
||||
if (pair == null) {
|
||||
pair = rule.get("host");
|
||||
}
|
||||
if (pair != null) {
|
||||
if (pair.getMatches() != null && pair.getMatches().size() > 0) {
|
||||
for (String host : pair.getMatches()) {
|
||||
if (ParseUtils.isMatchGlobPattern(host, ip)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pair.getUnmatches() != null && pair.getUnmatches().size() > 0) {
|
||||
boolean forbid = true;
|
||||
for (String host : pair.getUnmatches()) {
|
||||
if (ParseUtils.isMatchGlobPattern(host, ip)) {
|
||||
forbid = false;
|
||||
}
|
||||
}
|
||||
if (forbid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getConsumerMock(Consumer consumer) {
|
||||
return getOverridesMock(consumer.getOverrides());
|
||||
}
|
||||
|
||||
public String getOverridesMock(List<Override> overrides) {
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
for (Override override : overrides) {
|
||||
Map<String, String> params = StringUtils.parseQueryString(override.getParams());
|
||||
String mock = params.get("mock");
|
||||
if (mock != null && mock.length() > 0) {
|
||||
return mock;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean checkUrl(User user, String uri) {
|
||||
return true;
|
||||
/*if(!User.ROOT.equals(user.getRole())){
|
||||
List<String> disabledSysinfo = new ArrayList<String>();
|
||||
List<String> disabledSysmanage = new ArrayList<String>();
|
||||
Map<String, Boolean> features = daoCache.getFeatures();
|
||||
if (features.size() > 0){
|
||||
for(Entry<String,Boolean> feature : features.entrySet()){
|
||||
if(feature.getKey().startsWith("Sysinfo") && !feature.getValue()){
|
||||
disabledSysinfo.add(feature.getKey().replace(".", "/").toLowerCase());
|
||||
}else if(feature.getKey().startsWith("Sysmanage") && !feature.getValue()){
|
||||
disabledSysmanage.add(feature.getKey().replace(".", "/").toLowerCase());
|
||||
}
|
||||
}
|
||||
if(uri.startsWith("/sysinfo")){
|
||||
for(String disabled : disabledSysinfo){
|
||||
if (uri.contains(disabled)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(uri.startsWith("/sysmanage")){
|
||||
for(String disabled : disabledSysmanage){
|
||||
if (uri.contains(disabled)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;*/
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.pulltool;
|
||||
|
||||
import com.alibaba.citrus.service.pull.ToolFactory;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.RouteService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* PullTool for accessing message bundle.
|
||||
*
|
||||
*/
|
||||
public class ToolUtil implements ToolFactory {
|
||||
@Autowired
|
||||
OverrideService overrideService;
|
||||
|
||||
@Autowired
|
||||
RouteService routeService;
|
||||
private boolean singleton = false;
|
||||
|
||||
public Object createTool() throws Exception {
|
||||
Tool tool = new Tool();
|
||||
tool.setOverrideService(overrideService);
|
||||
tool.setRouteService(routeService);
|
||||
return tool;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return this.singleton;
|
||||
}
|
||||
|
||||
public void setSingleton(boolean singleton) {
|
||||
this.singleton = singleton;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.resolver;
|
||||
|
||||
import com.alibaba.citrus.service.dataresolver.DataResolver;
|
||||
import com.alibaba.citrus.service.dataresolver.DataResolverContext;
|
||||
import com.alibaba.citrus.service.dataresolver.DataResolverFactory;
|
||||
import com.alibaba.citrus.turbine.TurbineRunDataInternal;
|
||||
import com.alibaba.citrus.turbine.util.TurbineUtil;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* MapDataResolverFactory
|
||||
*
|
||||
*/
|
||||
public class MapDataResolverFactory implements DataResolverFactory {
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
public DataResolver getDataResolver(DataResolverContext context) {
|
||||
if (Map.class == context.getTypeInfo().getRawType()) {
|
||||
return new MapDataResolver(context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public class MapDataResolver implements DataResolver {
|
||||
|
||||
public final DataResolverContext context;
|
||||
|
||||
public MapDataResolver(DataResolverContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Object resolve() {
|
||||
TurbineRunDataInternal rundata = (TurbineRunDataInternal) TurbineUtil.getTurbineRunData(request);
|
||||
return new ParameterMap(request, rundata.getContext(), rundata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.resolver;
|
||||
|
||||
import com.alibaba.citrus.turbine.Context;
|
||||
import com.alibaba.citrus.turbine.TurbineRunDataInternal;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* ParameterMap
|
||||
*
|
||||
*/
|
||||
public class ParameterMap implements Map<String, Object> {
|
||||
|
||||
private static final String CONTEXT_PREFIX = "context.";
|
||||
|
||||
private static final String PARAMETER_PREFIX = "parameter.";
|
||||
|
||||
private static final String HEADER_PREFIX = "header.";
|
||||
|
||||
private static final String REQUEST_PREFIX = "request.";
|
||||
|
||||
private static final String SESSION_PREFIX = "session.";
|
||||
|
||||
private static final String COOKIE_PREFIX = "cookie.";
|
||||
|
||||
private static final String APPLICATION_PREFIX = "application.";
|
||||
|
||||
private static final String RUNDATA_PREFIX = "rundata.";
|
||||
|
||||
private static final String METHOD_KEY = REQUEST_PREFIX + "method";
|
||||
|
||||
private static final String REMOTE_HOST_KEY = REQUEST_PREFIX + "remoteHost";
|
||||
|
||||
private static final String CONTEXT_PATH_KEY = REQUEST_PREFIX + "contextPath";
|
||||
|
||||
private static final String USER_PRINCIPAL_KEY = REQUEST_PREFIX + "userPrincipal";
|
||||
|
||||
private static final String TARGET_KEY = RUNDATA_PREFIX + "target";
|
||||
|
||||
private static final String FORWARD_KEY = RUNDATA_PREFIX + "forward";
|
||||
|
||||
private static final String BACKWARD_KEY = RUNDATA_PREFIX + "backward";
|
||||
|
||||
private static final String REDIRECT_KEY = RUNDATA_PREFIX + "redirect";
|
||||
|
||||
private static final String REDIRECTED_KEY = RUNDATA_PREFIX + "redirected";
|
||||
|
||||
private static final String LAYOUT_KEY = RUNDATA_PREFIX + "layout";
|
||||
|
||||
private static final String LAYOUT_ENABLED_KEY = RUNDATA_PREFIX + "layoutEnabled";
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private final Context context;
|
||||
|
||||
private final TurbineRunDataInternal rundata;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ParameterMap(HttpServletRequest request, Context context, TurbineRunDataInternal navigator) {
|
||||
super();
|
||||
this.request = request;
|
||||
this.context = context;
|
||||
this.rundata = navigator;
|
||||
Enumeration<String> keys = request.getParameterNames();
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = keys.nextElement();
|
||||
Object value = getParameterValue(key);
|
||||
context.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
Set<String> keys = context.keySet();
|
||||
if (keys != null && keys.size() > 0) {
|
||||
for (String key : keys) {
|
||||
if (value.equals(context.get(key))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
String k = (String) key;
|
||||
if (k == null || k.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
return context.containsKey(k) || request.getParameter(k) != null;
|
||||
}
|
||||
|
||||
public Object get(Object key) {
|
||||
String k = (String) key;
|
||||
if (k == null || k.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (METHOD_KEY.equals(k)) {
|
||||
return request.getMethod();
|
||||
} else if (REMOTE_HOST_KEY.equals(k)) {
|
||||
return request.getRemoteHost();
|
||||
} else if (CONTEXT_PATH_KEY.equals(k)) {
|
||||
return request.getContextPath();
|
||||
} else if (USER_PRINCIPAL_KEY.equals(k)) {
|
||||
return request.getUserPrincipal();
|
||||
} else if (TARGET_KEY.equals(k)) {
|
||||
return rundata.getTarget();
|
||||
} else if (FORWARD_KEY.equals(k)) {
|
||||
return rundata.getRedirectTarget();
|
||||
} else if (REDIRECT_KEY.equals(k)) {
|
||||
return rundata.getRedirectLocation();
|
||||
} else if (REDIRECTED_KEY.equals(k)) {
|
||||
return rundata.isRedirected();
|
||||
} else if (LAYOUT_KEY.equals(k)) {
|
||||
return rundata.getLayoutTemplateOverride();
|
||||
} else if (LAYOUT_ENABLED_KEY.equals(k)) {
|
||||
return rundata.isLayoutEnabled();
|
||||
} else if (k.startsWith(CONTEXT_PREFIX)) {
|
||||
return context.get(k.substring(CONTEXT_PREFIX.length()));
|
||||
} else if (k.startsWith(PARAMETER_PREFIX)) {
|
||||
return getParameterValue(k.substring(PARAMETER_PREFIX.length()));
|
||||
} else if (k.startsWith(HEADER_PREFIX)) {
|
||||
return request.getHeader(k.substring(HEADER_PREFIX.length()));
|
||||
} else if (k.startsWith(REQUEST_PREFIX)) {
|
||||
return request.getAttribute(k.substring(REQUEST_PREFIX.length()));
|
||||
} else if (k.startsWith(SESSION_PREFIX)) {
|
||||
return request.getSession().getAttribute(k.substring(SESSION_PREFIX.length()));
|
||||
} else if (k.startsWith(COOKIE_PREFIX)) {
|
||||
return getCookieValue(k.substring(COOKIE_PREFIX.length()));
|
||||
} else if (k.startsWith(APPLICATION_PREFIX)) {
|
||||
return request.getSession().getServletContext().getAttribute(k.substring(APPLICATION_PREFIX.length()));
|
||||
} else {
|
||||
Object value = context.get(k);
|
||||
if (value == null) {
|
||||
value = getParameterValue(k);
|
||||
if (value == null) {
|
||||
value = request.getAttribute(k);
|
||||
if (value == null) {
|
||||
value = request.getSession().getAttribute(k);
|
||||
if (value == null) {
|
||||
value = getCookieValue(k);
|
||||
if (value == null) {
|
||||
value = request.getSession().getServletContext().getAttribute(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private Object getParameterValue(String key) {
|
||||
String[] values = request.getParameterValues(key);
|
||||
if (values == null || values.length == 0) {
|
||||
return null;
|
||||
} else if (values.length == 1) {
|
||||
return values[0];
|
||||
} else {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
private Object getCookieValue(String key) {
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null && cookies.length > 0) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (key.equals(cookie.getName())) {
|
||||
return cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object put(String key, Object value) {
|
||||
if (key == null || key.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (TARGET_KEY.equals(key)) {
|
||||
rundata.setTarget((String) value);
|
||||
return null;
|
||||
} else if (FORWARD_KEY.equals(key)) {
|
||||
rundata.setRedirectTarget((String) value);
|
||||
return null;
|
||||
} else if (BACKWARD_KEY.equals(key)) {
|
||||
rundata.setRedirectLocation(request.getHeader("Referer"));
|
||||
return null;
|
||||
} else if (REDIRECT_KEY.equals(key)) {
|
||||
rundata.setRedirectLocation((String) value);
|
||||
return null;
|
||||
} else if (LAYOUT_KEY.equals(key)) {
|
||||
rundata.setLayout((String) value);
|
||||
return null;
|
||||
} else if (LAYOUT_ENABLED_KEY.equals(key)) {
|
||||
rundata.setLayoutEnabled((Boolean) value);
|
||||
return null;
|
||||
} else {
|
||||
if (key.startsWith(REQUEST_PREFIX)) {
|
||||
key = key.substring(APPLICATION_PREFIX.length());
|
||||
Object old = request.getAttribute(key);
|
||||
if (value == null) {
|
||||
request.removeAttribute(key);
|
||||
} else {
|
||||
request.setAttribute(key, value);
|
||||
}
|
||||
return old;
|
||||
} else if (key.startsWith(SESSION_PREFIX)) {
|
||||
key = key.substring(APPLICATION_PREFIX.length());
|
||||
Object old = request.getSession().getAttribute(key);
|
||||
if (value == null) {
|
||||
request.getSession().removeAttribute(key);
|
||||
} else {
|
||||
request.getSession().setAttribute(key, value);
|
||||
}
|
||||
return old;
|
||||
} else if (key.startsWith(COOKIE_PREFIX)) {
|
||||
key = key.substring(APPLICATION_PREFIX.length());
|
||||
Object old = null;
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null && cookies.length > 0) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (key.equals(cookie.getName())) {
|
||||
old = cookie.getValue();
|
||||
if (value == null) {
|
||||
cookie.setMaxAge(-1);
|
||||
} else {
|
||||
cookie.setValue((String) value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return old;
|
||||
} else if (key.startsWith(APPLICATION_PREFIX)) {
|
||||
key = key.substring(APPLICATION_PREFIX.length());
|
||||
Object old = request.getSession().getServletContext().getAttribute(key);
|
||||
if (value == null) {
|
||||
request.getSession().getServletContext().removeAttribute(key);
|
||||
} else {
|
||||
request.getSession().getServletContext().setAttribute(key, value);
|
||||
}
|
||||
return old;
|
||||
} else {
|
||||
if (key.startsWith(APPLICATION_PREFIX)) {
|
||||
key = key.substring(APPLICATION_PREFIX.length());
|
||||
}
|
||||
Object old = context.get(key);
|
||||
if (value == null) {
|
||||
context.remove(key);
|
||||
} else {
|
||||
context.put(key, value);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object remove(Object key) {
|
||||
return put((String) key, null);
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends String, ? extends Object> map) {
|
||||
if (map != null && map.size() > 0) {
|
||||
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
|
||||
put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
Set<String> keys = context.keySet();
|
||||
if (keys != null && keys.size() > 0) {
|
||||
for (String key : keys) {
|
||||
context.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> keySet() {
|
||||
return context.keySet();
|
||||
}
|
||||
|
||||
public Collection<Object> values() {
|
||||
Set<String> keys = context.keySet();
|
||||
Set<Object> values = new HashSet<Object>();
|
||||
if (keys != null && keys.size() > 0) {
|
||||
for (String key : keys) {
|
||||
values.add(context.get(key));
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public Set<Entry<String, Object>> entrySet() {
|
||||
Set<String> keys = context.keySet();
|
||||
Set<Entry<String, Object>> entries = new HashSet<Entry<String, Object>>();
|
||||
if (keys != null && keys.size() > 0) {
|
||||
for (String key : keys) {
|
||||
entries.add(new ParameterEntry(key));
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
private class ParameterEntry implements Entry<String, Object> {
|
||||
|
||||
private final String key;
|
||||
|
||||
private volatile Object value;
|
||||
|
||||
public ParameterEntry(String key) {
|
||||
this.key = key;
|
||||
this.value = ParameterMap.this.get(key);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object setValue(Object value) {
|
||||
this.value = value;
|
||||
return ParameterMap.this.put(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.common.utils;
|
||||
|
||||
import com.alibaba.dubbo.governance.service.OwnerService;
|
||||
import com.alibaba.dubbo.registry.common.route.ParseUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class RelateUserUtils {
|
||||
/**
|
||||
* Add an owner related with service
|
||||
*
|
||||
* @param usernames the user to add
|
||||
* @param serviceName no wildcards
|
||||
*/
|
||||
public static void addOwnersOfService(Set<String> usernames, String serviceName,
|
||||
OwnerService ownerDAO) {
|
||||
List<String> serviceNamePatterns = ownerDAO.findAllServiceNames();
|
||||
for (String p : serviceNamePatterns) {
|
||||
if (ParseUtils.isMatchGlobPattern(p, serviceName)) {
|
||||
List<String> list = ownerDAO.findUsernamesByServiceName(p);
|
||||
usernames.addAll(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an owner related with service pattern
|
||||
*
|
||||
* @param usernames the user to add
|
||||
* @param serviceNamePattern service pattern, Glob
|
||||
*/
|
||||
public static void addOwnersOfServicePattern(Set<String> usernames, String serviceNamePattern,
|
||||
OwnerService ownerDAO) {
|
||||
List<String> serviceNamePatterns = ownerDAO.findAllServiceNames();
|
||||
for (String p : serviceNamePatterns) {
|
||||
if (ParseUtils.hasIntersection(p, serviceNamePattern)) {
|
||||
List<String> list = ownerDAO.findUsernamesByServiceName(p);
|
||||
usernames.addAll(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.service.RouteService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Access;
|
||||
import com.alibaba.dubbo.registry.common.domain.Route;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteRule;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteRule.MatchPair;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Providers. URI: /services/$service/accesses
|
||||
*
|
||||
*/
|
||||
public class Accesses extends Restful {
|
||||
|
||||
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3}$");
|
||||
private static final Pattern LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$");
|
||||
private static final Pattern ALL_IP_PATTERN = Pattern.compile("0{1,3}(\\.0{1,3}){3}$");
|
||||
@Autowired
|
||||
private RouteService routeService;
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
public void index(Map<String, Object> context) throws Exception {
|
||||
String service = (String) context.get("service");
|
||||
String address = (String) context.get("address");
|
||||
address = Tool.getIP(address);
|
||||
List<Route> routes;
|
||||
if (service != null && service.length() > 0) {
|
||||
routes = routeService.findForceRouteByService(service);
|
||||
} else if (address != null && address.length() > 0) {
|
||||
routes = routeService.findForceRouteByAddress(address);
|
||||
} else {
|
||||
routes = routeService.findAllForceRoute();
|
||||
}
|
||||
List<Access> accesses = new ArrayList<Access>();
|
||||
if (routes == null) {
|
||||
context.put("accesses", accesses);
|
||||
return;
|
||||
}
|
||||
for (Route route : routes) {
|
||||
Map<String, MatchPair> rule = RouteRule.parseRule(route.getMatchRule());
|
||||
MatchPair pair = rule.get("consumer.host");
|
||||
if (pair != null) {
|
||||
for (String host : pair.getMatches()) {
|
||||
Access access = new Access();
|
||||
access.setAddress(host);
|
||||
access.setService(route.getService());
|
||||
access.setAllow(false);
|
||||
accesses.add(access);
|
||||
}
|
||||
for (String host : pair.getUnmatches()) {
|
||||
Access access = new Access();
|
||||
access.setAddress(host);
|
||||
access.setService(route.getService());
|
||||
access.setAllow(true);
|
||||
accesses.add(access);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.put("accesses", accesses);
|
||||
}
|
||||
|
||||
public void add(Map<String, Object> context) {
|
||||
List<String> serviceList = Tool.sortSimpleName(providerService.findServices());
|
||||
context.put("serviceList", serviceList);
|
||||
}
|
||||
|
||||
public boolean create(Map<String, Object> context) throws Exception {
|
||||
String addr = (String) context.get("consumerAddress");
|
||||
String services = (String) context.get("service");
|
||||
Set<String> consumerAddresses = toAddr(addr);
|
||||
Set<String> aimServices = toService(services);
|
||||
for (String aimService : aimServices) {
|
||||
boolean isFirst = false;
|
||||
List<Route> routes = routeService.findForceRouteByService(aimService);
|
||||
Route route = null;
|
||||
if (routes == null || routes.size() == 0) {
|
||||
isFirst = true;
|
||||
route = new Route();
|
||||
route.setService(aimService);
|
||||
route.setForce(true);
|
||||
route.setName(aimService + " blackwhitelist");
|
||||
route.setFilterRule("false");
|
||||
route.setEnabled(true);
|
||||
} else {
|
||||
route = routes.get(0);
|
||||
}
|
||||
Map<String, MatchPair> when = null;
|
||||
MatchPair matchPair = null;
|
||||
if (isFirst) {
|
||||
when = new HashMap<String, MatchPair>();
|
||||
matchPair = new MatchPair(new HashSet<String>(), new HashSet<String>());
|
||||
when.put("consumer.host", matchPair);
|
||||
} else {
|
||||
when = RouteRule.parseRule(route.getMatchRule());
|
||||
matchPair = when.get("consumer.host");
|
||||
}
|
||||
for (String consumerAddress : consumerAddresses) {
|
||||
if (Boolean.valueOf((String) context.get("allow"))) {
|
||||
matchPair.getUnmatches().add(Tool.getIP(consumerAddress));
|
||||
|
||||
} else {
|
||||
matchPair.getMatches().add(Tool.getIP(consumerAddress));
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
RouteRule.contidionToString(sb, when);
|
||||
route.setMatchRule(sb.toString());
|
||||
route.setUsername(operator);
|
||||
if (isFirst) {
|
||||
routeService.createRoute(route);
|
||||
} else {
|
||||
routeService.updateRoute(route);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Set<String> toAddr(String addr) throws IOException {
|
||||
Set<String> consumerAddresses = new HashSet<String>();
|
||||
BufferedReader reader = new BufferedReader(new StringReader(addr));
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (null == line)
|
||||
break;
|
||||
|
||||
String[] split = line.split("[\\s,;]+");
|
||||
for (String s : split) {
|
||||
if (s.length() == 0)
|
||||
continue;
|
||||
if (!IP_PATTERN.matcher(s).matches()) {
|
||||
throw new IllegalStateException("illegal IP: " + s);
|
||||
}
|
||||
if (LOCAL_IP_PATTERN.matcher(s).matches() || ALL_IP_PATTERN.matcher(s).matches()) {
|
||||
throw new IllegalStateException("local IP or any host ip is illegal: " + s);
|
||||
}
|
||||
|
||||
consumerAddresses.add(s);
|
||||
}
|
||||
}
|
||||
return consumerAddresses;
|
||||
}
|
||||
|
||||
private Set<String> toService(String services) throws IOException {
|
||||
Set<String> aimServices = new HashSet<String>();
|
||||
BufferedReader reader = new BufferedReader(new StringReader(services));
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (null == line)
|
||||
break;
|
||||
|
||||
String[] split = line.split("[\\s,;]+");
|
||||
for (String s : split) {
|
||||
if (s.length() == 0)
|
||||
continue;
|
||||
aimServices.add(s);
|
||||
}
|
||||
}
|
||||
return aimServices;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws ParseException
|
||||
*/
|
||||
public boolean delete(Map<String, Object> context) throws ParseException {
|
||||
String accesses = (String) context.get("accesses");
|
||||
String[] temp = accesses.split(" ");
|
||||
Map<String, Set<String>> prepareToDeleate = new HashMap<String, Set<String>>();
|
||||
for (String s : temp) {
|
||||
String service = s.split("=")[0];
|
||||
String address = s.split("=")[1];
|
||||
Set<String> addresses = prepareToDeleate.get(service);
|
||||
if (addresses == null) {
|
||||
prepareToDeleate.put(service, new HashSet<String>());
|
||||
addresses = prepareToDeleate.get(service);
|
||||
}
|
||||
addresses.add(address);
|
||||
}
|
||||
for (Entry<String, Set<String>> entry : prepareToDeleate.entrySet()) {
|
||||
|
||||
String service = entry.getKey();
|
||||
List<Route> routes = routeService.findForceRouteByService(service);
|
||||
if (routes == null || routes.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
for (Route blackwhitelist : routes) {
|
||||
MatchPair pairs = RouteRule.parseRule(blackwhitelist.getMatchRule()).get("consumer.host");
|
||||
Set<String> matches = new HashSet<String>();
|
||||
matches.addAll(pairs.getMatches());
|
||||
Set<String> unmatches = new HashSet<String>();
|
||||
unmatches.addAll(pairs.getUnmatches());
|
||||
for (String pair : pairs.getMatches()) {
|
||||
for (String address : entry.getValue()) {
|
||||
if (pair.equals(address)) {
|
||||
matches.remove(pair);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String pair : pairs.getUnmatches()) {
|
||||
for (String address : entry.getValue()) {
|
||||
if (pair.equals(address)) {
|
||||
unmatches.remove(pair);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matches.size() == 0 && unmatches.size() == 0) {
|
||||
routeService.deleteRoute(blackwhitelist.getId());
|
||||
} else {
|
||||
Map<String, MatchPair> condition = new HashMap<String, MatchPair>();
|
||||
condition.put("consumer.host", new MatchPair(matches, unmatches));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
RouteRule.contidionToString(sb, condition);
|
||||
blackwhitelist.setMatchRule(sb.toString());
|
||||
routeService.updateRoute(blackwhitelist);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void show(Map<String, Object> context) {
|
||||
}
|
||||
|
||||
public void edit(Map<String, Object> context) {
|
||||
}
|
||||
|
||||
public String update(Map<String, Object> context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Providers.
|
||||
* URI: /services/$service/providers
|
||||
*
|
||||
*/
|
||||
public class Addresses extends Restful {
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
private ConsumerService consumerService;
|
||||
|
||||
public void index(Map<String, Object> context) {
|
||||
String application = (String) context.get("application");
|
||||
String service = (String) context.get("service");
|
||||
List<String> providerAddresses = null;
|
||||
List<String> consumerAddresses = null;
|
||||
|
||||
if (application != null && application.length() > 0) {
|
||||
providerAddresses = providerService.findAddressesByApplication(application);
|
||||
consumerAddresses = consumerService.findAddressesByApplication(application);
|
||||
} else if (service != null && service.length() > 0) {
|
||||
providerAddresses = providerService.findAddressesByService(service);
|
||||
consumerAddresses = consumerService.findAddressesByService(service);
|
||||
} else {
|
||||
providerAddresses = providerService.findAddresses();
|
||||
consumerAddresses = consumerService.findAddresses();
|
||||
}
|
||||
|
||||
Set<String> addresses = new TreeSet<String>();
|
||||
if (providerAddresses != null) {
|
||||
addresses.addAll(providerAddresses);
|
||||
}
|
||||
if (consumerAddresses != null) {
|
||||
addresses.addAll(consumerAddresses);
|
||||
}
|
||||
context.put("providerAddresses", providerAddresses);
|
||||
context.put("consumerAddresses", consumerAddresses);
|
||||
context.put("addresses", addresses);
|
||||
|
||||
if (context.get("service") == null
|
||||
&& context.get("application") == null
|
||||
&& context.get("address") == null) {
|
||||
context.put("address", "*");
|
||||
}
|
||||
|
||||
String keyword = (String) context.get("keyword");
|
||||
if (StringUtils.isNotEmpty(keyword)) {
|
||||
if ("*".equals(keyword)) return;
|
||||
|
||||
keyword = keyword.toLowerCase();
|
||||
Set<String> newList = new HashSet<String>();
|
||||
Set<String> newProviders = new HashSet<String>();
|
||||
Set<String> newConsumers = new HashSet<String>();
|
||||
|
||||
for (String o : addresses) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newList.add(o);
|
||||
}
|
||||
}
|
||||
for (String o : providerAddresses) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newProviders.add(o);
|
||||
}
|
||||
}
|
||||
for (String o : consumerAddresses) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newConsumers.add(o);
|
||||
}
|
||||
}
|
||||
context.put("addresses", newList);
|
||||
context.put("providerAddresses", newProviders);
|
||||
context.put("consumerAddresses", newConsumers);
|
||||
}
|
||||
}
|
||||
|
||||
public void search(Map<String, Object> context) {
|
||||
index(context);
|
||||
|
||||
Set<String> newList = new HashSet<String>();
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<String> list = (Set<String>) context.get("addresses");
|
||||
String keyword = (String) context.get("keyword");
|
||||
if (StringUtils.isNotEmpty(keyword)) {
|
||||
keyword = keyword.toLowerCase();
|
||||
for (String o : list) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newList.add(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.put("addresses", newList);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
import com.alibaba.dubbo.registry.common.route.OverrideUtils;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Providers.
|
||||
* URI: /applications
|
||||
*
|
||||
*/
|
||||
public class Applications extends Restful {
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
private ConsumerService consumerService;
|
||||
|
||||
@Autowired
|
||||
private OverrideService overrideService;
|
||||
|
||||
public void index(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
if (context.get("service") != null) {
|
||||
Set<String> applications = new TreeSet<String>();
|
||||
List<String> providerApplications = providerService.findApplicationsByServiceName(service);
|
||||
if (providerApplications != null && providerApplications.size() > 0) {
|
||||
applications.addAll(providerApplications);
|
||||
}
|
||||
List<String> consumerApplications = consumerService.findApplicationsByServiceName(service);
|
||||
if (consumerApplications != null && consumerApplications.size() > 0) {
|
||||
applications.addAll(consumerApplications);
|
||||
}
|
||||
context.put("applications", applications);
|
||||
context.put("providerApplications", providerApplications);
|
||||
context.put("consumerApplications", consumerApplications);
|
||||
if (service != null && service.length() > 0) {
|
||||
List<Override> overrides = overrideService.findByService(service);
|
||||
Map<String, List<Override>> application2Overrides = new HashMap<String, List<Override>>();
|
||||
if (overrides != null && overrides.size() > 0
|
||||
&& applications != null && applications.size() > 0) {
|
||||
for (String a : applications) {
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
List<Override> appOverrides = new ArrayList<Override>();
|
||||
for (Override override : overrides) {
|
||||
if (override.isMatch(service, null, a)) {
|
||||
appOverrides.add(override);
|
||||
}
|
||||
}
|
||||
Collections.sort(appOverrides, OverrideUtils.OVERRIDE_COMPARATOR);
|
||||
application2Overrides.put(a, appOverrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.put("overrides", application2Overrides);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (context.get("service") == null
|
||||
&& context.get("application") == null
|
||||
&& context.get("address") == null) {
|
||||
context.put("application", "*");
|
||||
}
|
||||
Set<String> applications = new TreeSet<String>();
|
||||
List<String> providerApplications = providerService.findApplications();
|
||||
if (providerApplications != null && providerApplications.size() > 0) {
|
||||
applications.addAll(providerApplications);
|
||||
}
|
||||
List<String> consumerApplications = consumerService.findApplications();
|
||||
if (consumerApplications != null && consumerApplications.size() > 0) {
|
||||
applications.addAll(consumerApplications);
|
||||
}
|
||||
|
||||
Set<String> newList = new HashSet<String>();
|
||||
Set<String> newProviders = new HashSet<String>();
|
||||
Set<String> newConsumers = new HashSet<String>();
|
||||
context.put("applications", applications);
|
||||
context.put("providerApplications", providerApplications);
|
||||
context.put("consumerApplications", consumerApplications);
|
||||
|
||||
String keyword = (String) context.get("keyword");
|
||||
if (StringUtils.isNotEmpty(keyword) && !"*".equals(keyword)) {
|
||||
keyword = keyword.toLowerCase();
|
||||
for (String o : applications) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newList.add(o);
|
||||
}
|
||||
}
|
||||
for (String o : providerApplications) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newProviders.add(o);
|
||||
}
|
||||
}
|
||||
for (String o : consumerApplications) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newConsumers.add(o);
|
||||
}
|
||||
}
|
||||
context.put("applications", newList);
|
||||
context.put("providerApplications", newProviders);
|
||||
context.put("consumerApplications", newConsumers);
|
||||
}
|
||||
}
|
||||
|
||||
public void search(Map<String, Object> context) {
|
||||
index(context);
|
||||
|
||||
Set<String> newList = new HashSet<String>();
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<String> apps = (Set<String>) context.get("applications");
|
||||
String keyword = (String) context.get("keyword");
|
||||
if (StringUtils.isNotEmpty(keyword)) {
|
||||
keyword = keyword.toLowerCase();
|
||||
for (String o : apps) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newList.add(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.put("applications", newList);
|
||||
}
|
||||
|
||||
public boolean shield(Map<String, Object> context) throws Exception {
|
||||
return mock(context, "force:return null");
|
||||
}
|
||||
|
||||
public boolean tolerant(Map<String, Object> context) throws Exception {
|
||||
return mock(context, "fail:return null");
|
||||
}
|
||||
|
||||
public boolean recover(Map<String, Object> context) throws Exception {
|
||||
return mock(context, "");
|
||||
}
|
||||
|
||||
private boolean mock(Map<String, Object> context, String mock) throws Exception {
|
||||
String service = (String) context.get("service");
|
||||
String applications = (String) context.get("application");
|
||||
if (service == null || service.length() == 0
|
||||
|| applications == null || applications.length() == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
for (String application : SPACE_SPLIT_PATTERN.split(applications)) {
|
||||
List<Override> overrides = overrideService.findByServiceAndApplication(service, application);
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
for (Override override : overrides) {
|
||||
Map<String, String> map = StringUtils.parseQueryString(override.getParams());
|
||||
if (mock == null || mock.length() == 0) {
|
||||
map.remove("mock");
|
||||
} else {
|
||||
map.put("mock", URL.encode(mock));
|
||||
}
|
||||
if (map.size() > 0) {
|
||||
override.setParams(StringUtils.toQueryString(map));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.updateOverride(override);
|
||||
} else {
|
||||
overrideService.deleteOverride(override.getId());
|
||||
}
|
||||
}
|
||||
} else if (mock != null && mock.length() > 0) {
|
||||
Override override = new Override();
|
||||
override.setService(service);
|
||||
override.setApplication(application);
|
||||
override.setParams("mock=" + URL.encode(mock));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean allshield(Map<String, Object> context) throws Exception {
|
||||
return allmock(context, "force:return null");
|
||||
}
|
||||
|
||||
public boolean alltolerant(Map<String, Object> context) throws Exception {
|
||||
return allmock(context, "fail:return null");
|
||||
}
|
||||
|
||||
public boolean allrecover(Map<String, Object> context) throws Exception {
|
||||
return allmock(context, "");
|
||||
}
|
||||
|
||||
private boolean allmock(Map<String, Object> context, String mock) throws Exception {
|
||||
String service = (String) context.get("service");
|
||||
if (service == null || service.length() == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
List<Override> overrides = overrideService.findByService(service);
|
||||
Override allOverride = null;
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
for (Override override : overrides) {
|
||||
if (override.isDefault()) {
|
||||
allOverride = override;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allOverride != null) {
|
||||
Map<String, String> map = StringUtils.parseQueryString(allOverride.getParams());
|
||||
if (mock == null || mock.length() == 0) {
|
||||
map.remove("mock");
|
||||
} else {
|
||||
map.put("mock", URL.encode(mock));
|
||||
}
|
||||
if (map.size() > 0) {
|
||||
allOverride.setParams(StringUtils.toQueryString(map));
|
||||
allOverride.setEnabled(true);
|
||||
allOverride.setOperator(operator);
|
||||
allOverride.setOperatorAddress(operatorAddress);
|
||||
overrideService.updateOverride(allOverride);
|
||||
} else {
|
||||
overrideService.deleteOverride(allOverride.getId());
|
||||
}
|
||||
} else if (mock != null && mock.length() > 0) {
|
||||
Override override = new Override();
|
||||
override.setService(service);
|
||||
override.setParams("mock=" + URL.encode(mock));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.service.RouteService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Consumer;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.domain.Route;
|
||||
import com.alibaba.dubbo.registry.common.route.OverrideUtils;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteRule;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteRule.MatchPair;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteUtils;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Consumers. URI: /services/$service/consumers
|
||||
*
|
||||
*/
|
||||
public class Consumers extends Restful {
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
private ConsumerService consumerService;
|
||||
|
||||
@Autowired
|
||||
private OverrideService overrideService;
|
||||
|
||||
@Autowired
|
||||
private RouteService routeService;
|
||||
|
||||
public void index(Map<String, Object> context) throws Exception {
|
||||
String service = (String) context.get("service");
|
||||
String application = (String) context.get("application");
|
||||
String address = (String) context.get("address");
|
||||
List<Consumer> consumers;
|
||||
List<Override> overrides;
|
||||
List<Provider> providers = null;
|
||||
List<Route> routes = null;
|
||||
// service
|
||||
if (service != null && service.length() > 0) {
|
||||
consumers = consumerService.findByService(service);
|
||||
overrides = overrideService.findByService(service);
|
||||
providers = providerService.findByService(service);
|
||||
routes = routeService.findByService(service);
|
||||
}
|
||||
// address
|
||||
else if (address != null && address.length() > 0) {
|
||||
consumers = consumerService.findByAddress(address);
|
||||
overrides = overrideService.findByAddress(Tool.getIP(address));
|
||||
}
|
||||
// application
|
||||
else if (application != null && application.length() > 0) {
|
||||
consumers = consumerService.findByApplication(application);
|
||||
overrides = overrideService.findByApplication(application);
|
||||
}
|
||||
// all
|
||||
else {
|
||||
consumers = consumerService.findAll();
|
||||
overrides = overrideService.findAll();
|
||||
}
|
||||
if (consumers != null && consumers.size() > 0) {
|
||||
for (Consumer consumer : consumers) {
|
||||
if (service == null || service.length() == 0) {
|
||||
providers = providerService.findByService(consumer.getService());
|
||||
routes = routeService.findByService(consumer.getService());
|
||||
}
|
||||
List<Route> routed = new ArrayList<Route>();
|
||||
consumer.setProviders(RouteUtils.route(consumer.getService(), consumer.getAddress(), consumer.getParameters(), providers, overrides, routes, null, routed));
|
||||
consumer.setRoutes(routed);
|
||||
OverrideUtils.setConsumerOverrides(consumer, overrides);
|
||||
}
|
||||
}
|
||||
context.put("consumers", consumers);
|
||||
}
|
||||
|
||||
public void show(Long id, Map<String, Object> context) {
|
||||
Consumer consumer = consumerService.findConsumer(id);
|
||||
List<Provider> providers = providerService.findByService(consumer.getService());
|
||||
List<Route> routes = routeService.findByService(consumer.getService());
|
||||
List<Override> overrides = overrideService.findByService(consumer.getService());
|
||||
List<Route> routed = new ArrayList<Route>();
|
||||
consumer.setProviders(RouteUtils.route(consumer.getService(), consumer.getAddress(), consumer.getParameters(), providers, overrides, routes, null, routed));
|
||||
consumer.setRoutes(routed);
|
||||
OverrideUtils.setConsumerOverrides(consumer, overrides);
|
||||
context.put("consumer", consumer);
|
||||
context.put("providers", consumer.getProviders());
|
||||
context.put("routes", consumer.getRoutes());
|
||||
context.put("overrides", consumer.getOverrides());
|
||||
}
|
||||
|
||||
public void edit(Long id, Map<String, Object> context) {
|
||||
show(id, context);
|
||||
}
|
||||
|
||||
public boolean update(Consumer newConsumer, Map<String, Object> context) {
|
||||
Long id = newConsumer.getId();
|
||||
String parameters = newConsumer.getParameters();
|
||||
Consumer consumer = consumerService.findConsumer(id);
|
||||
if (consumer == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
}
|
||||
String service = consumer.getService();
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
Map<String, String> oldMap = StringUtils.parseQueryString(consumer.getParameters());
|
||||
Map<String, String> newMap = StringUtils.parseQueryString(parameters);
|
||||
for (Map.Entry<String, String> entry : oldMap.entrySet()) {
|
||||
if (entry.getValue().equals(newMap.get(entry.getKey()))) {
|
||||
newMap.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
String address = consumer.getAddress();
|
||||
List<Override> overrides = overrideService.findByServiceAndAddress(consumer.getService(), consumer.getAddress());
|
||||
OverrideUtils.setConsumerOverrides(consumer, overrides);
|
||||
Override override = consumer.getOverride();
|
||||
if (override != null) {
|
||||
if (newMap.size() > 0) {
|
||||
override.setParams(StringUtils.toQueryString(newMap));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.updateOverride(override);
|
||||
} else {
|
||||
overrideService.deleteOverride(override.getId());
|
||||
}
|
||||
} else {
|
||||
override = new Override();
|
||||
override.setService(service);
|
||||
override.setAddress(address);
|
||||
override.setParams(StringUtils.toQueryString(newMap));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void routed(Long id, Map<String, Object> context) {
|
||||
show(id, context);
|
||||
}
|
||||
|
||||
public void notified(Long id, Map<String, Object> context) {
|
||||
show(id, context);
|
||||
}
|
||||
|
||||
public void overrided(Long id, Map<String, Object> context) {
|
||||
show(id, context);
|
||||
}
|
||||
|
||||
public boolean shield(Long[] ids, Map<String, Object> context) throws Exception {
|
||||
return mock(ids, context, "force:return null");
|
||||
}
|
||||
|
||||
public boolean tolerant(Long[] ids, Map<String, Object> context) throws Exception {
|
||||
return mock(ids, context, "fail:return null");
|
||||
}
|
||||
|
||||
public boolean recover(Long[] ids, Map<String, Object> context) throws Exception {
|
||||
return mock(ids, context, "");
|
||||
}
|
||||
|
||||
private boolean mock(Long[] ids, Map<String, Object> context, String mock) throws Exception {
|
||||
if (ids == null || ids.length == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
List<Consumer> consumers = new ArrayList<Consumer>();
|
||||
for (Long id : ids) {
|
||||
Consumer c = consumerService.findConsumer(id);
|
||||
if (c != null) {
|
||||
consumers.add(c);
|
||||
if (!super.currentUser.hasServicePrivilege(c.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", c.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Consumer consumer : consumers) {
|
||||
String service = consumer.getService();
|
||||
String address = Tool.getIP(consumer.getAddress());
|
||||
List<Override> overrides = overrideService.findByServiceAndAddress(service, address);
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
for (Override override : overrides) {
|
||||
Map<String, String> map = StringUtils.parseQueryString(override.getParams());
|
||||
if (mock == null || mock.length() == 0) {
|
||||
map.remove("mock");
|
||||
} else {
|
||||
map.put("mock", URL.encode(mock));
|
||||
}
|
||||
if (map.size() > 0) {
|
||||
override.setParams(StringUtils.toQueryString(map));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.updateOverride(override);
|
||||
} else {
|
||||
overrideService.deleteOverride(override.getId());
|
||||
}
|
||||
}
|
||||
} else if (mock != null && mock.length() > 0) {
|
||||
Override override = new Override();
|
||||
override.setService(service);
|
||||
override.setAddress(address);
|
||||
override.setParams("mock=" + URL.encode(mock));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean allshield(Map<String, Object> context) throws Exception {
|
||||
return allmock(context, "force:return null");
|
||||
}
|
||||
|
||||
public boolean alltolerant(Map<String, Object> context) throws Exception {
|
||||
return allmock(context, "fail:return null");
|
||||
}
|
||||
|
||||
public boolean allrecover(Map<String, Object> context) throws Exception {
|
||||
return allmock(context, "");
|
||||
}
|
||||
|
||||
private boolean allmock(Map<String, Object> context, String mock) throws Exception {
|
||||
String service = (String) context.get("service");
|
||||
if (service == null || service.length() == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
List<Override> overrides = overrideService.findByService(service);
|
||||
Override allOverride = null;
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
for (Override override : overrides) {
|
||||
if (override.isDefault()) {
|
||||
allOverride = override;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allOverride != null) {
|
||||
Map<String, String> map = StringUtils.parseQueryString(allOverride.getParams());
|
||||
if (mock == null || mock.length() == 0) {
|
||||
map.remove("mock");
|
||||
} else {
|
||||
map.put("mock", URL.encode(mock));
|
||||
}
|
||||
if (map.size() > 0) {
|
||||
allOverride.setParams(StringUtils.toQueryString(map));
|
||||
allOverride.setEnabled(true);
|
||||
allOverride.setOperator(operator);
|
||||
allOverride.setOperatorAddress(operatorAddress);
|
||||
overrideService.updateOverride(allOverride);
|
||||
} else {
|
||||
overrideService.deleteOverride(allOverride.getId());
|
||||
}
|
||||
} else if (mock != null && mock.length() > 0) {
|
||||
Override override = new Override();
|
||||
override.setService(service);
|
||||
override.setParams("mock=" + URL.encode(mock));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean allow(Long[] ids, Map<String, Object> context) throws Exception {
|
||||
return access(ids, context, true, false);
|
||||
}
|
||||
|
||||
public boolean forbid(Long[] ids, Map<String, Object> context) throws Exception {
|
||||
return access(ids, context, false, false);
|
||||
}
|
||||
|
||||
public boolean onlyallow(Long[] ids, Map<String, Object> context) throws Exception {
|
||||
return access(ids, context, true, true);
|
||||
}
|
||||
|
||||
public boolean onlyforbid(Long[] ids, Map<String, Object> context) throws Exception {
|
||||
return access(ids, context, false, true);
|
||||
}
|
||||
|
||||
private boolean access(Long[] ids, Map<String, Object> context, boolean allow, boolean only) throws Exception {
|
||||
if (ids == null || ids.length == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
List<Consumer> consumers = new ArrayList<Consumer>();
|
||||
for (Long id : ids) {
|
||||
Consumer c = consumerService.findConsumer(id);
|
||||
if (c != null) {
|
||||
consumers.add(c);
|
||||
if (!super.currentUser.hasServicePrivilege(c.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", c.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, Set<String>> serviceAddresses = new HashMap<String, Set<String>>();
|
||||
for (Consumer consumer : consumers) {
|
||||
String service = consumer.getService();
|
||||
String address = Tool.getIP(consumer.getAddress());
|
||||
Set<String> addresses = serviceAddresses.get(service);
|
||||
if (addresses == null) {
|
||||
addresses = new HashSet<String>();
|
||||
serviceAddresses.put(service, addresses);
|
||||
}
|
||||
addresses.add(address);
|
||||
}
|
||||
for (Map.Entry<String, Set<String>> entry : serviceAddresses.entrySet()) {
|
||||
String service = entry.getKey();
|
||||
boolean isFirst = false;
|
||||
List<Route> routes = routeService.findForceRouteByService(service);
|
||||
Route route = null;
|
||||
if (routes == null || routes.size() == 0) {
|
||||
isFirst = true;
|
||||
route = new Route();
|
||||
route.setService(service);
|
||||
route.setForce(true);
|
||||
route.setName(service + " blackwhitelist");
|
||||
route.setFilterRule("false");
|
||||
route.setEnabled(true);
|
||||
} else {
|
||||
route = routes.get(0);
|
||||
}
|
||||
Map<String, MatchPair> when = null;
|
||||
MatchPair matchPair = null;
|
||||
if (isFirst) {
|
||||
when = new HashMap<String, MatchPair>();
|
||||
matchPair = new MatchPair(new HashSet<String>(), new HashSet<String>());
|
||||
when.put("consumer.host", matchPair);
|
||||
} else {
|
||||
when = RouteRule.parseRule(route.getMatchRule());
|
||||
matchPair = when.get("consumer.host");
|
||||
}
|
||||
if (only) {
|
||||
matchPair.getUnmatches().clear();
|
||||
matchPair.getMatches().clear();
|
||||
if (allow) {
|
||||
matchPair.getUnmatches().addAll(entry.getValue());
|
||||
} else {
|
||||
matchPair.getMatches().addAll(entry.getValue());
|
||||
}
|
||||
} else {
|
||||
for (String consumerAddress : entry.getValue()) {
|
||||
if (matchPair.getUnmatches().size() > 0) { // whitelist take effect
|
||||
matchPair.getMatches().remove(consumerAddress); // remove data in blacklist
|
||||
if (allow) { // if allowed
|
||||
matchPair.getUnmatches().add(consumerAddress); // add to whitelist
|
||||
} else { // if not allowed
|
||||
matchPair.getUnmatches().remove(consumerAddress); // remove from whitelist
|
||||
}
|
||||
} else { // blacklist take effect
|
||||
if (allow) { // if allowed
|
||||
matchPair.getMatches().remove(consumerAddress); // remove from blacklist
|
||||
} else { // if not allowed
|
||||
matchPair.getMatches().add(consumerAddress); // add to blacklist
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
RouteRule.contidionToString(sb, when);
|
||||
route.setMatchRule(sb.toString());
|
||||
route.setUsername(operator);
|
||||
if (matchPair.getMatches().size() > 0 || matchPair.getUnmatches().size() > 0) {
|
||||
if (isFirst) {
|
||||
routeService.createRoute(route);
|
||||
} else {
|
||||
routeService.updateRoute(route);
|
||||
}
|
||||
} else if (!isFirst) {
|
||||
routeService.deleteRoute(route.getId());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.utils.CollectionUtils;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.LoadBalance;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.util.OverrideUtils;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Providers.
|
||||
* URI: /services/$service/loadbalances
|
||||
*
|
||||
*/
|
||||
public class Loadbalances extends Restful {
|
||||
|
||||
@Autowired
|
||||
private OverrideService overrideService;
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
public void index(Map<String, Object> context) {
|
||||
final String service = StringUtils.trimToNull((String) context.get("service"));
|
||||
|
||||
List<LoadBalance> loadbalances;
|
||||
if (service != null && service.length() > 0) {
|
||||
loadbalances = OverrideUtils.overridesToLoadBalances(overrideService.findByService(service));
|
||||
|
||||
loadbalances = OverrideUtils.overridesToLoadBalances(overrideService.findByService(service));
|
||||
} else {
|
||||
loadbalances = OverrideUtils.overridesToLoadBalances(overrideService.findAll());
|
||||
}
|
||||
context.put("loadbalances", loadbalances);
|
||||
}
|
||||
|
||||
public void show(Long id, Map<String, Object> context) {
|
||||
LoadBalance loadbalance = OverrideUtils.overrideToLoadBalance(overrideService.findById(id));
|
||||
context.put("loadbalance", loadbalance);
|
||||
}
|
||||
|
||||
public void add(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
if (service != null && service.length() > 0 && !service.contains("*")) {
|
||||
List<Provider> providerList = providerService.findByService(service);
|
||||
List<String> addressList = new ArrayList<String>();
|
||||
for (Provider provider : providerList) {
|
||||
addressList.add(provider.getUrl().split("://")[1].split("/")[0]);
|
||||
}
|
||||
context.put("addressList", addressList);
|
||||
context.put("service", service);
|
||||
context.put("methods", CollectionUtils.sort(providerService.findMethodsByService(service)));
|
||||
} else {
|
||||
List<String> serviceList = Tool.sortSimpleName(providerService.findServices());
|
||||
context.put("serviceList", serviceList);
|
||||
}
|
||||
if (context.get("input") != null) context.put("input", context.get("input"));
|
||||
}
|
||||
|
||||
public void edit(Long id, Map<String, Object> context) {
|
||||
add(context);
|
||||
show(id, context);
|
||||
}
|
||||
|
||||
public boolean create(LoadBalance loadBalance, Map<String, Object> context) {
|
||||
if (!super.currentUser.hasServicePrivilege(loadBalance.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", loadBalance.getService()));
|
||||
return false;
|
||||
}
|
||||
|
||||
loadBalance.setUsername((String) context.get("operator"));
|
||||
overrideService.saveOverride(OverrideUtils.loadBalanceToOverride(loadBalance));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean update(LoadBalance loadBalance, Map<String, Object> context) {
|
||||
if (!super.currentUser.hasServicePrivilege(loadBalance.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", loadBalance.getService()));
|
||||
return false;
|
||||
}
|
||||
overrideService.updateOverride(OverrideUtils.loadBalanceToOverride(loadBalance));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public boolean delete(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
LoadBalance lb = OverrideUtils.overrideToLoadBalance(overrideService.findById(id));
|
||||
if (!super.currentUser.hasServicePrivilege(lb.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", lb.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Long id : ids) {
|
||||
overrideService.deleteOverride(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.citrus.turbine.Context;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* TODO Comment of NoServicePrivilege
|
||||
*
|
||||
*/
|
||||
public class NoServicePrivilege {
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
public void execute(Context context) {
|
||||
context.put("returnUrl", request.getParameter("returnUrl"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.CollectionUtils;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Overrides extends Restful {
|
||||
static final Pattern AND = Pattern.compile("\\&");
|
||||
static final Pattern EQUAL = Pattern.compile("([^=\\s]*)\\s*=\\s*(\\S*)");
|
||||
static final String DEFAULT_MOCK_JSON_KEY = "mock";
|
||||
static final String MOCK_JSON_KEY_POSTFIX = ".mock";
|
||||
static final String FORM_OVERRIDE_KEY = "overrideKey";
|
||||
static final String FORM_OVERRIDE_VALUE = "overrideValue";
|
||||
static final String FORM_DEFAULT_MOCK_METHOD_FORCE = "mockDefaultMethodForce";
|
||||
static final String FORM_DEFAULT_MOCK_METHOD_JSON = "mockDefaultMethodJson";
|
||||
static final String FORM_ORIGINAL_METHOD_FORCE_PREFIX = "mockMethodForce.";
|
||||
static final String FORM_ORIGINAL_METHOD_PREFIX = "mockMethod.";
|
||||
static final String FORM_DYNAMIC_METHOD_NAME_PREFIX = "mockMethodName";
|
||||
static final String FORM_DYNAMIC_METHOD_FORCE_PREFIX = "mockMethodForce";
|
||||
static final String FORM_DYNAMIC_METHOD_JSON_PREFIX = "mockMethodJson";
|
||||
@Autowired
|
||||
private OverrideService overrideService;
|
||||
|
||||
// FORM KEY
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
@Autowired
|
||||
private ConsumerService consumerService;
|
||||
|
||||
static Map<String, String> parseQueryString(String query) {
|
||||
HashMap<String, String> ret = new HashMap<String, String>();
|
||||
if (query == null || (query = query.trim()).length() == 0) return ret;
|
||||
|
||||
String[] kvs = AND.split(query);
|
||||
for (String kv : kvs) {
|
||||
Matcher matcher = EQUAL.matcher(kv);
|
||||
if (!matcher.matches()) continue;
|
||||
String key = matcher.group(1);
|
||||
String value = matcher.group(2);
|
||||
ret.put(key, value);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void index(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
String application = (String) context.get("application");
|
||||
String address = (String) context.get("address");
|
||||
List<Override> overrides;
|
||||
if (StringUtils.isNotEmpty(service)) {
|
||||
overrides = overrideService.findByService(service);
|
||||
} else if (StringUtils.isNotEmpty(application)) {
|
||||
overrides = overrideService.findByApplication(application);
|
||||
} else if (StringUtils.isNotEmpty(address)) {
|
||||
overrides = overrideService.findByAddress(address);
|
||||
} else {
|
||||
overrides = overrideService.findAll();
|
||||
}
|
||||
context.put("overrides", overrides);
|
||||
}
|
||||
|
||||
public void show(Long id, Map<String, Object> context) {
|
||||
Override override = overrideService.findById(id);
|
||||
|
||||
Map<String, String> parameters = parseQueryString(override.getParams());
|
||||
|
||||
if (parameters.get(DEFAULT_MOCK_JSON_KEY) != null) {
|
||||
String mock = URL.decode(parameters.get(DEFAULT_MOCK_JSON_KEY));
|
||||
String[] tokens = parseMock(mock);
|
||||
context.put(FORM_DEFAULT_MOCK_METHOD_FORCE, tokens[0]);
|
||||
context.put(FORM_DEFAULT_MOCK_METHOD_JSON, tokens[1]);
|
||||
parameters.remove(DEFAULT_MOCK_JSON_KEY);
|
||||
}
|
||||
|
||||
Map<String, String> method2Force = new LinkedHashMap<String, String>();
|
||||
Map<String, String> method2Json = new LinkedHashMap<String, String>();
|
||||
|
||||
for (Iterator<Map.Entry<String, String>> iterator = parameters.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<String, String> e = iterator.next();
|
||||
String key = e.getKey();
|
||||
|
||||
if (key.endsWith(MOCK_JSON_KEY_POSTFIX)) {
|
||||
String m = key.substring(0, key.length() - MOCK_JSON_KEY_POSTFIX.length());
|
||||
parseMock(m, e.getValue(), method2Force, method2Json);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
context.put("methodForces", method2Force);
|
||||
context.put("methodJsons", method2Json);
|
||||
context.put("parameters", parameters);
|
||||
context.put("override", override);
|
||||
}
|
||||
|
||||
public void add(Map<String, Object> context) {
|
||||
List<String> serviceList = new ArrayList<String>();
|
||||
List<String> applicationList = new ArrayList<String>();
|
||||
String service = (String) context.get("service");
|
||||
String application = (String) context.get("application");
|
||||
if (StringUtils.isNotEmpty(application)) {
|
||||
serviceList.addAll(providerService.findServicesByApplication(application));
|
||||
serviceList.addAll(consumerService.findServicesByApplication(application));
|
||||
context.put("serviceList", serviceList);
|
||||
} else if (StringUtils.isNotEmpty(service)) {
|
||||
applicationList.addAll(providerService.findApplicationsByServiceName(service));
|
||||
applicationList.addAll(consumerService.findApplicationsByServiceName(service));
|
||||
context.put("applicationList", applicationList);
|
||||
} else {
|
||||
serviceList.addAll(providerService.findServices());
|
||||
serviceList.addAll(consumerService.findServices());
|
||||
providerService.findServicesByApplication(application);
|
||||
consumerService.findServicesByApplication(application);
|
||||
}
|
||||
context.put("serviceList", serviceList);
|
||||
|
||||
if (StringUtils.isNotEmpty(service) && !service.contains("*")) {
|
||||
context.put("methods", CollectionUtils.sort(new ArrayList<String>(providerService.findMethodsByService(service))));
|
||||
}
|
||||
}
|
||||
|
||||
public void edit(Long id, Map<String, Object> context) {
|
||||
Override override = overrideService.findById(id);
|
||||
|
||||
Map<String, String> parameters = parseQueryString(override.getParams());
|
||||
|
||||
if (parameters.get(DEFAULT_MOCK_JSON_KEY) != null) {
|
||||
String mock = URL.decode(parameters.get(DEFAULT_MOCK_JSON_KEY));
|
||||
String[] tokens = parseMock(mock);
|
||||
context.put(FORM_DEFAULT_MOCK_METHOD_FORCE, tokens[0]);
|
||||
context.put(FORM_DEFAULT_MOCK_METHOD_JSON, tokens[1]);
|
||||
parameters.remove(DEFAULT_MOCK_JSON_KEY);
|
||||
}
|
||||
|
||||
Map<String, String> method2Force = new LinkedHashMap<String, String>();
|
||||
Map<String, String> method2Json = new LinkedHashMap<String, String>();
|
||||
|
||||
List<String> methods = CollectionUtils.sort(new ArrayList<String>(providerService.findMethodsByService(override.getService())));
|
||||
if (methods != null && methods.isEmpty()) {
|
||||
for (String m : methods) {
|
||||
parseMock(m, parameters.get(m + MOCK_JSON_KEY_POSTFIX), method2Force, method2Json);
|
||||
parameters.remove(m + MOCK_JSON_KEY_POSTFIX);
|
||||
}
|
||||
}
|
||||
for (Iterator<Map.Entry<String, String>> iterator = parameters.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<String, String> e = iterator.next();
|
||||
String key = e.getKey();
|
||||
|
||||
if (key.endsWith(MOCK_JSON_KEY_POSTFIX)) {
|
||||
String m = key.substring(0, key.length() - MOCK_JSON_KEY_POSTFIX.length());
|
||||
parseMock(m, e.getValue(), method2Force, method2Json);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
context.put("methods", methods);
|
||||
context.put("methodForces", method2Force);
|
||||
context.put("methodJsons", method2Json);
|
||||
context.put("parameters", parameters);
|
||||
context.put("override", override);
|
||||
}
|
||||
|
||||
private void parseMock(String m, String mock, Map<String, String> method2Force, Map<String, String> method2Json) {
|
||||
String[] tokens = parseMock(mock);
|
||||
method2Force.put(m, tokens[0]);
|
||||
method2Json.put(m, tokens[1]);
|
||||
}
|
||||
|
||||
private String[] parseMock(String mock) {
|
||||
mock = URL.decode(mock);
|
||||
String force;
|
||||
if (mock.startsWith("force:")) {
|
||||
force = "force";
|
||||
mock = mock.substring("force:".length());
|
||||
} else if (mock.startsWith("fail:")) {
|
||||
force = "fail";
|
||||
mock = mock.substring("fail:".length());
|
||||
} else {
|
||||
force = "fail";
|
||||
}
|
||||
String[] tokens = new String[2];
|
||||
tokens[0] = force;
|
||||
tokens[1] = mock;
|
||||
return tokens;
|
||||
}
|
||||
|
||||
boolean catchParams(Override override, Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
if (service == null || service.trim().length() == 0) {
|
||||
context.put("message", getMessage("service is blank!"));
|
||||
return false;
|
||||
}
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
|
||||
String defaultMockMethodForce = (String) context.get(FORM_DEFAULT_MOCK_METHOD_FORCE);
|
||||
String defaultMockMethodJson = (String) context.get(FORM_DEFAULT_MOCK_METHOD_JSON);
|
||||
|
||||
Map<String, String> override2Value = new HashMap<String, String>();
|
||||
Map<String, String> method2Json = new HashMap<String, String>();
|
||||
|
||||
for (Map.Entry<String, Object> param : context.entrySet()) {
|
||||
String key = param.getKey().trim();
|
||||
if (!(param.getValue() instanceof String)) continue;
|
||||
|
||||
String value = (String) param.getValue();
|
||||
|
||||
if (key.startsWith(FORM_OVERRIDE_KEY) && value != null && value.trim().length() > 0) {
|
||||
String index = key.substring(FORM_OVERRIDE_KEY.length());
|
||||
String overrideValue = (String) context.get(FORM_OVERRIDE_VALUE + index);
|
||||
if (overrideValue != null && overrideValue.trim().length() > 0) {
|
||||
override2Value.put(value.trim(), overrideValue.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (key.startsWith(FORM_ORIGINAL_METHOD_PREFIX) && value != null && value.trim().length() > 0) {
|
||||
String method = key.substring(FORM_ORIGINAL_METHOD_PREFIX.length());
|
||||
String force = (String) context.get(FORM_ORIGINAL_METHOD_FORCE_PREFIX + method);
|
||||
method2Json.put(method, force + ":" + value.trim());
|
||||
}
|
||||
|
||||
if (key.startsWith(FORM_DYNAMIC_METHOD_NAME_PREFIX) && value != null && value.trim().length() > 0) {
|
||||
String index = key.substring(FORM_DYNAMIC_METHOD_NAME_PREFIX.length());
|
||||
String force = (String) context.get(FORM_DYNAMIC_METHOD_FORCE_PREFIX + index);
|
||||
String json = (String) context.get(FORM_DYNAMIC_METHOD_JSON_PREFIX + index);
|
||||
|
||||
if (json != null && json.trim().length() > 0) {
|
||||
method2Json.put(value.trim(), force + ":" + json.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder paramters = new StringBuilder();
|
||||
boolean isFirst = true;
|
||||
if (defaultMockMethodJson != null && defaultMockMethodJson.trim().length() > 0) {
|
||||
paramters.append("mock=").append(URL.encode(defaultMockMethodForce + ":" + defaultMockMethodJson.trim()));
|
||||
isFirst = false;
|
||||
}
|
||||
for (Map.Entry<String, String> e : method2Json.entrySet()) {
|
||||
if (isFirst) isFirst = false;
|
||||
else paramters.append("&");
|
||||
|
||||
paramters.append(e.getKey()).append(MOCK_JSON_KEY_POSTFIX).append("=").append(URL.encode(e.getValue()));
|
||||
}
|
||||
for (Map.Entry<String, String> e : override2Value.entrySet()) {
|
||||
if (isFirst) isFirst = false;
|
||||
else paramters.append("&");
|
||||
|
||||
paramters.append(e.getKey()).append("=").append(URL.encode(e.getValue()));
|
||||
}
|
||||
|
||||
String p = paramters.toString();
|
||||
if (p.trim().length() == 0) {
|
||||
context.put("message", getMessage("Please enter Parameters!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
override.setParams(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean create(Override override, Map<String, Object> context) {
|
||||
if (!catchParams(override, context)) return false;
|
||||
|
||||
overrideService.saveOverride(override);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean update(Override override, Map<String, Object> context) {
|
||||
Override o = overrideService.findById(override.getId());
|
||||
override.setService(o.getService());
|
||||
override.setAddress(o.getAddress());
|
||||
override.setApplication(o.getApplication());
|
||||
|
||||
if (!catchParams(override, context)) return false;
|
||||
|
||||
overrideService.updateOverride(override);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean delete(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
overrideService.deleteOverride(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean enable(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
Override override = overrideService.findById(id);
|
||||
if (override == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
} else {
|
||||
if (!super.currentUser.hasServicePrivilege(override.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", override.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Long id : ids) {
|
||||
overrideService.enableOverride(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean disable(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
Override override = overrideService.findById(id);
|
||||
if (override == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
} else {
|
||||
if (!super.currentUser.hasServicePrivilege(override.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", override.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Long id : ids) {
|
||||
overrideService.disableOverride(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.governance.service.OwnerService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Owner;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Providers. URI: /services/$service/owners
|
||||
*
|
||||
*/
|
||||
public class Owners extends Restful {
|
||||
|
||||
@Autowired
|
||||
private OwnerService ownerService;
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
public void index(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
List<Owner> owners;
|
||||
if (service != null && service.length() > 0) {
|
||||
owners = ownerService.findByService(service);
|
||||
} else {
|
||||
owners = ownerService.findAll();
|
||||
}
|
||||
context.put("owners", owners);
|
||||
}
|
||||
|
||||
public void add(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
if (service == null || service.length() == 0) {
|
||||
List<String> serviceList = Tool.sortSimpleName(new ArrayList<String>(providerService.findServices()));
|
||||
context.put("serviceList", serviceList);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean create(Owner owner, Map<String, Object> context) {
|
||||
String service = owner.getService();
|
||||
String username = owner.getUsername();
|
||||
if (service == null || service.length() == 0
|
||||
|| username == null || username.length() == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
ownerService.saveOwner(owner);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean delete(Long[] ids, Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
String username = (String) context.get("username");
|
||||
Owner owner = new Owner();
|
||||
owner.setService(service);
|
||||
owner.setUsername(username);
|
||||
if (service == null || service.length() == 0
|
||||
|| username == null || username.length() == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
ownerService.deleteOwner(owner);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.route.OverrideUtils;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>Providers.</p>
|
||||
* URI: <br>
|
||||
* GET /providers, show all providers<br>
|
||||
* GET /providers/add, show web form for add a static provider<br>
|
||||
* POST /provider/create, create a static provider, save form<br>
|
||||
* GET /providers/$id, show provider details<br>
|
||||
* GET /providers/$id/edit, web form for edit provider<br>
|
||||
* POST /providers/$id, update provider, save form<br>
|
||||
* GET /providers/$id/delete, delete a provider<br>
|
||||
* GET /providers/$id/tostatic, transfer to static<br>
|
||||
* GET /providers/$id/todynamic, transfer to dynamic<br>
|
||||
* GET /providers/$id/enable, enable a provider<br>
|
||||
* GET /providers/$id/disable, disable a provider<br>
|
||||
* GET /providers/$id/reconnect, reconnect<br>
|
||||
* GET /providers/$id/recover, recover<br>
|
||||
* <br>
|
||||
* GET /services/$service/providers, show all provider of a specific service<br>
|
||||
* GET /services/$service/providers/add, show web form for add a static provider<br>
|
||||
* POST /services/$service/providers, save a static provider<br>
|
||||
* GET /services/$service/providers/$id, show provider details<br>
|
||||
* GET /services/$service/providers/$id/edit, show web form for edit provider<br>
|
||||
* POST /services/$service/providers/$id, save changes of provider<br>
|
||||
* GET /services/$service/providers/$id/delete, delete provider<br>
|
||||
* GET /services/$service/providers/$id/tostatic, transfer to static<br>
|
||||
* GET /services/$service/providers/$id/todynamic, transfer to dynamic<br>
|
||||
* GET /services/$service/providers/$id/enable, enable<br>
|
||||
* GET /services/$service/providers/$id/disable, diable<br>
|
||||
* GET /services/$service/providers/$id/reconnect, reconnect<br>
|
||||
* GET /services/$service/providers/$id/recover, recover<br>
|
||||
*
|
||||
*/
|
||||
public class Providers extends Restful {
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
private OverrideService overrideService;
|
||||
|
||||
@Autowired
|
||||
private HttpServletResponse response;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
public void index(Provider provider, Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
String application = (String) context.get("application");
|
||||
String address = (String) context.get("address");
|
||||
|
||||
String value = "";
|
||||
String separators = "....";
|
||||
|
||||
List<Provider> providers = null;
|
||||
|
||||
// service
|
||||
if (service != null && service.length() > 0) {
|
||||
providers = providerService.findByService(service);
|
||||
|
||||
value = service + separators + request.getRequestURI();
|
||||
}
|
||||
// address
|
||||
else if (address != null && address.length() > 0) {
|
||||
providers = providerService.findByAddress(address);
|
||||
|
||||
value = address + separators + request.getRequestURI();
|
||||
}
|
||||
// application
|
||||
else if (application != null && application.length() > 0) {
|
||||
providers = providerService.findByApplication(application);
|
||||
|
||||
value = application + separators + request.getRequestURI();
|
||||
}
|
||||
// all
|
||||
else {
|
||||
providers = providerService.findAll();
|
||||
}
|
||||
|
||||
context.put("providers", providers);
|
||||
context.put("serviceAppMap", getServiceAppMap(providers));
|
||||
|
||||
// record search history to cookies
|
||||
setSearchHistroy(context, value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Calculate the application list corresponding to each service, to facilitate the "repeat" prompt on service page
|
||||
* @param providers app services
|
||||
*/
|
||||
private Map<String, Set<String>> getServiceAppMap(List<Provider> providers) {
|
||||
Map<String, Set<String>> serviceAppMap = new HashMap<String, Set<String>>();
|
||||
if (providers != null && providers.size() > 0) {
|
||||
for (Provider provider : providers) {
|
||||
Set<String> appSet;
|
||||
String service = provider.getService();
|
||||
if (serviceAppMap.get(service) == null) {
|
||||
appSet = new HashSet<String>();
|
||||
} else {
|
||||
appSet = serviceAppMap.get(service);
|
||||
}
|
||||
appSet.add(provider.getApplication());
|
||||
serviceAppMap.put(service, appSet);
|
||||
}
|
||||
}
|
||||
return serviceAppMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record search history to cookies, steps:
|
||||
* Check whether the added record exists in the cookie, and if so, update the list order; if it does not exist, insert it to the front
|
||||
*
|
||||
* @param context
|
||||
* @param value
|
||||
*/
|
||||
private void setSearchHistroy(Map<String, Object> context, String value) {
|
||||
// Analyze existing cookies
|
||||
String separatorsB = "\\.\\.\\.\\.\\.\\.";
|
||||
String newCookiev = value;
|
||||
Cookie[] cookies = request.getCookies();
|
||||
for (Cookie c : cookies) {
|
||||
if (c.getName().equals("HISTORY")) {
|
||||
String cookiev = c.getValue();
|
||||
String[] values = cookiev.split(separatorsB);
|
||||
int count = 1;
|
||||
for (String v : values) {
|
||||
if (count <= 10) {
|
||||
if (!value.equals(v)) {
|
||||
newCookiev = newCookiev + separatorsB + v;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Cookie _cookie = new Cookie("HISTORY", newCookiev);
|
||||
_cookie.setMaxAge(60 * 60 * 24 * 7); // Set the cookie's lifetime to 30 minutes
|
||||
_cookie.setPath("/");
|
||||
response.addCookie(_cookie); // Write to client hard disk
|
||||
}
|
||||
|
||||
public void show(Long id, Map<String, Object> context) {
|
||||
Provider provider = providerService.findProvider(id);
|
||||
if (provider != null && provider.isDynamic()) {
|
||||
List<Override> overrides = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress());
|
||||
OverrideUtils.setProviderOverrides(provider, overrides);
|
||||
}
|
||||
context.put("provider", provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load new service page, get all the service name
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void add(Long id, Map<String, Object> context) {
|
||||
if (context.get("service") == null) {
|
||||
List<String> serviceList = Tool.sortSimpleName(new ArrayList<String>(providerService.findServices()));
|
||||
context.put("serviceList", serviceList);
|
||||
}
|
||||
if (id != null) {
|
||||
Provider p = providerService.findProvider(id);
|
||||
if (p != null) {
|
||||
context.put("provider", p);
|
||||
String parameters = p.getParameters();
|
||||
if (parameters != null && parameters.length() > 0) {
|
||||
Map<String, String> map = StringUtils.parseQueryString(parameters);
|
||||
map.put("timestamp", String.valueOf(System.currentTimeMillis()));
|
||||
map.remove("pid");
|
||||
p.setParameters(StringUtils.toQueryString(map));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void edit(Long id, Map<String, Object> context) {
|
||||
show(id, context);
|
||||
}
|
||||
|
||||
public boolean create(Provider provider, Map<String, Object> context) {
|
||||
String service = provider.getService();
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
if (provider.getParameters() == null) {
|
||||
String url = provider.getUrl();
|
||||
if (url != null) {
|
||||
int i = url.indexOf('?');
|
||||
if (i > 0) {
|
||||
provider.setUrl(url.substring(0, i));
|
||||
provider.setParameters(url.substring(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
provider.setDynamic(false); // Provider add through web page must be static
|
||||
providerService.create(provider);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean update(Provider newProvider, Map<String, Object> context) {
|
||||
Long id = newProvider.getId();
|
||||
String parameters = newProvider.getParameters();
|
||||
Provider provider = providerService.findProvider(id);
|
||||
if (provider == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
}
|
||||
String service = provider.getService();
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
Map<String, String> oldMap = StringUtils.parseQueryString(provider.getParameters());
|
||||
Map<String, String> newMap = StringUtils.parseQueryString(parameters);
|
||||
for (Map.Entry<String, String> entry : oldMap.entrySet()) {
|
||||
if (entry.getValue().equals(newMap.get(entry.getKey()))) {
|
||||
newMap.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
if (provider.isDynamic()) {
|
||||
String address = provider.getAddress();
|
||||
List<Override> overrides = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress());
|
||||
OverrideUtils.setProviderOverrides(provider, overrides);
|
||||
Override override = provider.getOverride();
|
||||
if (override != null) {
|
||||
if (newMap.size() > 0) {
|
||||
override.setParams(StringUtils.toQueryString(newMap));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.updateOverride(override);
|
||||
} else {
|
||||
overrideService.deleteOverride(override.getId());
|
||||
}
|
||||
} else {
|
||||
override = new Override();
|
||||
override.setService(service);
|
||||
override.setAddress(address);
|
||||
override.setParams(StringUtils.toQueryString(newMap));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
} else {
|
||||
provider.setParameters(parameters);
|
||||
providerService.updateProvider(provider);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean delete(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
Provider provider = providerService.findProvider(id);
|
||||
if (provider == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
} else if (provider.isDynamic()) {
|
||||
context.put("message", getMessage("CanNotDeleteDynamicData", id));
|
||||
return false;
|
||||
} else if (!super.currentUser.hasServicePrivilege(provider.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", provider.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
providerService.deleteStaticProvider(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean enable(Long[] ids, Map<String, Object> context) {
|
||||
Map<Long, Provider> id2Provider = new HashMap<Long, Provider>();
|
||||
for (Long id : ids) {
|
||||
Provider provider = providerService.findProvider(id);
|
||||
if (provider == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
} else if (!super.currentUser.hasServicePrivilege(provider.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", provider.getService()));
|
||||
return false;
|
||||
}
|
||||
id2Provider.put(id, provider);
|
||||
}
|
||||
for (Long id : ids) {
|
||||
providerService.enableProvider(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean disable(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
Provider provider = providerService.findProvider(id);
|
||||
if (provider == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
} else if (!super.currentUser.hasServicePrivilege(provider.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", provider.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
providerService.disableProvider(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean doubling(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
Provider provider = providerService.findProvider(id);
|
||||
if (provider == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
} else if (!super.currentUser.hasServicePrivilege(provider.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", provider.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
providerService.doublingProvider(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean halving(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
Provider provider = providerService.findProvider(id);
|
||||
if (provider == null) {
|
||||
context.put("message", getMessage("NoSuchOperationData", id));
|
||||
return false;
|
||||
} else if (!super.currentUser.hasServicePrivilege(provider.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", provider.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
providerService.halvingProvider(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,523 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.utils.CollectionUtils;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.service.OwnerService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.service.RouteService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Consumer;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.domain.Route;
|
||||
import com.alibaba.dubbo.registry.common.route.ParseUtils;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteRule;
|
||||
import com.alibaba.dubbo.registry.common.route.RouteUtils;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Providers.
|
||||
* URI: /services/$service/routes
|
||||
*
|
||||
*/
|
||||
public class Routes extends Restful {
|
||||
|
||||
private static final int MAX_RULE_LENGTH = 1000;
|
||||
static String[][] when_names = {
|
||||
{"method", "method", "unmethod"},
|
||||
{"consumer.application", "consumerApplication", "unconsumerApplication"},
|
||||
{"consumer.cluster", "consumerCluster", "unconsumerCluster"},
|
||||
{"consumer.host", "consumerHost", "unconsumerHost"},
|
||||
{"consumer.version", "consumerVersion", "unconsumerVersion"},
|
||||
{"consumer.group", "consumerGroup", "unconsumerGroup"},
|
||||
};
|
||||
static String[][] then_names = {
|
||||
{"provider.application", "providerApplication", "unproviderApplication"},
|
||||
{"provider.cluster", "providerCluster", "unproviderCluster"}, // Must check if Cluster exists
|
||||
{"provider.host", "providerHost", "unproviderHost"},
|
||||
{"provider.protocol", "providerProtocol", "unproviderProtocol"},
|
||||
{"provider.port", "providerPort", "unproviderPort"},
|
||||
{"provider.version", "providerVersion", "unproviderVersion"},
|
||||
{"provider.group", "providerGroup", "unproviderGroup"}
|
||||
};
|
||||
@Autowired
|
||||
private RouteService routeService;
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
@Autowired
|
||||
private ConsumerService consumerService;
|
||||
|
||||
static void checkService(String service) {
|
||||
if (service.contains(",")) throw new IllegalStateException("service(" + service + ") contain illegale ','");
|
||||
|
||||
String interfaceName = service;
|
||||
int gi = interfaceName.indexOf("/");
|
||||
if (gi != -1) interfaceName = interfaceName.substring(gi + 1);
|
||||
int vi = interfaceName.indexOf(':');
|
||||
if (vi != -1) interfaceName = interfaceName.substring(0, vi);
|
||||
|
||||
if (interfaceName.indexOf('*') != -1 && interfaceName.indexOf('*') != interfaceName.length() - 1) {
|
||||
throw new IllegalStateException("service(" + service + ") only allow 1 *, and must be last char!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add owners related with service
|
||||
*
|
||||
* @param usernames the usernames to add
|
||||
* @param serviceName no wildcards
|
||||
*/
|
||||
public static void addOwnersOfService(Set<String> usernames, String serviceName,
|
||||
OwnerService ownerDAO) {
|
||||
List<String> serviceNamePatterns = ownerDAO.findAllServiceNames();
|
||||
for (String p : serviceNamePatterns) {
|
||||
if (ParseUtils.isMatchGlobPattern(p, serviceName)) {
|
||||
List<String> list = ownerDAO.findUsernamesByServiceName(p);
|
||||
usernames.addAll(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add owners related with service pattern
|
||||
*
|
||||
* @param usernames the usernames to add
|
||||
* @param serviceNamePattern service pattern, Glob
|
||||
*/
|
||||
public static void addOwnersOfServicePattern(Set<String> usernames, String serviceNamePattern,
|
||||
OwnerService ownerDAO) {
|
||||
List<String> serviceNamePatterns = ownerDAO.findAllServiceNames();
|
||||
for (String p : serviceNamePatterns) {
|
||||
if (ParseUtils.hasIntersection(p, serviceNamePattern)) {
|
||||
List<String> list = ownerDAO.findUsernamesByServiceName(p);
|
||||
usernames.addAll(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Routing module home page
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void index(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
String address = (String) context.get("address");
|
||||
address = Tool.getIP(address);
|
||||
List<Route> routes;
|
||||
if (service != null && service.length() > 0
|
||||
&& address != null && address.length() > 0) {
|
||||
routes = routeService.findByServiceAndAddress(service, address);
|
||||
} else if (service != null && service.length() > 0) {
|
||||
routes = routeService.findByService(service);
|
||||
} else if (address != null && address.length() > 0) {
|
||||
routes = routeService.findByAddress(address);
|
||||
} else {
|
||||
routes = routeService.findAll();
|
||||
}
|
||||
context.put("routes", routes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display routing details
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void show(Map<String, Object> context) {
|
||||
try {
|
||||
Route route = routeService.findRoute(Long.parseLong((String) context.get("id")));
|
||||
|
||||
if (route == null) {
|
||||
throw new IllegalArgumentException("The route is not existed.");
|
||||
}
|
||||
if (route.getService() != null && !route.getService().isEmpty()) {
|
||||
context.put("service", route.getService());
|
||||
}
|
||||
|
||||
RouteRule routeRule = RouteRule.parse(route);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, RouteRule.MatchPair>[] paramArray = new Map[]{
|
||||
routeRule.getWhenCondition(), routeRule.getThenCondition()};
|
||||
String[][][] namesArray = new String[][][]{when_names, then_names};
|
||||
|
||||
for (int i = 0; i < paramArray.length; ++i) {
|
||||
Map<String, RouteRule.MatchPair> param = paramArray[i];
|
||||
String[][] names = namesArray[i];
|
||||
for (String[] name : names) {
|
||||
RouteRule.MatchPair matchPair = param.get(name[0]);
|
||||
if (matchPair == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!matchPair.getMatches().isEmpty()) {
|
||||
String m = RouteRule.join(matchPair.getMatches());
|
||||
context.put(name[1], m);
|
||||
}
|
||||
if (!matchPair.getUnmatches().isEmpty()) {
|
||||
String u = RouteRule.join(matchPair.getUnmatches());
|
||||
context.put(name[2], u);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.put("route", route);
|
||||
context.put("methods", CollectionUtils.sort(new ArrayList<String>(providerService.findMethodsByService(route.getService()))));
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load new route page
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void add(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
if (service != null && service.length() > 0 && !service.contains("*")) {
|
||||
context.put("service", service);
|
||||
context.put("methods", CollectionUtils.sort(new ArrayList<String>(providerService.findMethodsByService(service))));
|
||||
} else {
|
||||
List<String> serviceList = Tool.sortSimpleName(new ArrayList<String>(providerService.findServices()));
|
||||
context.put("serviceList", serviceList);
|
||||
}
|
||||
|
||||
if (context.get("input") != null) context.put("input", context.get("input"));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load modified routing page
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void edit(Map<String, Object> context) {
|
||||
add(context);
|
||||
show(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the routing information to the database
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public boolean create(Map<String, Object> context) {
|
||||
String name = (String) context.get("name");
|
||||
String service = (String) context.get("service");
|
||||
if (StringUtils.isNotEmpty(service)
|
||||
&& StringUtils.isNotEmpty(name)) {
|
||||
checkService(service);
|
||||
|
||||
Map<String, String> when_name2valueList = new HashMap<String, String>();
|
||||
Map<String, String> notWhen_name2valueList = new HashMap<String, String>();
|
||||
for (String[] names : when_names) {
|
||||
when_name2valueList.put(names[0], (String) context.get(names[1]));
|
||||
notWhen_name2valueList.put(names[0], (String) context.get(names[2])); // TODO. We should guarantee value is never null in here, will be supported later
|
||||
}
|
||||
|
||||
Map<String, String> then_name2valueList = new HashMap<String, String>();
|
||||
Map<String, String> notThen_name2valueList = new HashMap<String, String>();
|
||||
for (String[] names : then_names) {
|
||||
then_name2valueList.put(names[0], (String) context.get(names[1]));
|
||||
notThen_name2valueList.put(names[0], (String) context.get(names[2]));
|
||||
}
|
||||
|
||||
RouteRule routeRule = RouteRule.createFromNameAndValueListString(
|
||||
when_name2valueList, notWhen_name2valueList,
|
||||
then_name2valueList, notThen_name2valueList);
|
||||
|
||||
if (routeRule.getThenCondition().isEmpty()) {
|
||||
context.put("message", getMessage("Add route error! then is empty."));
|
||||
return false;
|
||||
}
|
||||
|
||||
String matchRule = routeRule.getWhenConditionString();
|
||||
String filterRule = routeRule.getThenConditionString();
|
||||
|
||||
// Limit the length of the expression
|
||||
if (matchRule.length() > MAX_RULE_LENGTH) {
|
||||
context.put("message", getMessage("When rule is too long!"));
|
||||
return false;
|
||||
}
|
||||
if (filterRule.length() > MAX_RULE_LENGTH) {
|
||||
context.put("message", getMessage("Then rule is too long!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
Route route = new Route();
|
||||
route.setService(service);
|
||||
route.setName(name);
|
||||
route.setUsername((String) context.get("operator"));
|
||||
route.setOperator((String) context.get("operatorAddress"));
|
||||
route.setRule(routeRule.toString());
|
||||
if (StringUtils.isNotEmpty((String) context.get("priority"))) {
|
||||
route.setPriority(Integer.parseInt((String) context.get("priority")));
|
||||
}
|
||||
routeService.createRoute(route);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the update data to the database
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public boolean update(Map<String, Object> context) {
|
||||
String idStr = (String) context.get("id");
|
||||
if (idStr != null && idStr.length() > 0) {
|
||||
String[] blacks = (String[]) context.get("black");
|
||||
boolean black = false;
|
||||
if (blacks != null && blacks.length > 0) {
|
||||
black = true;
|
||||
}
|
||||
|
||||
Route oldRoute = routeService.findRoute(Long.valueOf(idStr));
|
||||
if (null == oldRoute) {
|
||||
context.put("message", getMessage("NoSuchRecord"));
|
||||
return false;
|
||||
}
|
||||
// Check parameters, patchwork rule
|
||||
if (StringUtils.isNotEmpty((String) context.get("name"))) {
|
||||
String service = oldRoute.getService();
|
||||
if (context.get("operator") == null) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<String, String> when_name2valueList = new HashMap<String, String>();
|
||||
Map<String, String> notWhen_name2valueList = new HashMap<String, String>();
|
||||
for (String[] names : when_names) {
|
||||
when_name2valueList.put(names[0], (String) context.get(names[1]));
|
||||
notWhen_name2valueList.put(names[0], (String) context.get(names[2]));
|
||||
}
|
||||
|
||||
Map<String, String> then_name2valueList = new HashMap<String, String>();
|
||||
Map<String, String> notThen_name2valueList = new HashMap<String, String>();
|
||||
for (String[] names : then_names) {
|
||||
then_name2valueList.put(names[0], (String) context.get(names[1]));
|
||||
notThen_name2valueList.put(names[0], (String) context.get(names[2]));
|
||||
}
|
||||
|
||||
RouteRule routeRule = RouteRule.createFromNameAndValueListString(
|
||||
when_name2valueList, notWhen_name2valueList,
|
||||
then_name2valueList, notThen_name2valueList);
|
||||
|
||||
RouteRule result = null;
|
||||
if (black) {
|
||||
RouteRule.MatchPair matchPair = routeRule.getThenCondition().get("black");
|
||||
Map<String, RouteRule.MatchPair> then = null;
|
||||
if (null == matchPair) {
|
||||
matchPair = new RouteRule.MatchPair();
|
||||
then = new HashMap<String, RouteRule.MatchPair>();
|
||||
then.put("black", matchPair);
|
||||
} else {
|
||||
matchPair.getMatches().clear();
|
||||
}
|
||||
matchPair.getMatches().add(String.valueOf(black));
|
||||
result = RouteRule.copyWithReplace(routeRule, null, then);
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
result = routeRule;
|
||||
}
|
||||
|
||||
if (result.getThenCondition().isEmpty()) {
|
||||
context.put("message", getMessage("Update route error! then is empty."));
|
||||
return false;
|
||||
}
|
||||
|
||||
String matchRule = result.getWhenConditionString();
|
||||
String filterRule = result.getThenConditionString();
|
||||
|
||||
// Limit the length of the expression
|
||||
if (matchRule.length() > MAX_RULE_LENGTH) {
|
||||
context.put("message", getMessage("When rule is too long!"));
|
||||
return false;
|
||||
}
|
||||
if (filterRule.length() > MAX_RULE_LENGTH) {
|
||||
context.put("message", getMessage("Then rule is too long!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int priority = 0;
|
||||
if (StringUtils.isNotEmpty((String) context.get("priority"))) {
|
||||
priority = Integer.parseInt((String) context.get("priority"));
|
||||
}
|
||||
|
||||
Route route = new Route();
|
||||
route.setRule(result.toString());
|
||||
route.setService(service);
|
||||
route.setPriority(priority);
|
||||
route.setName((String) context.get("name"));
|
||||
route.setUsername((String) context.get("operator"));
|
||||
route.setOperator((String) context.get("operatorAddress"));
|
||||
route.setId(Long.valueOf(idStr));
|
||||
route.setPriority(Integer.parseInt((String) context.get("priority")));
|
||||
route.setEnabled(oldRoute.isEnabled());
|
||||
routeService.updateRoute(route);
|
||||
|
||||
Set<String> usernames = new HashSet<String>();
|
||||
usernames.add((String) context.get("operator"));
|
||||
usernames.add(route.getUsername());
|
||||
//RelateUserUtils.addOwnersOfService(usernames, route.getService(), ownerDAO);
|
||||
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("action", "update");
|
||||
params.put("route", route);
|
||||
|
||||
} else {
|
||||
context.put("message", getMessage("MissRequestParameters", "name"));
|
||||
}
|
||||
} else {
|
||||
context.put("message", getMessage("MissRequestParameters", "id"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the route rule for the specified ID
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public boolean delete(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
routeService.deleteRoute(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the specified route ID rules (batch processing)
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public boolean enable(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
routeService.enableRoute(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disabling route rules for specified IDs (can be batch processed)
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public boolean disable(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
routeService.disableRoute(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose consumers
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void routeselect(Map<String, Object> context) {
|
||||
long rid = Long.valueOf((String) context.get("id"));
|
||||
context.put("id", rid);
|
||||
|
||||
Route route = routeService.findRoute(rid);
|
||||
if (route == null) {
|
||||
throw new IllegalStateException("Route(id=" + rid + ") is not existed!");
|
||||
}
|
||||
|
||||
context.put("route", route);
|
||||
// retrieve data
|
||||
List<Consumer> consumers = consumerService.findByService(route.getService());
|
||||
context.put("consumers", consumers);
|
||||
|
||||
Map<String, Boolean> matchRoute = new HashMap<String, Boolean>();
|
||||
for (Consumer c : consumers) {
|
||||
matchRoute.put(c.getAddress(), RouteUtils.matchRoute(c.getAddress(), null, route, null));
|
||||
}
|
||||
context.put("matchRoute", matchRoute);
|
||||
}
|
||||
|
||||
public void preview(Map<String, Object> context) throws Exception {
|
||||
String rid = (String) context.get("id");
|
||||
String consumerid = (String) context.get("cid");
|
||||
|
||||
|
||||
if (StringUtils.isEmpty(rid)) {
|
||||
context.put("message", getMessage("MissRequestParameters", "id"));
|
||||
}
|
||||
|
||||
Map<String, String> serviceUrls = new HashMap<String, String>();
|
||||
Route route = routeService.findRoute(Long.valueOf(rid));
|
||||
if (null == route) {
|
||||
context.put("message", getMessage("NoSuchRecord"));
|
||||
}
|
||||
List<Provider> providers = providerService.findByService(route.getService());
|
||||
if (providers != null) {
|
||||
for (Provider p : providers) {
|
||||
serviceUrls.put(p.getUrl(), p.getParameters());
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotEmpty(consumerid)) {
|
||||
Consumer consumer = consumerService.findConsumer(Long.valueOf(consumerid));
|
||||
if (null == consumer) {
|
||||
context.put("message", getMessage("NoSuchRecord"));
|
||||
}
|
||||
Map<String, String> result = RouteUtils.previewRoute(consumer.getService(), consumer.getAddress(), consumer.getParameters(), serviceUrls,
|
||||
route, null, null);
|
||||
context.put("route", route);
|
||||
context.put("consumer", consumer);
|
||||
context.put("result", result);
|
||||
} else {
|
||||
String address = (String) context.get("address");
|
||||
String service = (String) context.get("service");
|
||||
|
||||
Map<String, String> result = RouteUtils.previewRoute(service, address, null, serviceUrls,
|
||||
route, null, null);
|
||||
context.put("route", route);
|
||||
|
||||
Consumer consumer = new Consumer();
|
||||
consumer.setService(service);
|
||||
consumer.setAddress(address);
|
||||
context.put("consumer", consumer);
|
||||
context.put("result", result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Override;
|
||||
import com.alibaba.dubbo.registry.common.route.OverrideUtils;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Providers. URI: /services/$service/providers /addresses/$address/services /application/$application/services
|
||||
*
|
||||
*/
|
||||
public class Services extends Restful {
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
private ConsumerService consumerService;
|
||||
|
||||
@Autowired
|
||||
private OverrideService overrideService;
|
||||
|
||||
public void index(Map<String, Object> context) {
|
||||
String application = (String) context.get("application");
|
||||
String address = (String) context.get("address");
|
||||
|
||||
if (context.get("service") == null
|
||||
&& context.get("application") == null
|
||||
&& context.get("address") == null) {
|
||||
context.put("service", "*");
|
||||
}
|
||||
|
||||
List<String> providerServices = null;
|
||||
List<String> consumerServices = null;
|
||||
List<Override> overrides = null;
|
||||
if (application != null && application.length() > 0) {
|
||||
providerServices = providerService.findServicesByApplication(application);
|
||||
consumerServices = consumerService.findServicesByApplication(application);
|
||||
overrides = overrideService.findByApplication(application);
|
||||
} else if (address != null && address.length() > 0) {
|
||||
providerServices = providerService.findServicesByAddress(address);
|
||||
consumerServices = consumerService.findServicesByAddress(address);
|
||||
overrides = overrideService.findByAddress(Tool.getIP(address));
|
||||
} else {
|
||||
providerServices = providerService.findServices();
|
||||
consumerServices = consumerService.findServices();
|
||||
overrides = overrideService.findAll();
|
||||
}
|
||||
|
||||
Set<String> services = new TreeSet<String>();
|
||||
if (providerServices != null) {
|
||||
services.addAll(providerServices);
|
||||
}
|
||||
if (consumerServices != null) {
|
||||
services.addAll(consumerServices);
|
||||
}
|
||||
|
||||
Map<String, List<Override>> service2Overrides = new HashMap<String, List<Override>>();
|
||||
if (overrides != null && overrides.size() > 0
|
||||
&& services != null && services.size() > 0) {
|
||||
for (String s : services) {
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
for (Override override : overrides) {
|
||||
List<Override> serOverrides = new ArrayList<Override>();
|
||||
if (override.isMatch(s, address, application)) {
|
||||
serOverrides.add(override);
|
||||
}
|
||||
Collections.sort(serOverrides, OverrideUtils.OVERRIDE_COMPARATOR);
|
||||
service2Overrides.put(s, serOverrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.put("providerServices", providerServices);
|
||||
context.put("consumerServices", consumerServices);
|
||||
context.put("services", services);
|
||||
context.put("overrides", service2Overrides);
|
||||
|
||||
String keyword = (String) context.get("keyword");
|
||||
if (StringUtils.isNotEmpty(keyword) && !"*".equals(keyword)) {
|
||||
keyword = keyword.toLowerCase();
|
||||
Set<String> newList = new HashSet<String>();
|
||||
Set<String> newProviders = new HashSet<String>();
|
||||
Set<String> newConsumers = new HashSet<String>();
|
||||
|
||||
for (String o : services) {
|
||||
if (o.toLowerCase().toLowerCase().indexOf(keyword) != -1) {
|
||||
newList.add(o);
|
||||
}
|
||||
}
|
||||
for (String o : providerServices) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newProviders.add(o);
|
||||
}
|
||||
}
|
||||
for (String o : consumerServices) {
|
||||
if (o.toLowerCase().indexOf(keyword) != -1) {
|
||||
newConsumers.add(o);
|
||||
}
|
||||
}
|
||||
context.put("services", newList);
|
||||
context.put("providerServices", newProviders);
|
||||
context.put("consumerServices", newConsumers);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shield(Map<String, Object> context) throws Exception {
|
||||
return mock(context, "force:return null");
|
||||
}
|
||||
|
||||
public boolean tolerant(Map<String, Object> context) throws Exception {
|
||||
return mock(context, "fail:return null");
|
||||
}
|
||||
|
||||
public boolean recover(Map<String, Object> context) throws Exception {
|
||||
return mock(context, "");
|
||||
}
|
||||
|
||||
private boolean mock(Map<String, Object> context, String mock) throws Exception {
|
||||
String services = (String) context.get("service");
|
||||
String application = (String) context.get("application");
|
||||
if (services == null || services.length() == 0
|
||||
|| application == null || application.length() == 0) {
|
||||
context.put("message", getMessage("NoSuchOperationData"));
|
||||
return false;
|
||||
}
|
||||
for (String service : SPACE_SPLIT_PATTERN.split(services)) {
|
||||
if (!super.currentUser.hasServicePrivilege(service)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", service));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (String service : SPACE_SPLIT_PATTERN.split(services)) {
|
||||
List<Override> overrides = overrideService.findByServiceAndApplication(service, application);
|
||||
if (overrides != null && overrides.size() > 0) {
|
||||
for (Override override : overrides) {
|
||||
Map<String, String> map = StringUtils.parseQueryString(override.getParams());
|
||||
if (mock == null || mock.length() == 0) {
|
||||
map.remove("mock");
|
||||
} else {
|
||||
map.put("mock", URL.encode(mock));
|
||||
}
|
||||
if (map.size() > 0) {
|
||||
override.setParams(StringUtils.toQueryString(map));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.updateOverride(override);
|
||||
} else {
|
||||
overrideService.deleteOverride(override.getId());
|
||||
}
|
||||
}
|
||||
} else if (mock != null && mock.length() > 0) {
|
||||
Override override = new Override();
|
||||
override.setService(service);
|
||||
override.setApplication(application);
|
||||
override.setParams("mock=" + URL.encode(mock));
|
||||
override.setEnabled(true);
|
||||
override.setOperator(operator);
|
||||
override.setOperatorAddress(operatorAddress);
|
||||
overrideService.saveOverride(override);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.governance.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.utils.CollectionUtils;
|
||||
import com.alibaba.dubbo.governance.service.OverrideService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.module.screen.Restful;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
import com.alibaba.dubbo.registry.common.domain.Weight;
|
||||
import com.alibaba.dubbo.registry.common.util.OverrideUtils;
|
||||
import com.alibaba.dubbo.registry.common.util.Tool;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Providers.
|
||||
* URI: /services/$service/weights
|
||||
*
|
||||
*/
|
||||
public class Weights extends Restful {
|
||||
|
||||
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3}$");
|
||||
private static final Pattern LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$");
|
||||
private static final Pattern ALL_IP_PATTERN = Pattern.compile("0{1,3}(\\.0{1,3}){3}$");
|
||||
@Autowired
|
||||
private OverrideService overrideService;
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
public void index(Map<String, Object> context) {
|
||||
final String service = StringUtils.trimToNull((String) context.get("service"));
|
||||
String address = (String) context.get("address");
|
||||
address = Tool.getIP(address);
|
||||
List<Weight> weights;
|
||||
if (service != null && service.length() > 0) {
|
||||
weights = OverrideUtils.overridesToWeights(overrideService.findByService(service));
|
||||
} else if (address != null && address.length() > 0) {
|
||||
weights = OverrideUtils.overridesToWeights(overrideService.findByAddress(address));
|
||||
} else {
|
||||
weights = OverrideUtils.overridesToWeights(overrideService.findAll());
|
||||
}
|
||||
context.put("weights", weights);
|
||||
}
|
||||
|
||||
/**
|
||||
* load page for the adding
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void add(Map<String, Object> context) {
|
||||
String service = (String) context.get("service");
|
||||
if (service != null && service.length() > 0 && !service.contains("*")) {
|
||||
List<Provider> providerList = providerService.findByService(service);
|
||||
List<String> addressList = new ArrayList<String>();
|
||||
for (Provider provider : providerList) {
|
||||
addressList.add(provider.getUrl().split("://")[1].split("/")[0]);
|
||||
}
|
||||
context.put("addressList", addressList);
|
||||
context.put("service", service);
|
||||
context.put("methods", CollectionUtils.sort(providerService.findMethodsByService(service)));
|
||||
} else {
|
||||
List<String> serviceList = Tool.sortSimpleName(providerService.findServices());
|
||||
context.put("serviceList", serviceList);
|
||||
}
|
||||
if (context.get("input") != null) context.put("input", context.get("input"));
|
||||
}
|
||||
|
||||
/**
|
||||
* load page for the multi adding
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void multiadd(Map<String, Object> context) {
|
||||
List<String> serviceList = Tool.sortSimpleName(providerService.findServices());
|
||||
context.put("serviceList", serviceList);
|
||||
}
|
||||
|
||||
public boolean create(Map<String, Object> context) throws Exception {
|
||||
String addr = (String) context.get("address");
|
||||
String services = (String) context.get("multiservice");
|
||||
if (services == null || services.trim().length() == 0) {
|
||||
services = (String) context.get("service");
|
||||
}
|
||||
String weight = (String) context.get("weight");
|
||||
|
||||
int w = Integer.parseInt(weight);
|
||||
|
||||
Set<String> addresses = new HashSet<String>();
|
||||
BufferedReader reader = new BufferedReader(new StringReader(addr));
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (null == line)
|
||||
break;
|
||||
|
||||
String[] split = line.split("[\\s,;]+");
|
||||
for (String s : split) {
|
||||
if (s.length() == 0)
|
||||
continue;
|
||||
|
||||
String ip = s;
|
||||
String port = null;
|
||||
if (s.indexOf(":") != -1) {
|
||||
ip = s.substring(0, s.indexOf(":"));
|
||||
port = s.substring(s.indexOf(":") + 1, s.length());
|
||||
if (port.trim().length() == 0) port = null;
|
||||
}
|
||||
if (!IP_PATTERN.matcher(ip).matches()) {
|
||||
context.put("message", "illegal IP: " + s);
|
||||
return false;
|
||||
}
|
||||
if (LOCAL_IP_PATTERN.matcher(ip).matches() || ALL_IP_PATTERN.matcher(ip).matches()) {
|
||||
context.put("message", "local IP or any host ip is illegal: " + s);
|
||||
return false;
|
||||
}
|
||||
if (port != null) {
|
||||
if (!NumberUtils.isDigits(port)) {
|
||||
context.put("message", "illegal port: " + s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
addresses.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> aimServices = new HashSet<String>();
|
||||
reader = new BufferedReader(new StringReader(services));
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (null == line)
|
||||
break;
|
||||
|
||||
String[] split = line.split("[\\s,;]+");
|
||||
for (String s : split) {
|
||||
if (s.length() == 0)
|
||||
continue;
|
||||
if (!super.currentUser.hasServicePrivilege(s)) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", s));
|
||||
return false;
|
||||
}
|
||||
aimServices.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
for (String aimService : aimServices) {
|
||||
for (String a : addresses) {
|
||||
Weight wt = new Weight();
|
||||
wt.setUsername((String) context.get("operator"));
|
||||
wt.setAddress(Tool.getIP(a));
|
||||
wt.setService(aimService);
|
||||
wt.setWeight(w);
|
||||
overrideService.saveOverride(OverrideUtils.weightToOverride(wt));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void edit(Long id, Map<String, Object> context) {
|
||||
add(context);
|
||||
show(id, context);
|
||||
context.put("service", overrideService.findById(id).getService());
|
||||
}
|
||||
|
||||
public void sameSeviceEdit(Long id, Map<String, Object> context) {
|
||||
add(context);
|
||||
show(id, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* load weight for editing
|
||||
*
|
||||
* @param id
|
||||
* @param context
|
||||
*/
|
||||
public void show(Long id, Map<String, Object> context) {
|
||||
Weight weight = OverrideUtils.overrideToWeight(overrideService.findById(id));
|
||||
context.put("weight", weight);
|
||||
}
|
||||
|
||||
public boolean update(Weight weight, Map<String, Object> context) {
|
||||
if (!super.currentUser.hasServicePrivilege(weight.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", weight.getService()));
|
||||
return false;
|
||||
}
|
||||
weight.setAddress(Tool.getIP(weight.getAddress()));
|
||||
overrideService.updateOverride(OverrideUtils.weightToOverride(weight));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public boolean delete(Long[] ids, Map<String, Object> context) {
|
||||
for (Long id : ids) {
|
||||
Weight w = OverrideUtils.overrideToWeight(overrideService.findById(id));
|
||||
if (!super.currentUser.hasServicePrivilege(w.getService())) {
|
||||
context.put("message", getMessage("HaveNoServicePrivilege", w.getService()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (Long id : ids) {
|
||||
overrideService.deleteOverride(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.home.module.control;
|
||||
|
||||
import com.alibaba.citrus.service.requestcontext.parser.CookieParser;
|
||||
import com.alibaba.citrus.turbine.Context;
|
||||
import com.alibaba.dubbo.governance.sync.RegistryServerSync;
|
||||
import com.alibaba.dubbo.governance.web.common.pulltool.RootContextPath;
|
||||
import com.alibaba.dubbo.governance.web.util.WebConstants;
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
public class Menu {
|
||||
|
||||
@Autowired
|
||||
ServletContext servletcontext;
|
||||
@Autowired
|
||||
RegistryServerSync registryServerSync;
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
public void execute(HttpSession session, Context context, CookieParser parser) {
|
||||
|
||||
User user = (User) session.getAttribute(WebConstants.CURRENT_USER_KEY);
|
||||
if (user != null) context.put("operator", user.getUsername());
|
||||
|
||||
RootContextPath rootContextPath = new RootContextPath(request.getContextPath());
|
||||
context.put("rootContextPath", rootContextPath);
|
||||
if (!context.containsKey("bucLogoutAddress")) {
|
||||
context.put("bucLogoutAddress", rootContextPath.getURI("logout"));
|
||||
}
|
||||
if (!context.containsKey("helpUrl")) {
|
||||
context.put("helpUrl", "http://code.alibabatech.com/wiki/display/dubbo");
|
||||
}
|
||||
context.put(WebConstants.CURRENT_USER_KEY, user);
|
||||
context.put("language", parser.getString("locale"));
|
||||
context.put("registryServerSync", registryServerSync);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 com.alibaba.dubbo.governance.web.home.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Disable extends Shell {
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
public void setProviderDAO(ProviderService providerDAO) {
|
||||
this.providerService = providerDAO;
|
||||
}
|
||||
|
||||
protected String doExecute(Map<String, Object> context) throws Exception {
|
||||
String address = request.getParameter("provider");
|
||||
if (address == null || address.length() == 0) {
|
||||
address = request.getParameter("client");
|
||||
}
|
||||
if (address == null || address.length() == 0) {
|
||||
throw new IllegalArgumentException("The url provider parameter is null! Usage: " + request.getRequestURL().toString() + "?provider=" + operatorAddress);
|
||||
}
|
||||
List<Provider> providers = providerService.findByAddress(address);
|
||||
if (providers != null && providers.size() > 0) {
|
||||
for (Provider provider : providers) {
|
||||
if (!currentUser.hasServicePrivilege(provider.getService())) {
|
||||
throw new IllegalStateException("The user " + currentUser.getUsername() + " have no privilege of service " + provider.getService());
|
||||
}
|
||||
}
|
||||
for (Provider provider : providers) {
|
||||
provider.setUsername(operator);
|
||||
provider.setOperatorAddress(operatorAddress);
|
||||
providerService.disableProvider(provider.getId());
|
||||
}
|
||||
}
|
||||
return "Disable " + (providers == null ? 0 : providers.size()) + " services.";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.home.module.screen;
|
||||
|
||||
import com.alibaba.citrus.turbine.Context;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
import com.alibaba.dubbo.governance.web.common.pulltool.RootContextPath;
|
||||
import com.alibaba.dubbo.registry.common.domain.Consumer;
|
||||
import com.alibaba.dubbo.registry.common.domain.Provider;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Index
|
||||
*
|
||||
*/
|
||||
public class Index {
|
||||
// logger
|
||||
private static final Logger logger = LoggerFactory.getLogger(Index.class);
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
|
||||
@Autowired
|
||||
private ConsumerService consumerService;
|
||||
|
||||
public void execute(Context context) {
|
||||
Set<String> applications = new HashSet<String>();
|
||||
Set<String> services = new HashSet<String>();
|
||||
List<Provider> pList = new ArrayList<Provider>();
|
||||
try {
|
||||
pList = providerService.findAll();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
for (Provider p : pList) {
|
||||
applications.add(p.getApplication());
|
||||
services.add(p.getService());
|
||||
}
|
||||
List<Consumer> cList = new ArrayList<Consumer>();
|
||||
try {
|
||||
cList = consumerService.findAll();
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
for (Consumer c : cList) {
|
||||
applications.add(c.getApplication());
|
||||
services.add(c.getService());
|
||||
}
|
||||
context.put("rootContextPath", new RootContextPath(request.getContextPath()));
|
||||
context.put("services", services.size());
|
||||
context.put("providers", pList.size());
|
||||
context.put("consumers", cList.size());
|
||||
context.put("applications", applications.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.home.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.governance.service.ConsumerService;
|
||||
import com.alibaba.dubbo.registry.RegistryService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Lookup extends Restful {
|
||||
|
||||
@Autowired
|
||||
ConsumerService consumerDAO;
|
||||
|
||||
@Autowired
|
||||
private RegistryService registryService;
|
||||
|
||||
public Result doExecute(Map<String, Object> context) throws Exception {
|
||||
String inf = request.getParameter("interface");
|
||||
if (inf == null || inf.isEmpty()) {
|
||||
throw new IllegalArgumentException("please give me the interface");
|
||||
}
|
||||
String group = null;
|
||||
if (inf.contains("/")) {
|
||||
int idx = inf.indexOf('/');
|
||||
group = inf.substring(idx);
|
||||
inf = inf.substring(idx + 1, inf.length());
|
||||
}
|
||||
String version = null;
|
||||
if (inf.contains(":")) {
|
||||
int idx = inf.lastIndexOf(':');
|
||||
version = inf.substring(idx + 1, inf.length());
|
||||
inf = inf.substring(idx);
|
||||
}
|
||||
|
||||
String parameters = request.getParameter("parameters");
|
||||
String url = "subscribe://" + operatorAddress + "/" + request.getParameter("interface");
|
||||
if (parameters != null && parameters.trim().length() > 0) {
|
||||
url += parameters.trim();
|
||||
}
|
||||
|
||||
URL u = URL.valueOf(url);
|
||||
if (group != null) {
|
||||
u.addParameter("group", group);
|
||||
}
|
||||
|
||||
if (version != null) u.addParameter("version", version);
|
||||
|
||||
List<URL> lookup = registryService.lookup(u);
|
||||
|
||||
Map<String, Map<String, String>> serviceUrl = new HashMap<String, Map<String, String>>();
|
||||
Map<String, String> urls = new HashMap<String, String>();
|
||||
serviceUrl.put(request.getParameter("interface").trim(), urls);
|
||||
|
||||
for (URL u2 : lookup) {
|
||||
urls.put(u2.toIdentityString(), u2.toParameterString());
|
||||
}
|
||||
|
||||
Result result = new Result();
|
||||
result.setMessage(serviceUrl);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.home.module.screen;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Reg extends Restful {
|
||||
|
||||
public Result doExecute(Map<String, Object> context) throws Exception {
|
||||
if (url == null) {
|
||||
throw new IllegalArgumentException("please give me the url");
|
||||
}
|
||||
if (url.getPath().isEmpty()) {
|
||||
throw new IllegalArgumentException("please use interface as your url path");
|
||||
}
|
||||
Map<String, String> tmp = new HashMap<String, String>();
|
||||
tmp.put(url.toIdentityString(), url.toParameterString());
|
||||
Map<String, Map<String, String>> register = new HashMap<String, Map<String, String>>();
|
||||
register.put(url.getPath(), tmp);
|
||||
// Map<String, Map<String, String>> newRegister = RegistryUtils.convertRegister(register);
|
||||
// registryService.register(operatorAddress, newRegister, false);
|
||||
Result result = new Result();
|
||||
result.setMessage("Register Successfully!");
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.home.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.utils.CollectionUtils;
|
||||
import com.alibaba.dubbo.common.utils.StringUtils;
|
||||
import com.alibaba.dubbo.governance.service.ProviderService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Register extends Shell {
|
||||
|
||||
@Autowired
|
||||
private ProviderService providerDAO;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
// @Autowired
|
||||
// private RegistryCache registryCache;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected String doExecute(Map<String, Object> context) throws Exception {
|
||||
Map<String, String[]> params = request.getParameterMap();
|
||||
if (params == null || params.size() == 0) {
|
||||
throw new IllegalArgumentException("The url parameters is null! Usage: " + request.getRequestURL().toString() + "?com.xxx.XxxService=http://" + request.getRemoteAddr() + "/xxxService?application=xxx&foo1=123");
|
||||
}
|
||||
Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
|
||||
for (Map.Entry<String, String[]> entry : params.entrySet()) {
|
||||
if (entry.getKey() != null && entry.getKey().length() > 0
|
||||
&& entry.getValue() != null && entry.getValue().length > 0
|
||||
&& entry.getValue()[0] != null && entry.getValue()[0].length() > 0) {
|
||||
if (!currentUser.hasServicePrivilege(entry.getKey())) {
|
||||
throw new IllegalStateException("The user " + currentUser.getUsername() + " have no privilege of service " + entry.getKey());
|
||||
}
|
||||
String serviceName = entry.getKey();
|
||||
Map<String, String> url2query = CollectionUtils.split(Arrays.asList(entry.getValue()), "?");
|
||||
// check whether url contain application info
|
||||
for (Map.Entry<String, String> e : url2query.entrySet()) {
|
||||
Map<String, String> query = StringUtils.parseQueryString(e.getValue());
|
||||
String app = query.get("application");
|
||||
if (StringUtils.isBlank(app)) {
|
||||
throw new IllegalStateException("No application for service(" + serviceName + "): "
|
||||
+ e.getKey() + "?" + e.getValue());
|
||||
}
|
||||
}
|
||||
map.put(serviceName, url2query);
|
||||
}
|
||||
}
|
||||
if (map.size() > 0) {
|
||||
// providerDAO.register(registryCache.getCurrentRegistry(), request.getRemoteAddr(), operatorAddress, operator, map, false, true);
|
||||
}
|
||||
return "Register " + map.size() + " services.";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.home.module.screen;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.governance.web.util.WebConstants;
|
||||
import com.alibaba.dubbo.registry.common.domain.User;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Restful {
|
||||
|
||||
protected String role = null;
|
||||
protected String operator = null;
|
||||
|
||||
// @Autowired
|
||||
// RegistryValidator registryService;
|
||||
protected User currentUser = null;
|
||||
protected String operatorAddress = null;
|
||||
protected URL url = null;
|
||||
@Autowired
|
||||
HttpServletRequest request;
|
||||
@Autowired
|
||||
private HttpServletResponse response;
|
||||
|
||||
public void execute(Map<String, Object> context) throws Exception {
|
||||
Result result = new Result();
|
||||
if (request.getParameter("url") != null) {
|
||||
url = URL.valueOf(URL.decode(request.getParameter("url")));
|
||||
}
|
||||
if (context.get(WebConstants.CURRENT_USER_KEY) != null) {
|
||||
User user = (User) context.get(WebConstants.CURRENT_USER_KEY);
|
||||
currentUser = user;
|
||||
operator = user.getUsername();
|
||||
role = user.getRole();
|
||||
context.put(WebConstants.CURRENT_USER_KEY, user);
|
||||
}
|
||||
operatorAddress = (String) context.get("clientid");
|
||||
if (operatorAddress == null || operatorAddress.isEmpty()) {
|
||||
operatorAddress = (String) context.get("request.remoteHost");
|
||||
}
|
||||
context.put("operator", operator);
|
||||
context.put("operatorAddress", operatorAddress);
|
||||
String jsonResult = null;
|
||||
try {
|
||||
result = doExecute(context);
|
||||
result.setStatus("OK");
|
||||
} catch (IllegalArgumentException t) {
|
||||
result.setStatus("ERROR");
|
||||
result.setCode(3);
|
||||
result.setMessage(t.getMessage());
|
||||
}
|
||||
// catch (InvalidRequestException t) {
|
||||
// result.setStatus("ERROR");
|
||||
// result.setCode(2);
|
||||
// result.setMessage(t.getMessage());
|
||||
// }
|
||||
catch (Throwable t) {
|
||||
result.setStatus("ERROR");
|
||||
result.setCode(1);
|
||||
result.setMessage(t.getMessage());
|
||||
}
|
||||
response.setContentType("application/javascript");
|
||||
ServletOutputStream os = response.getOutputStream();
|
||||
try {
|
||||
jsonResult = JSON.toJSONString(result);
|
||||
os.print(jsonResult);
|
||||
} catch (Exception e) {
|
||||
response.setStatus(500);
|
||||
os.print(e.getMessage());
|
||||
} finally {
|
||||
os.flush();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Result doExecute(Map<String, Object> context) throws Exception;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.governance.web.home.module.screen;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Result implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4922467873471920132L;
|
||||
private String status;
|
||||
private Object message;
|
||||
private int code;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Object getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(Object message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + code;
|
||||
result = prime * result + ((message == null) ? 0 : message.hashCode());
|
||||
result = prime * result + ((status == null) ? 0 : status.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
Result other = (Result) obj;
|
||||
if (code != other.code) return false;
|
||||
if (message == null) {
|
||||
if (other.message != null) return false;
|
||||
} else if (!message.equals(other.message)) return false;
|
||||
if (status == null) {
|
||||
if (other.status != null) return false;
|
||||
} else if (!status.equals(other.status)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue