diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 0000000000..0ca3390e94 --- /dev/null +++ b/.asf.yaml @@ -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. +# + +github: + description: EventMesh is a dynamic event-driven application runtime used to decouple the application and backend middleware layer, which supports a wide range of use cases that encompass complex multi-cloud, widely distributed topologies using diverse technology stacks. + homepage: https://eventmesh.apache.org/ + labels: + - pubsub + - event-mesh + - event-gateway + - event-driven + - event-streaming + - event-sourcing + - event-governance + - event-routing + - cloud-native + - serverless + - serverless-workflow + - esb + - message-bus + - cqrs + - multi-runtime + - microservice + - state-management + enabled_merge_buttons: + squash: true + merge: true + rebase: false + protected_branches: + master: + required_status_checks: + strict: true + required_pull_request_reviews: + dismiss_stale_reviews: true + required_approving_review_count: 1 diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index cf27a37024..0000000000 --- a/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -service_name: travis-pro diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..7eefbc7944 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,106 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 +title: "[Bug] Bug title " +description: If something isn't working as expected. +labels: [ "bug" ] +body: + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + + - type: checkboxes + attributes: + label: Search before asking + description: > + Please make sure to search in the [issues](https://github.com/apache/eventmesh/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/eventmesh/issues?q=is%3Aissue) and found + no similar issues. + required: true + + - type: dropdown + attributes: + label: Environment + description: Describe the environment. + options: + - Mac + - Windows + - Linux + - Other + validations: + required: true + + - type: dropdown + attributes: + label: EventMesh version + description: Describe the EventMesh version. + options: + - master + - 1.5.0 + - 1.4.0 + - 1.3.0 + - 1.2.0 + - Other + validations: + required: true + + - type: textarea + attributes: + label: What happened + description: Describe what happened. + placeholder: > + A clear and concise description of what the bug is. + validations: + required: true + + - type: textarea + attributes: + label: How to reproduce + description: > + Describe the steps to reproduce the bug here. + placeholder: > + Please make sure you provide a reproducible step-by-step case of how to reproduce the problem + as minimally and precisely as possible. + validations: + required: true + + - type: textarea + attributes: + label: Debug logs + description: Anything else we need to know? + placeholder: > + Add your debug logs here. + validations: + required: false + + - type: checkboxes + attributes: + label: Are you willing to submit PR? + 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. + options: + - label: Yes I am willing to submit a PR! + + - type: markdown + attributes: + value: "Thanks for completing our form!" diff --git a/.github/ISSUE_TEMPLATE/documentation_related.yml b/.github/ISSUE_TEMPLATE/documentation_related.yml new file mode 100644 index 0000000000..9841b8caf8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation_related.yml @@ -0,0 +1,60 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Documentation Related +title: "[Doc] Documentation Related " +description: I find some issues related to the documentation. +labels: [ "documentation" ] +body: + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + + - type: checkboxes + attributes: + label: Search before asking + description: > + Please make sure to search in the [issues](https://github.com/apache/eventmesh/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/eventmesh/issues?q=is%3Aissue) and found + no similar issues. + required: true + + - type: textarea + attributes: + label: Documentation Related + description: Describe the suggestion about document. + placeholder: > + e.g There is a typo + validations: + required: true + + - type: checkboxes + attributes: + label: Are you willing to submit PR? + 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. + options: + - label: Yes I am willing to submit a PR! + + - type: markdown + attributes: + value: "Thanks for completing our form!" \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/enhancement_request.yml b/.github/ISSUE_TEMPLATE/enhancement_request.yml new file mode 100644 index 0000000000..b4bee79aba --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement_request.yml @@ -0,0 +1,70 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Enhancement Request +title: "[Enhancement] Enhancement title" +description: I want to suggest an enhancement for this project +labels: [ "enhancement" ] +body: + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + + - type: checkboxes + attributes: + label: Search before asking + description: > + Please make sure to search in the [issues](https://github.com/apache/eventmesh/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/eventmesh/issues?q=is%3Aissue) and found + no similar issues. + required: true + + - type: textarea + attributes: + label: Enhancement Request + description: Describe the suggestion. + placeholder: > + First of all: Have you checked the docs https://github.com/apache/incubator-eventmesh/tree/develop/docs, + or GitHub issues whether someone else has already reported your issue? + validations: + required: true + + - type: textarea + attributes: + label: Describe the solution you'd like + description: Describe the suggestion. + placeholder: > + A clear and concise description of what you want to happen. Add any considered drawbacks. + validations: + required: true + + - type: checkboxes + attributes: + label: Are you willing to submit PR? + 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. + options: + - label: Yes I am willing to submit a PR! + + - type: markdown + attributes: + value: "Thanks for completing our form!" \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000..b04ec7aff9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,62 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Feature Request +title: "[Feature] Feature title " +description: I want to suggest a feature for this project. +labels: [ "feature" ] +body: + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + + - type: checkboxes + attributes: + label: Search before asking + description: > + Please make sure to search in the [issues](https://github.com/apache/eventmesh/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/eventmesh/issues?q=is%3Aissue) and found + no similar issues. + required: true + + - type: textarea + attributes: + label: Feature Request + description: Describe the feature. + placeholder: > + First of all: Have you checked the docs https://github.com/apache/incubator-eventmesh/tree/develop/docs, + or GitHub issues whether someone else has already reported your issue? + Maybe the feature already exists? + validations: + required: true + + - type: checkboxes + attributes: + label: Are you willing to submit PR? + 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. + options: + - label: Yes I am willing to submit a PR! + + - type: markdown + attributes: + value: "Thanks for completing our form!" diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 0000000000..bd39533a10 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -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. +# + +name: Question +title: "[Question] Question title " +description: I have a question that isn't answered in docs or issue. +labels: [ "question" ] +body: + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + + - type: checkboxes + attributes: + label: Search before asking + description: > + Please make sure to search in the [issues](https://github.com/apache/eventmesh/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/eventmesh/issues?q=is%3Aissue) and found + no similar issues. + required: true + + - type: textarea + attributes: + label: Question + description: Describe your question. + placeholder: > + Describe your question here :D + validations: + required: true + + - type: markdown + attributes: + value: "Thanks for completing our form!" diff --git a/.github/ISSUE_TEMPLATE/unit_test.yml b/.github/ISSUE_TEMPLATE/unit_test.yml new file mode 100644 index 0000000000..4dcfdafc64 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/unit_test.yml @@ -0,0 +1,86 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: Unit Test +title: "[Unit Test] Unit test title" +description: I want to do some unit tests for this project +labels: [ "testing" ] +body: + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + + - type: checkboxes + attributes: + label: Search before asking + description: > + Please make sure to search in the [issues](https://github.com/apache/eventmesh/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/eventmesh/issues?q=is%3Aissue) and found + no similar issues. + required: true + + - type: checkboxes + attributes: + label: Read the unit testing guidelines + description: > + Read the [unit testing guidelines](https://github.com/apache/incubator-eventmesh/blob/master/docs/en/contribute/02-write-unit-test.md) before writing unit test code. + options: + - label: > + I have read. + required: true + + - type: textarea + attributes: + label: Unit test request + description: Describe the unit test. + placeholder: > + First of all: Have you checked the docs https://github.com/apache/incubator-eventmesh/tree/develop/docs, + or GitHub issues whether someone else has already reported your issue? + Maybe the unit tests you want to do have already been done? + validations: + required: true + + - type: textarea + attributes: + label: Describe the unit tests you want to do + description: Describe the unit test. + value: | + Module name: + Located at: + Task status: ×(unfinished) / √(finished) + | Task Status | Class | Type | + | :------: | :------ | :------ | + | × | xxxxxx | xxxxxx | + validations: + required: true + + - type: checkboxes + attributes: + label: Are you willing to submit PR? + 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. + options: + - label: Yes I am willing to submit a PR! + + - type: markdown + attributes: + value: "Thanks for completing our form!" \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..ddf705cfed --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,46 @@ + + + + +Fixes ISSUE #. + +### Motivation + +*Explain the content here.* +*Explain why you want to make the changes and what problem you're trying to solve.* + + + +### Modifications + +*Describe the modifications you've done.* + + + +### Documentation + +- Does this pull request introduce a new feature? (yes / no) +- If yes, how is the feature documented? (not applicable / docs / JavaDocs / not documented) +- If a feature is not applicable for documentation, explain why? +- If a feature is not documented yet in this PR, please create a followup issue for adding the documentation diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..d17ca19232 --- /dev/null +++ b/.github/workflows/ci.yml @@ -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. +# + +name: "Continuous Integration" + +on: + push: + branches: ['*'] + pull_request: + branches: [ '*' ] + +jobs: + build: + name: Build + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macOS-latest] + java: [8, 11] + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + languages: ${{ matrix.language }} + + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + + - name: Build + run: ./gradlew clean build jar dist jacocoTestReport + + - name: Install plugin + run: ./gradlew installPlugin + + - name: Perform CodeQL analysis + uses: github/codeql-action/analyze@v1 + + - name: Upload coverage report to codecov.io + run: bash <(curl -s https://codecov.io/bash) || echo 'Failed to upload coverage report!' + + license-check: + name: License Check + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Check license header + uses: apache/skywalking-eyes@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check third party dependencies + run: | + ./gradlew clean jar dist -x test -x checkstyleMain -x javaDoc && ./gradlew installPlugin && ./gradlew tar && sh tools/dependency-check/check-dependencies.sh && echo "Thirty party dependencies check success" diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100644 index 0000000000..ccb8df0061 --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,72 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +name: Greetings + +on: [pull_request_target, issues] + +jobs: + greeting: + name: Greeting + runs-on: ubuntu-latest + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: | + Welcome to the Apache EventMesh (incubating) community!! + We are glad that you are contributing by opening this issue. :D + + Please make sure to include all the relevant context. + We will be here shortly. + + If you are interested in contributing to our project, please let us know! + You can check out our contributing guide on [contributing to EventMesh](https://github.com/apache/incubator-eventmesh/blob/develop/CONTRIBUTING.md). + + Want to get closer to the community? + + WeChat Group: + ![wechat_qr](https://github.com/apache/incubator-eventmesh/blob/develop/docs/images/mesh-helper.png?raw=true) + + Mailing Lists: + | Name | Description |Subscribe |Unsubscribe|Archive + | ---- | ---- |---- | ---- | ---- | + |Users |User support and questions mailing list| [Subscribe](mailto:users-subscribe@eventmesh.incubator.apache.org) |[Unsubscribe](mailto:users-unsubscribe@eventmesh.incubator.apache.org) |[Mail Archives](https://lists.apache.org/list.html?users@eventmesh.apache.org)| + |Development |Development related discussions| [Subscribe](mailto:dev-subscribe@eventmesh.incubator.apache.org) |[Unsubscribe](mailto:dev-unsubscribe@eventmesh.incubator.apache.org) |[Mail Archives](https://lists.apache.org/list.html?dev@eventmesh.apache.org)| + |Commits |All commits to repositories| [Subscribe](mailto:commits-subscribe@eventmesh.incubator.apache.org) |[Unsubscribe](mailto:commits-unsubscribe@eventmesh.incubator.apache.org) |[Mail Archives](https://lists.apache.org/list.html?commits@eventmesh.apache.org)| + + pr-message: | + Welcome to the Apache EventMesh (incubating) community!! + This is your first PR in our project. We're very excited to have you onboard contributing. Your contributions are greatly appreciated! + + Please make sure that the changes are covered by tests. + We will be here shortly. + Let us know if you need any help! + + Want to get closer to the community? + + WeChat Group: + ![wechat_qr](https://github.com/apache/incubator-eventmesh/blob/develop/docs/images/mesh-helper.png?raw=true) + + Mailing Lists: + | Name | Description |Subscribe |Unsubscribe|Archive + | ---- | ---- |---- | ---- | ---- | + |Users |User support and questions mailing list| [Subscribe](mailto:users-subscribe@eventmesh.incubator.apache.org) |[Unsubscribe](mailto:users-unsubscribe@eventmesh.incubator.apache.org) |[Mail Archives](https://lists.apache.org/list.html?users@eventmesh.apache.org)| + |Development |Development related discussions| [Subscribe](mailto:dev-subscribe@eventmesh.incubator.apache.org) |[Unsubscribe](mailto:dev-unsubscribe@eventmesh.incubator.apache.org) |[Mail Archives](https://lists.apache.org/list.html?dev@eventmesh.apache.org)| + |Commits |All commits to repositories| [Subscribe](mailto:commits-subscribe@eventmesh.incubator.apache.org) |[Unsubscribe](mailto:commits-unsubscribe@eventmesh.incubator.apache.org) |[Mail Archives](https://lists.apache.org/list.html?commits@eventmesh.apache.org)| diff --git a/.gitignore b/.gitignore index 936bb5cb18..cc35f18615 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,20 @@ logs build .classpath .project +.checkstyle test-output dist .pmd classes +package-lock.json +node_modules +.DS_Store +.run +/**/bin + +h2/db.mv.db + +# license check tmp file +all-dependencies.txt +self-modules.txt +third-party-dependencies.txt diff --git a/.licenserc.yaml b/.licenserc.yaml new file mode 100644 index 0000000000..19f4722454 --- /dev/null +++ b/.licenserc.yaml @@ -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. +# + +header: + license: + spdx-id: Apache-2.0 + copyright-owner: Apache Software Foundation + + paths-ignore: + - '.github/PULL_REQUEST_TEMPLATE' + - '.gitmodules' + - '**/.gitkeep' + - '**/.gitignore' + - '**/*.md' + - '**/*.json' + - '**/*.ftl' + - '**/*.iml' + - '**/*.ini' + - '**/*.crt' + - '**/*.pem' + - '**/go.sum' + - 'LICENSE' + - 'NOTICE' + - 'DISCLAIMER-WIP' + - 'gradlew' + - 'gradlew.bat' + + comment: on-failure diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4c2ba8ba57..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -dist: trusty - -language: java -jdk: -- oraclejdk8 - -script: -- travis_retry gradle check - -after_success: -- gradle clean test jacocoAllTestReport coveralls - -env: - global: - - secure: "T1QAuaAzcB7K8YjAAVVb4P9+W0JAdOFbyBwRxliyyoSZUShlIqa0eE7ioXHXWBP/d5f3XtROse6lq2qILqcU9sFSncKE2vRJlwJ5p7R23WIsCXdV70A9AVE2gLJcIJiOTMwd/YYYzNDrGLp3CSJNcKo8t7t70V2j/11I9xPTOHnaZ8FHGC3d/7bjfR/+g/3d4EOCvV8Vm6ndEmmailmF8OJ/kcbuRbArKIehjUwNDyQZfwAc9+vvPZlHgnQvR1pJ/KiK6muEIi7RQohDq7lMTmcc2LZSYgy/+aqFrmBcQwXScABFmSwysQ4KMXfrCqqMsBdmvno/NoKVGofHHKdym/oauv/G3lxLx5sgM9A7ZSFBK08x08r7u/6TDsTFmQ9LzVFDNo/OLZhxs3dr9x2C9Pa2A7IP1i1oVbbYkwBJv4z6o3khWpQAAY/IWijlCZ9vkjFfqdIXbvlPqamEaFRAmK5I3MVqL2+eBF+2Or/zwv4rXjo+v5LUKTfmDl77QUshPv6J+hblbBR0cJ/ZTSh9rHgdqhEzPGSt3e0YrEefkKWfinBr8TjIsHgQgmfU8Kz7gf7tvioOuAgKj4WlgEQJs3dPp7J5zxFVNMM6teAMFy8c2MtAdzKrs13Ri1qZWtL6B7JWlH6yhHqhKghyJhRjUFNVZnBkA/z9gzDKZ+tz2m8=" \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c03c59a0bc..70dff529b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,21 +1,33 @@ # Contributing to EventMesh -Welcome to EventMesh! This document is a guideline about how to contribute to EventMesh. -If you find something incorrect or missing, please leave comments / suggestions. +Welcome to EventMesh! This document is a guideline about how to contribute to EventMesh. If you find something incorrect +or missing, please leave comments / suggestions. ## Before you get started ### Setting up your development environment -You should have JDK installed in your operating system. +You should have JDK installed in your develop environment. +### Code style + +Import [EventMesh CheckStyle](./style/checkStyle.xml) file to your IDE. + +For IDEA, you can import check style file by: +```shell +Editor -> Code Style -> Java -> Scheme -> Import Scheme -> CheckStyle Configuration +``` +If you can't see CheckStyle Configuration section under Import Scheme, you can install CheckStyle-IDEA plugin first, and you will see it. + +You can also use `./gradlew check` to check the code style. +(NOTE: this command will check all file in project, when you submit a pr, the ci will only check the file has been changed in this pr). ## Contributing -We are always very happy to have contributions, whether for typo fix, bug fix or big new features. -Please do not ever hesitate to ask a question or send a pull request. +We are always very happy to have contributions, whether for typo fix, bug fix or big new features. Please do not ever +hesitate to ask a question or send a pull request. -We strongly value documentation and integration with other projects. -We are very glad to accept improvements for these aspects. +We strongly value documentation and integration with other projects. We are very glad to accept improvements for these +aspects. ### GitHub workflow @@ -25,44 +37,73 @@ Here are the workflow for contributors: 1. Fork to your own 2. Clone fork to local repository +```git +git clone git@github.com:yourgithub/incubator-eventmesh.git +``` 3. Create a new branch and work on it +```git +git checkout -b fix_patch_xx +``` 4. Keep your branch in sync +```git +git remote add upstream git@github.com:apache/incubator-eventmesh.git +git fetch upstream develop:upstream_develop +git rebase upstream_develop +``` 5. Commit your changes (make sure your commit message concise) 6. Push your commits to your forked repository 7. Create a pull request -Please follow [the pull request template](./.github/PULL_REQUEST_TEMPLATE.md). -Please make sure the PR has a corresponding issue. +Please follow [the pull request template](./.github/PULL_REQUEST_TEMPLATE.md). Please make sure the PR has a +corresponding issue. [GitHub Issues](https://github.com/apache/incubator-eventmesh/issues) -After creating a PR, one or more reviewers will be assigned to the pull request. -The reviewers will review the code. - -Before merging a PR, squash any fix review feedback, typo, merged, and rebased sorts of commits. -The final commit message should be clear and concise. +After creating a PR, one or more committers will help to review the pull request, after approve, this PR will be merged in to +EventMesh repository, and the related Issue will be closed. ### Open an issue / PR -We use [GitHub Issues](https://github.com/WeBankFinTech/EventMesh/issues) and [Pull Requests](https://github.com/WeBankFinTech/EventMesh/pulls) for trackers. +We use [GitHub Issues](https://github.com/apache/incubator-eventmesh/issues) +and [Pull Requests](https://github.com/apache/incubator-eventmesh/pulls) for trackers. + +If you find a bug in code, or want new features, or want to give suggestions, you +can [open an issue on GitHub](https://github.com/apache/incubator-eventmesh/issues/new) to report it. Please follow the +guideline message in the issue template. -If you find a typo in a document, find a bug in code, or want new features, or want to give suggestions, -you can [open an issue on GitHub](https://github.com/WeBankFinTech/EventMesh/issues/new) to report it. -Please follow the guideline message in the issue template. +If you want to contribute, please follow the [contribution workflow](#github-workflow) and create a new pull request. Your PR title should start with [ISSUE #xx]. +If your PR contains large changes, e.g. component refactor or new components, please write detailed documents about its +design and usage. -If you want to contribute, please follow the [contribution workflow](#github-workflow) and create a new pull request. -If your PR contains large changes, e.g. component refactor or new components, please write detailed documents -about its design and usage. +If your change is about a typo or small optimize, you needn't create an Issue, just submit a PR and title with [MINOR]. -Note that a single pull request should not be too large. If heavy changes are required, it's better to separate the changes -to a few individual PRs. +[Note]: A single pull request should not be too large. If heavy changes are required, it's better to separate the +changes to a few individual PRs. -### Code review +### PR review All code should be well reviewed by one or more committers. Some principles: -- Readability: Important code should be well-documented. Comply with our code style. +- Readability: Important code should be well-documented. Comply with our [code style](./style/checkStyle.xml). - Elegance: New functions, classes or components should be well-designed. - Testability: Important code should be well-tested (high unit test coverage). +### License review + +EventMesh follows [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) policy. All source files should +have the Apache License header added to the file header. EventMesh uses the [apache/skywalking-eyes](https://github.com/apache/skywalking-eyes) to check +the source file header. + +EventMesh uses [check-dependencies.sh](tools/dependency-check/check-dependencies.sh) script to check for third-part dependencies. +When you need to add a three-part dependency, you need to register the newly added dependency in tool/license/known-dependencies.txt. The newly added three-part libraries need to meet [ASF 3RD PARTY LICENSE POLICY](https://apache.org/legal/resolved.html). +It is highly recommended communicating with EventMesh community before you need to add a three-part library. + +### PR merge + +After a PR is approved by at least one committer, it can be merged. Before the merge, the committer can make changes to the commits message, requiring the commits +message to be clear without duplication, and use Squash and Merge to make sure one PR should only contain one commits. +For large multi-person PR, use Merge to merge, and fix the commits by rebase before merging. + ## Community ### Contact us + +Mail: dev@eventmesh.apache.org diff --git a/CONTRIBUTING.zh-CN.md b/CONTRIBUTING.zh-CN.md new file mode 100644 index 0000000000..2e9e7a721b --- /dev/null +++ b/CONTRIBUTING.zh-CN.md @@ -0,0 +1,99 @@ +# 贡献给EventMesh + +欢迎使用EventMesh! 本文档是有关如何为EventMesh做出贡献的指南。 如果发现不正确或缺失的内容,请留下评论/建议。 + +## 开始之前 + +### 设置您的开发环境 + +您应该在开发环境中安装了JDK。 + +### Code Style + +将 [EventMesh CheckStyle](./style/checkStyle.xml) 文件导入开发者工具。如果你使用IDEA,你可以通过以下步骤导入: +```shell +Editor -> Code Style -> Java -> Scheme -> Import Scheme -> CheckStyle Configuration +``` +如果你在Import Scheme下看不到CheckStyle Configuration选项,你可以先安装CheckStyle-IDEA插件,然后你就可以看到这个选项了。 + +你也可以通过执行`./gradlew check`来检查代码格式。(NOTE: 这个命令将会检查整个项目中的代码格式, 当你提交一个PR时,CI只会检查在此次PR中被被修改的文件的代码格式) +## 贡献 + +无论是对于拼写错误,BUG修复还是重要的新功能,我们总是很乐意接受您的贡献。请不要犹豫,在Github Issue上提出或者通过邮件列表进行讨论。 + +我们非常重视文档以及与其他项目的集成,我们很高兴接受这些方面的改进。 + +### GitHub工作流程 + +我们将`develop`分支用作开发分支,这表明这是一个不稳定的分支。 + +这是贡献者的工作流程 : + +1. Fork到您个人仓库 +2. 克隆到本地存储库 +```git +git clone git@github.com:yourgithub/incubator-eventmesh.git +``` +3. 创建一个新分支并对其进行处理 +```git +git checkout -b fix_patch_xx +``` +4. 保持分支与主库同步 +```git +git remote add upstream git@github.com:apache/incubator-eventmesh.git +git fetch upstream develop:upstream_develop +git rebase upstream_develop +``` +5. 提交您的更改(确保您的提交消息简明扼要) +6. 将您的提交推送到分叉的存储库 +7. 创建PR合并请求 + +请遵循[Pull Requests模板](./.github/PULL_REQUEST_TEMPLATE.md). +请确保PR对应有相应的问题. [GitHub Issues](https://github.com/apache/incubator-eventmesh/issues) + +创建PR后,社区会有committer成员帮助review,review通过之后,PR将会合并到主库,相应的Issue会被关闭。 + +### 打开问题/ PR + +我们将使用Issues和Pull Requests作为跟踪器 +- [GitHub Issues](https://github.com/apache/incubator-eventmesh/issues) +- [Pull Requests](https://github.com/apache/incubator-eventmesh/pulls) + +如果您发现新的Bug,想要新功能或提出新当建议,您可以在GitHub上[创建Issue](https://github.com/apache/incubator-eventmesh/issues/new) ,请按照Issue模板中的准则进行操作。 +如果您在文档中发现拼写错误,或者发现代码中存在可以进行微小的优化的地方,您可以无需创建Issue, 直接提交一个PR。 + +如果您想贡献,请遵循[贡献工作流程](#github-workflow)并创建一个新的拉取请求。 如果您的PR包含较大的更改,例如组件重构或新组件,请写详细文档 有关其设计和使用的信息。 +对于PR的标题请依照[ISSUE #xx]进行开头,如果是细小的改动请以[MINOR]进行开头。 + +【注意】: 单个PR不应太大。如果需要进行重大更改,最好将更改分开 到一些个人PR。 + +### PR审查 + +所有PR应由一个或多个committer进行良好的审查。一些原则: + +- 可读性: 重要代码应有详细记录。符合我们的[代码风格](./style/checkStyle.xml) +- 优雅: 新功能,类或组件应经过精心设计 +- 可测试性: 重要代码应经过良好测试(较高的单元测试覆盖率) + +### License审查 + +EventMesh遵循[Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) 政策。 +所有的源代码文件应该在文件头部添加Apache License header,EventMesh会使用[apache/skywalking-eyes](https://github.com/apache/skywalking-eyes) +对源代码文件头进行校验。 + +EventMesh使用[check-dependencies.sh](tools/dependency-check/check-dependencies.sh)脚本 +检查第三方依赖,当你需要添加三方依赖时,你需要将新添加的依赖注册在tool/license/known-dependencies.txt中, +同时新添加的三方库需要满足[Apache对于第三方的政策](https://apache.org/legal/resolved.html)。 + +当添加依赖时遇到问题时,社区PPMC会协助解决,非常建议在需要添加三方依赖之前与EventMesh社区进行沟通。 + +### PR合并 + +PR经过至少一个committer approve之后会由committer负责合并,在合并的时候,committer可以对commits信息进行修改,要求commits信息简洁明了,不重复。 +在合并时使用Squash and merge, 要求一个PR保留一个commits。对于大型多人协助的PR,使用Merge进行合并,在合并之前通过rebase修正commits。 + +## 社区 + +### 联系我们 + +邮件:dev@eventmesh.apache.org diff --git a/DISCLAIMER-WIP b/DISCLAIMER-WIP new file mode 100644 index 0000000000..e72dd1b9d0 --- /dev/null +++ b/DISCLAIMER-WIP @@ -0,0 +1,19 @@ +Apache EventMesh is an effort undergoing incubation at The Apache Software Foundation (ASF), +sponsored by the Apache Incubator PMC. + +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. + +Some of the incubating project’s releases may not be fully compliant with ASF policy. +For example, releases may have incomplete or un-reviewed licensing conditions. +What follows is a list of issues the project is currently aware of (this list is likely to be incomplete): + +1- Releases may have incomplete licensing conditions + + +If you are planning to incorporate this work into your product/project, +please be aware that you will need to conduct a thorough licensing review to determine the overall implications of including this work. +For the current status of this project through the Apache Incubator, visit: https://incubator.apache.org/projects/eventmesh.html diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000000..76091d57bb --- /dev/null +++ b/NOTICE @@ -0,0 +1,5 @@ +Apache EventMesh (incubating) +Copyright 2021-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). diff --git a/README.md b/README.md index 1d59312312..6642938509 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,116 @@ -[![Build Status](https://www.travis-ci.org/WeBankFinTech/DeFiBus.svg?branch=master)](https://www.travis-ci.org/WeBankFinTech/EventMesh) [![Coverage Status](https://coveralls.io/repos/github/WeBankFinTech/DeFiBus/badge.svg?branch=master)](https://coveralls.io/github/WeBankFinTech/EventMesh?branch=master) +
-## What is an Event Mesh? -This diagram shows where an event mesh fits in an application stack relative to other technologies such as service mesh: -![architecture1](docs/images/eventmesh-define.png) +

+ +
-An event mesh is a configurable and dynamic infrastructure layer for distributing events among decoupled applications, cloud services and devices. It enables event communications to be governed, flexible, reliable and fast. An event mesh is created and enabled through a network of interconnected event meshers. +[![CI status](https://img.shields.io/github/workflow/status/apache/incubator-eventmesh/Continuous%20Integration?logo=github&style=for-the-badge)](https://github.com/apache/incubator-eventmesh/actions/workflows/ci.yml) +[![CodeCov](https://img.shields.io/codecov/c/gh/apache/incubator-eventmesh/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/apache/incubator-eventmesh) +[![Code Quality: Java](https://img.shields.io/lgtm/grade/java/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18&style=for-the-badge)](https://lgtm.com/projects/g/apache/incubator-eventmesh/context:java) +[![Total Alerts](https://img.shields.io/lgtm/alerts/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18&style=for-the-badge)](https://lgtm.com/projects/g/apache/incubator-eventmesh/alerts/) -## What are the core capabilities of an event mesh? -This diagram shows the architecture of EventMesh: -![architecture2](docs/images/eventmesh-arch.png) +[![License](https://img.shields.io/github/license/apache/incubator-eventmesh?style=for-the-badge)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![GitHub Release](https://img.shields.io/github/v/release/apache/eventmesh?style=for-the-badge)](https://github.com/apache/incubator-eventmesh/releases) +[![Slack Status](https://img.shields.io/badge/slack-join_chat-blue.svg?logo=slack&style=for-the-badge)](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-1blhcbedu-9b7yvwAQcDs3fddZxnZXag) -An event mesh allows events from one application to be dynamically routed and received by any other application no matter where these applications are deployed (no cloud, private cloud, public cloud). -The generic capabilities of an event mesh: -* inherently ‘event-driven;’ -* created by connecting event meshers; -* environment agnostic (can be deployed anywhere); and, -* dynamic. +[📦 Documentation](https://eventmesh.apache.org/docs/introduction) | +[📔 Examples](https://github.com/apache/incubator-eventmesh/tree/master/eventmesh-examples) | +[⚙️ Roadmap](https://eventmesh.apache.org/docs/roadmap) | +[🌐 简体中文](README.zh-CN.md) +
-Key components: -* eventmesh-emesher : an middleware to transmit events between event producers and consumers, support cloud native apps and microservices -* eventmesh-sdk-java : support for popular open standard protocols and APIs, including REST/HTTP, AMQP, MQTT, Websocket and JMS, gRPC etc. -* eventmesh-registry : automatically routes events between applications and services connected to seperate event meshers -* eventmesh-governance : governace layer for event producers and consumers -* eventmesh-acl : security at various level of authentication, authorization and topic/channel access control -* eventmesh-store : the store layer of Event-Mesh which implemented with [DeFiBus](https://github.com/WeBankFinTech/DeFiBus)(based on RocketMQ in financial scenario) or RocketMQ by default. We wish the store layeris a general solution and can use any store implement such as kafka, redis ,blockchain etc. -## Quick Start -Coming soon... +# Apache EventMesh (Incubating) + +**Apache EventMesh (Incubating)** is a dynamic [event-driven](https://en.wikipedia.org/wiki/Event-driven_architecture) application multi-runtime used to decouple the application and backend middleware layer, which supports a wide range of use cases that encompass complex multi-cloud, widely distributed topologies using diverse technology stacks. + +## Features + +### Multi-Runtime Architecture + +![EventMesh Architecture](docs/images/eventmesh-architecture.png) + +### Orchestration + +![EventMesh Orchestration](docs/images/eventmesh-orchestration.png) + +### Data Mesh + +![EventMesh Data Mesh](docs/images/eventmesh-bridge.png) + +## Components + +Apache EventMesh (Incubating) consists of multiple components that integrate different middlewares and messaging protocols to enhance the functionalities of the application runtime. + +- **eventmesh-runtime**: The middleware that transmits events between producers and consumers, which supports cloud-native apps and microservices. +- **eventmesh-sdk-java**: The Java SDK that supports HTTP, TCP, and [gRPC](https://grpc.io) protocols. +- **eventmesh-sdk-go**: The Golang SDK that supports HTTP, TCP, and [gRPC](https://grpc.io) protocols. +- **eventmesh-connector-plugin**: The collection of plugins that connects middlewares such as [Apache RocketMQ](https://rocketmq.apache.org) (implemented) [Apache Kafka](https://kafka.apache.org) (in progress), [Apache Pulsar](https://pulsar.apache.org/) (in progress), and [Redis](https://redis.io) (in progress). +- **eventmesh-registry-plugin**: The collection of plugins that integrate service registries such as [Nacos](https://nacos.io) and [etcd](https://etcd.io). +- **eventmesh-security-plugin**: The collection of plugins that implement security mechanisms, such as ACL (access control list), authentication, and authorization. +- **eventmesh-protocol-plugin**: The collection of plugins that implement messaging protocols, such as [CloudEvents](https://cloudevents.io) and [MQTT](https://mqtt.org). +- **eventmesh-admin**: The control plane that manages clients, topics, and subscriptions. + +## Downloads + +Please go to the [release page](https://eventmesh.apache.org/download) to get the release of Apache EventMesh (Incubating). + +## Quick start +Here are the guidelines: + +[Step 1: Deploy eventmesh-store](docs/zh/instruction/01-store.md) + +[Step 2: Start eventmesh-runtime](docs/zh/instruction/02-runtime.md) + +[Step 3: Run our demos](docs/zh/instruction/03-demo.md) + +Besides, we also provide the docker-version guidelines for you if you prefer Docker: + +[Step 1: Deploy eventmesh-store using docker](docs/zh/instruction/01-store-with-docker.md) + +[Step 2: Start eventmesh-runtime using docker](docs/zh/instruction/02-runtime-with-docker.md) + +[Step 3: Run our demos](docs/zh/instruction/03-demo.md) ## Contributing -Contributions are always welcomed! Please see [CONTRIBUTING](CONTRIBUTING.md) for detailed guidelines. -You can start with the issues labeled with good first issue. +Each contributor has played an important role in promoting the robust development of Apache EventMesh (Incubating). We sincerely appreciate all contributors who have contributed code and documents. + +- [Contributing Guideline](https://github.com/apache/incubator-eventmesh/blob/master/docs/en/contribute/03-new-contributor-guidelines.md) +- [Good First Issues](https://github.com/apache/incubator-eventmesh/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) + +Here is the [List of Contributors](https://github.com/apache/incubator-eventmesh/graphs/contributors), thank you all! :) + + + + + + +## CNCF Landscape + +
+ + + + +Apache EventMesh (Incubating) enriches the CNCF Cloud Native Landscape. + +
## License -[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) Copyright (C) Apache Software Foundation -## Contacts +Apache EventMesh (Incubating) is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). + +## Community +|WeChat Assistant|WeChat Official Account|Slack| +|-|-|-| +|||[Join Slack Chat](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-1blhcbedu-9b7yvwAQcDs3fddZxnZXag)| +### Mailing List +|Name|Description|Subscribe|Unsubscribe|Archive +|-|-|-|-|-| +|Users|User discussion|[Subscribe](mailto:users-subscribe@eventmesh.incubator.apache.org)|[Unsubscribe](mailto:users-unsubscribe@eventmesh.incubator.apache.org)|[Mail Archives](https://lists.apache.org/list.html?users@eventmesh.apache.org)| +|Development|Development discussion (Design Documents, Issues, etc.)|[Subscribe](mailto:dev-subscribe@eventmesh.incubator.apache.org)|[Unsubscribe](mailto:dev-unsubscribe@eventmesh.incubator.apache.org)|[Mail Archives](https://lists.apache.org/list.html?dev@eventmesh.apache.org)| +|Commits|Commits to related repositories| [Subscribe](mailto:commits-subscribe@eventmesh.incubator.apache.org) |[Unsubscribe](mailto:commits-unsubscribe@eventmesh.incubator.apache.org) |[Mail Archives](https://lists.apache.org/list.html?commits@eventmesh.apache.org)| diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000000..8477f1816d --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,118 @@ +
+ +

+ +
+ +[![CI status](https://img.shields.io/github/workflow/status/apache/incubator-eventmesh/Continuous%20Integration?logo=github&style=for-the-badge)](https://github.com/apache/incubator-eventmesh/actions/workflows/ci.yml) +[![CodeCov](https://img.shields.io/codecov/c/gh/apache/incubator-eventmesh/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/apache/incubator-eventmesh) +[![Code Quality: Java](https://img.shields.io/lgtm/grade/java/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18&style=for-the-badge)](https://lgtm.com/projects/g/apache/incubator-eventmesh/context:java) +[![Total Alerts](https://img.shields.io/lgtm/alerts/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18&style=for-the-badge)](https://lgtm.com/projects/g/apache/incubator-eventmesh/alerts/) + +[![License](https://img.shields.io/github/license/apache/incubator-eventmesh?style=for-the-badge)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![GitHub Release](https://img.shields.io/github/v/release/apache/eventmesh?style=for-the-badge)](https://github.com/apache/incubator-eventmesh/releases) +[![Slack Status](https://img.shields.io/badge/slack-join_chat-blue.svg?logo=slack&style=for-the-badge)](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-16y1n77va-q~JepYy3RqpkygDYmQaQbw) + +[📦 文档 (英文)](https://eventmesh.apache.org/docs/introduction) | +[📔 例子](https://github.com/apache/incubator-eventmesh/tree/master/eventmesh-examples) | +[⚙️ 路线图](https://eventmesh.apache.org/docs/roadmap) | +[🌐 英文版](README.md) +
+ +# Apache EventMesh (Incubating) + +**Apache EventMesh (Incubating)** 是一个用于解耦应用和后端中间件层的的动态云原生 [事件驱动](https://en.wikipedia.org/wiki/Event-driven_architecture) 架构基础设施。它支持广泛的用例,包括复杂的混合云、使用了不同技术栈的分布式架构。 + +## 特性 + +### 多运行时微服务架构 + +![EventMesh Architecture](docs/images/eventmesh-architecture.png) + +### 编排 + +![EventMesh Orchestration](docs/images/eventmesh-orchestration.png) + +### 数据网格 + +![EventMesh Data Mesh](docs/images/eventmesh-bridge.png) + +## 组件 + +**Apache EventMesh (Incubating)** 由多个组件组成,这些组件集成了不同的中间件和消息传输协议,以增强应用程序运行时的功能。 + +- **eventmesh-runtime**: 在生产者和消费者之间传输事件的中间件,它支持云原生应用程序和微服务。 +- **eventmesh-sdk-java**: 支持 HTTP、TCP 和 [gRPC](https://grpc.io) 协议的 Java SDK。 +- **eventmesh-sdk-go**: 支持 HTTP、TCP 和 [gRPC](https://grpc.io) 协议的 Golang SDK。 +- **eventmesh-connector-plugin**: 连接 [Apache RocketMQ](https://rocketmq.apache.org)、 [Apache Kafka](https://kafka.apache.org)、[Apache Pulsar](https://pulsar.apache.org/) 和 [Redis](https://redis.io) 等中间件的插件集合。 +- **eventmesh-registry-plugin**: 集成服务注册表的插件集合,如 [Nacos](https://nacos.io) 和 [etcd](https://etcd.io)。 + +- **eventmesh-security-plugin**: 实现安全机制的插件的集合,如 ACL(访问控制列表)、认证和授权。 + +- **eventmesh-protocol-plugin**: 实现消息传递协议的插件集合,如 [CloudEvents](https://cloudevents.io) 和 [MQTT](https://mqtt.org)。 + +- **eventmesh-admin**: 客户端管理、主题管理、订阅管理和其他管理。 + +## 下载 + +你可以在这个页面 [release page](https://eventmesh.apache.org/download) 获取所有的历史发布版本。 + +## 快速开始指引 + +[Step 1: Deploy eventmesh-store](docs/zh/instruction/01-store.md) + +[Step 2: Start eventmesh-runtime](docs/zh/instruction/02-runtime.md) + +[Step 3: Run our demos](docs/zh/instruction/03-demo.md) + +除此之外,我们还提供了 Docker 版本的快速开始指引,方便您借助 Docker 来初探我们的项目: + +[Step 1: Deploy eventmesh-store using docker](docs/zh/instruction/01-store-with-docker.md) + +[Step 2: Start eventmesh-runtime using docker](docs/zh/instruction/02-runtime-with-docker.md) + +[Step 3: Run our demos](docs/zh/instruction/03-demo.md) + + + +## 贡献这个项目 + +每一名贡献者都在这个项目的发展上都是至关重要的。我们真诚地感谢所有对代码和文档的贡献者!想要尝试贡献的可以看看以下三个链接。 + +- [贡献准则](https://eventmesh.apache.org/docs/contribute/contribute) +- [值得新人尝试的 Issue](https://github.com/apache/incubator-eventmesh/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) + +这是项目的[贡献者名单](https://github.com/apache/incubator-eventmesh/graphs/contributors) +,感谢各位的大力支持 :) + + + + + +## CNCF Landscape + +
+ + + + +Apache EventMesh (Incubating) enriches the CNCF Cloud Native Landscape. +
+ +## 开源授权 + +Apache EventMesh (Incubating) is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). + +## 社区 + +|微信小助手|微信公众号|Slack| +|-|-|-| +|||[加入 Slack](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-16y1n77va-q~JepYy3RqpkygDYmQaQbw)| + +### 邮件名单 + +| 列表名称 | 描述 |订阅 |取消订阅|邮件列表存档 +| ---- | ---- |---- | ---- | ---- | +|用户 |用户支持与用户问题| [点击订阅](mailto:users-subscribe@eventmesh.incubator.apache.org) |[点击取消订阅](mailto:users-unsubscribe@eventmesh.incubator.apache.org) |[邮件列表存档](https://lists.apache.org/list.html?users@eventmesh.apache.org)| +|开发 |开发相关| [点击订阅](mailto:dev-subscribe@eventmesh.incubator.apache.org) |[点击取消订阅](mailto:dev-unsubscribe@eventmesh.incubator.apache.org) |[邮件列表存档](https://lists.apache.org/list.html?dev@eventmesh.apache.org)| +|Commits |所有与仓库相关的 commits 信息通知| [点击订阅](mailto:commits-subscribe@eventmesh.incubator.apache.org) |[点击取消订阅](mailto:commits-unsubscribe@eventmesh.incubator.apache.org) |[邮件列表存档](https://lists.apache.org/list.html?commits@eventmesh.apache.org)| diff --git a/build.gradle b/build.gradle index e69de29bb2..dedd041caf 100644 --- a/build.gradle +++ b/build.gradle @@ -0,0 +1,495 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 java.util.concurrent.TimeUnit + +buildscript { + repositories { + maven { + url "https://maven.aliyun.com/repository/public" + } + + maven { + url "https://plugins.gradle.org/m2/" + } + } + + dependencies { + classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:5.0.3" + classpath "io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE" + classpath "com.github.jk1:gradle-license-report:1.17" + } +} + +//Remove doclint warnings that pollute javadoc logs when building with java8 +if(JavaVersion.current().isJava8()){ + allprojects { + tasks.withType(Javadoc){ + options.addStringOption('xdoclint:none','-quiet') + } + } +} + +allprojects { + apply plugin: 'java' + apply plugin: "eclipse" + apply plugin: "idea" + apply plugin: "project-reports" + apply plugin: "maven-publish" + apply plugin: "com.github.spotbugs" + apply plugin: "project-reports" + apply plugin: "jacoco" + apply plugin: "pmd" + apply plugin: "java-library" + apply plugin: 'signing' + apply plugin: 'checkstyle' + + [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' + + compileJava.options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" + + clean.doFirst { + delete 'build' + delete 'dist' + delete 'out' + } + + checkstyle { + toolVersion = '9.0' + ignoreFailures = false + showViolations = true + maxWarnings = 0 + configFile = new File("${rootDir}/style/checkStyle.xml") + } + + checkstyleMain.exclude '**/org/apache/eventmesh/client/grpc/protos**' + + dependencies { + repositories { + maven { + url "https://maven.aliyun.com/repository/public" + } + } + testImplementation "junit:junit:4.13.2" + } +} + +task tar(type: Tar) { + archiveBaseName.set(project.name) + archiveVersion.set(project.version.toString()) + archiveExtension.set('tar.gz') + compression = Compression.GZIP + destinationDirectory = new File(projectDir, 'build') + into('/') { + from 'dist' + } +} + +task zip(type: Zip) { + archiveBaseName.set(project.name) + archiveVersion.set(project.version.toString()) + archiveExtension.set('zip') + destinationDirectory = new File(projectDir, 'build') + into('/') { + from 'dist' + } +} + +task installPlugin() { + if (!new File("${rootDir}/dist").exists()) { + return + } + String[] libJars = java.util.Optional.ofNullable(new File("${rootDir}/dist/lib").list()).orElseGet(() -> new String[0]) + getAllprojects().forEach(subProject -> { + var file = new File("${subProject.projectDir}/gradle.properties") + if (!file.exists()) { + return + } + var properties = new Properties() + properties.load(new FileInputStream(file)) + var pluginType = properties.getProperty("pluginType") + var pluginName = properties.getProperty("pluginName") + if (pluginType == null || pluginName == null) { + return + } + var pluginFile = new File("${rootDir}/dist/plugin/${pluginType}/${pluginName}") + if (pluginFile.exists()) { + return + } + pluginFile.mkdirs() + println String.format( + "install plugin, pluginType: %s, pluginInstanceName: %s, module: %s", pluginType, pluginName, subProject.getName() + ) + + copy { + into "${rootDir}/dist/plugin/${pluginType}/${pluginName}" + from "${subProject.getProjectDir()}/dist/apps" + } + copy { + into "${rootDir}/dist/plugin/${pluginType}/${pluginName}" + from "${subProject.getProjectDir()}/dist/lib/" + exclude(libJars) + } + copy { + into "${rootDir}/dist/conf" + from "${subProject.getProjectDir()}/dist/conf" + exclude 'META-INF' + } + }) +} + +task printProjects() { + getAllprojects().forEach(subProject -> { + if ("EventMesh".equals(subProject.getName())) { + return + } + println String.format("%s-%s.jar", subProject.getName(), subProject.getVersion()) + }) +} + +subprojects { + + apply plugin: "io.spring.dependency-management" + + sourceSets { + main { + java.srcDirs = ['src/main/java'] + } + + test { + java.srcDirs = ['src/test/java'] + } + } + + clean.doFirst { + delete 'build' + delete 'dist' + } + + jacoco { + toolVersion = "0.8.6" + } + + jacocoTestReport { + reports { + xml.enabled true + csv.enabled false + html.enabled false + } + } + + spotbugs { + ignoreFailures = true + showProgress = true + showStackTraces = true + effort = 'default' + reportsDir = file("$buildDir/reports/spotbugs") + projectName = rootProject.name + release = version + extraArgs = ['-nested:false'] + maxHeapSize = '256m' + + } + + spotbugsMain { + + reports { + xml.enabled = false + html { + enabled = true + destination = file("$buildDir/reports/spotbugs/main/spotbugs.html") + stylesheet = 'fancy-hist.xsl' + } + } + } + + spotbugsTest { + reports { + xml.enabled = false + html { + enabled = true + destination = file("$buildDir/reports/spotbugs/test/spotbugs.html") + stylesheet = 'fancy-hist.xsl' + } + } + } + + pmd { + consoleOutput = true + toolVersion = "6.23.0" + rulesMinimumPriority = 5 + ruleSets = ["category/java/errorprone.xml", "category/java/bestpractices.xml"] + ignoreFailures = true + } + + jar { + manifest { + attributes("Specification-Version": project.version, + "Specification-Vendor": "Apache", + "Specification-Title": project.name, + "Implementation-Version": project.version, + "Implementation-Vendor": "Apache", + "Implementation-Title": project.name, + "Build-Jdk": project.findProperty("jdk") + ) + } + } + + task dist(dependsOn: ['jar']) { + doFirst { + new File("${projectDir}/dist/bin").mkdirs() + new File("${projectDir}/dist/apps").mkdirs() + new File("${projectDir}/dist/conf").mkdirs() + new File("${projectDir}/dist/lib").mkdirs() + new File("${projectDir}/dist/licenses").mkdirs() + } + Set rootProject = ["eventmesh-admin", + "eventmesh-admin-rocketmq", + "eventmesh-common", + "eventmesh-connector-api", + "eventmesh-metrics-api", + "eventmesh-registry-api", + "eventmesh-trace-api", + "eventmesh-runtime", + "eventmesh-security-api", + "eventmesh-protocol-api", + "eventmesh-starter", + "eventmesh-spi", + "eventmesh-webhook-api", + "eventmesh-webhook-admin", + "eventmesh-webhook-receive" + ] + doLast { + copy { + into("${projectDir}/dist/apps") + from project.jar.getArchivePath() + } + copy { + into("${projectDir}/dist/lib") + from project.configurations.runtimeClasspath + } + copy { + into("${projectDir}/dist/bin") + from 'bin' + } + copy { + into("${projectDir}/dist/conf") + from 'conf', sourceSets.main.resources.srcDirs + setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE) + exclude 'META-INF' + } + if (rootProject.contains(project.name)) { + new File("${rootDir}/dist/apps").mkdirs() + new File("${rootDir}/dist/lib").mkdirs() + new File("${rootDir}/dist/bin").mkdirs() + new File("${rootDir}/dist/conf").mkdirs() + copy { + into("${rootDir}/dist/apps") + from "${projectDir}/dist/apps" + } + copy { + into "${rootDir}/dist/lib" + from "${projectDir}/dist/lib" + exclude "eventmesh-*" + } + copy { + into "${rootDir}/dist/bin" + from "${projectDir}/dist/bin" + } + copy { + into "${rootDir}/dist/conf" + from "${projectDir}/dist/conf" + } + } + copy { + into "${rootDir}/dist" + from "${rootDir}/tools/third-party-licenses" + } + } + } + + javadoc { + source = sourceSets.main.java + destinationDir = reporting.file("javadoc") + } + + task packageJavadoc(type: Jar, dependsOn: ['javadoc']) { + from project.javadoc.destinationDir + classifier = 'javadoc' + } + + task packageSources(type: Jar) { + from project.sourceSets.main.allSource + classifier = 'sources' // either here or in artifacts block + } + + artifacts { + archives jar + archives packageJavadoc + archives packageSources + } + + if (!Boolean.valueOf(signEnabled)) { + tasks.whenTaskAdded { task -> + if (task.name.contains("sign")) { + task.enabled = false + } + } + } + + repositories { + maven { url "https://maven.aliyun.com/repository/public" } + mavenCentral() + mavenLocal() + } + + configurations.all { + resolutionStrategy.cacheChangingModulesFor 0, TimeUnit.SECONDS + resolutionStrategy.cacheDynamicVersionsFor 0, TimeUnit.SECONDS + } + + publishing { + publications { + mavenJava(MavenPublication) { + from components.java + artifact packageSources + artifact packageJavadoc + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } + } + pom { + name = 'EventMesh' + description = 'Apache EventMesh' + url = 'https://github.com/apache/incubator-eventmesh' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'Apache EventMesh(incubating)' + name = 'Apache EventMesh(incubating) of ASF' + url = 'https://eventmesh.apache.org/' + } + } + scm { + connection = 'scm:git:git@github.com:apache/incubator-eventmesh.git' + developerConnection = 'scm:git:git@github.com:apache/incubator-eventmesh.git' + url = 'https://github.com/apache/incubator-eventmesh' + } + } + } + } + repositories { + maven { + def releasesRepoUrl = 'https://repository.apache.org/service/local/staging/deploy/maven2' + def snapshotsRepoUrl = 'https://repository.apache.org/content/repositories/snapshots/' + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + credentials { + username apacheUserName + password apachePassWord + } + + } + } + } + + signing { + sign publishing.publications.mavenJava + } + + dependencyManagement { + dependencies { + dependency "org.apache.commons:commons-lang3:3.6" + dependency "org.apache.commons:commons-collections4:4.1" + dependency "org.apache.commons:commons-text:1.9" + + + dependency "com.google.guava:guava:31.0.1-jre" + + dependency "org.slf4j:slf4j-api:1.7.30" + dependency "org.apache.logging.log4j:log4j-api:2.17.1" + dependency "org.apache.logging.log4j:log4j-core:2.17.1" + dependency "org.apache.logging.log4j:log4j-slf4j-impl:2.17.1" + + dependency "com.lmax:disruptor:3.4.2" + + dependency "com.fasterxml.jackson.core:jackson-databind:2.13.0" + dependency "com.fasterxml.jackson.core:jackson-core:2.13.0" + dependency "com.fasterxml.jackson.core:jackson-annotations:2.13.0" + + dependency "org.apache.httpcomponents:httpclient:4.5.13" + + dependency "io.netty:netty-all:4.1.73.Final" + + dependency 'io.dropwizard.metrics:metrics-core:4.1.0' + dependency "io.dropwizard.metrics:metrics-healthchecks:4.1.0" + dependency "io.dropwizard.metrics:metrics-annotation:4.1.0" + dependency "io.dropwizard.metrics:metrics-json:4.1.0" + + dependency 'io.opentelemetry:opentelemetry-api:1.3.0' + dependency 'io.opentelemetry:opentelemetry-sdk:1.3.0' + dependency 'io.opentelemetry:opentelemetry-sdk-metrics:1.3.0-alpha' + dependency 'io.opentelemetry:opentelemetry-exporter-prometheus:1.3.0-alpha' + dependency 'io.prometheus:simpleclient:0.8.1' + dependency 'io.prometheus:simpleclient_httpserver:0.8.1' + dependency 'io.opentelemetry:opentelemetry-exporter-zipkin:1.3.0' + dependency 'io.opentelemetry:opentelemetry-semconv:1.3.0-alpha' + + dependency "io.openmessaging:openmessaging-api:2.2.1-pubsub" + + dependency "com.h3xstream.findsecbugs:findsecbugs-plugin:1.11.0" + dependency "com.mebigfatguy.fb-contrib:fb-contrib:7.4.7" + + dependency "org.springframework.boot:spring-boot-starter-web:2.6.7" + dependency "io.openmessaging:registry-server:0.0.1" + + dependency "junit:junit:4.13.2" + dependency "com.github.stefanbirkner:system-rules:1.16.1" + dependency "org.assertj:assertj-core:2.6.0" + + dependency "org.mockito:mockito-core:3.8.0" + dependency "org.mockito:mockito-inline:3.8.0" + dependency "org.powermock:powermock-module-junit4:2.0.2" + dependency "org.powermock:powermock-api-mockito2:2.0.2" + + dependency "io.cloudevents:cloudevents-core:2.2.0" + dependency "io.cloudevents:cloudevents-json-jackson:2.2.0" + + dependency "io.grpc:grpc-protobuf:1.17.1" + dependency "io.grpc:grpc-stub:1.17.1" + dependency "io.grpc:grpc-netty:1.17.1" + dependency "io.grpc:grpc-netty-shaded:1.17.1" + + dependency "javax.annotation:javax.annotation-api:1.3.2" + + dependency "com.github.seancfoley:ipaddress:5.3.3" + dependency "com.google.code.gson:gson:2.8.2" + + dependency "org.yaml:snakeyaml:1.30" + dependency "org.javassist:javassist:3.24.0-GA" + + } + } +} diff --git a/docker/centos7-jdk8/Dockerfile b/docker/centos7-jdk8/Dockerfile new file mode 100644 index 0000000000..7d968413d5 --- /dev/null +++ b/docker/centos7-jdk8/Dockerfile @@ -0,0 +1,31 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +FROM docker.io/centos:7 + +MAINTAINER mikexue + +RUN yum update -y && yum install net-tools -y && yum install lrzsz -y && yum install vim -y +ADD jdk-8u281-linux-x64.tar.gz /usr/local/src/ +RUN ln -s /usr/local/src/jdk1.8.0_281/ /usr/local/jdk + +ENV JAVA_HOME /usr/local/jdk +ENV JRE_HOME $JAVA_HOME/jre +ENV CLASSPATH .:$JAVA_HOME/lib/:$JRE_HOME/lib/ +ENV PATH $PATH:$JAVA_HOME/bin diff --git a/docker/eventmesh/Dockerfile b/docker/eventmesh/Dockerfile new file mode 100644 index 0000000000..6ea5944d19 --- /dev/null +++ b/docker/eventmesh/Dockerfile @@ -0,0 +1,35 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +FROM centos7-jdk8:latest + +MAINTAINER mikexue mike_xwm@126.com + +WORKDIR /data +RUN mkdir /data/app +ADD EventMesh_1.3.0-release.tar.gz /data/app/eventmesh +WORKDIR /data/app/eventmesh/bin + +EXPOSE 10000 +EXPOSE 10105 + +ENV DOCKER true + +CMD sh start.sh + diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index c4192631f2..0000000000 --- a/docs/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-cayman \ No newline at end of file diff --git a/docs/cn/features/0-introduction.md b/docs/cn/features/0-introduction.md deleted file mode 100644 index 195054feb7..0000000000 --- a/docs/cn/features/0-introduction.md +++ /dev/null @@ -1,49 +0,0 @@ -# DeFiBus -       -**DeFiBus=RPC+MQ,是基于开源消息中间件打造的安全可靠的分布式金融级消息总线。DeFibus不仅提供了RPC同步调用,还提供了MQ的异步事件通知、事件组播和广播等常用服务调用和消息模式,同时增加了应用多中心多活、服务就近、灰度发布等分布式场景下的高可用能力。在对于机器故障的容错能力方面的增强,也让消息总线的服务更加稳定可靠,为业务提供7x24的服务。** - -### 整体架构 -
- -![architecture1](../../../docs/images/features/a-distributing-architecture-in-financial.png) - -
- -![architecture2](../../../docs/images/features/architecture-p1.png) - -DeFiBus主要包括以下几个组件(模块): - -* **Broker**:通过轻量的Topic和Queue机制提供消息存储功能。Broker定期将Topic信息上报到NameServer中,同集群中的Broker实例上报的NameServer必须保持一致,避免路由信息不一致。 - -* **NameServer**:NameServer提供Topic的发现和路由,每一个NameServer接受Broker上报的Topic信息,并维护Topic的路由信息供客户端查询。 - -* **GSL**:全局服务定位(Global Service Location)服务提供服务级别的路由发现。服务可以部署在不同的区域(比如不同的数据中心、逻辑分区等),服务请求方在请求某一个具体服务时,无需关注服务部署的区域,GSL能够根据服务发现规则自动定位到具体的服务,将服务信息返回给客户端。 - -* **SGS**:服务治理系统(Service Government System)负责全局的服务管理,包括服务的申请、服务部署规划、服务下线等服务全生命周期的管理。在DeFiBus中,服务与Topic一一对应,Topic的名称由对应的服务按照一定的规则来命名。Topic的创建、更新和删除由SGS统一管理。SGS在服务的部署区域对应的Broker集群中创建Topic之后,将更新全局服务路由数据,供GSL定位服务使用。 - -* **Proxy**:服务代理(Proxy)提供HTTP接入方式,同时允许按照协议规范开发的C、GO、Python等其他语言客户端的接入。 - -### 服务和Topic的定义 -       -DeFiBus把服务和Topic做了一一对应,每个服务必须对应一个Topic。Topic根据服务的唯一ID和服务的部署区域来命名。每个服务需要有服务的唯一标识,可以用数字ID或者字符串来表示。每个部署区域使用3位长度的字符串(限数字和字母构成)表示。 -Topic按照如下格式来命名: -``` -[区域代码]-[服务唯一ID] -``` - -比如,余额查询服务的服务ID为20190001表示,部署在“A10”这个区域,那么该服务在A10区域的Topic就命名为“A10-20190001”。Topic的命名规则 - - -### 特性列表: -* [RPC调用:即“Request-Reply”模式,支持系统间的同步调用](docs/cn/features/1-request-response-call.md) -* 消息发布/订阅:消息的发布和订阅 -* [灰度发布:服务级别的灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制:应用实例级别的熔断](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近:就近进行服务的请求和响应,减少跨区调用](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活:应用多中心多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列 :自适应应用实例数量,动态调整队列个数](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制:故障和错误隔离](docs/cn/features/8-fault-tolerant.md) -* 服务路由和定位:动态路由及定位(后续开源) -* 服务代理:HTTP及多语言的代理(后续开源) -* 服务治理:服务元数据的管理(后续开源) -* 平滑升级:平滑升级、平滑扩容(后续开源) \ No newline at end of file diff --git a/docs/cn/features/1-request-response-call.md b/docs/cn/features/1-request-response-call.md deleted file mode 100644 index 1feabaf457..0000000000 --- a/docs/cn/features/1-request-response-call.md +++ /dev/null @@ -1,34 +0,0 @@ -## 1. Request-Reply同步调用 - -       -Request-Reply同步调用指的是请求方发出一条消息之后,需要响应方在消费完这条消息后回复一个响应结果。 - -
- -![RR](../../images/features/RR-call-p1.png) - -
- -整个调用过程包含了两个消息的产生和消费过程。 -**1.请求方产生请求消息,服务响应方消费这条请求消息** -       -请求方根据服务提供方的协议将请求内容设置到消息体中,并将消息发送到Broker上。服务响应方订阅相应的Topic,从Broker上获取到请求消息,并消费。 - -**2.服务响应方产生响应消息,请求方接收这条响应消息** -       -服务响应方收到请求消息后,执行相应的处理,并将请求结果设置到响应消息的消息体中,将响应消息发送到Broker上。请求方接收响应消息的方式采用的是Broker推送的形式,而不是由Producer订阅的方式,从而使得响应消息能够精准回到发出请求消息的实例上。 - -       -DeFiBus在每条请求消息中增加REPLY_TO属性来唯一标识每一个请求方实例。在创建响应消息时将REPLY_TO属性透传到响应消息中。Broker收到响应消息后,根据REPLY_TO属性,查找出对应的请求方实例的连接,将响应消息推送给该请求方实例。 - - ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) \ No newline at end of file diff --git a/docs/cn/features/10-flow-control.md b/docs/cn/features/10-flow-control.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/cn/features/2-dark-launch.md b/docs/cn/features/2-dark-launch.md deleted file mode 100644 index e6e7e20119..0000000000 --- a/docs/cn/features/2-dark-launch.md +++ /dev/null @@ -1,24 +0,0 @@ -## 2.灰度发布 - -       -同一个消费组中的消费者实例通常订阅的Topic是相同的。在有新业务上线时,我们希望仅仅在个别实例上进行灰度,验证通过之后再进行全量。DeFiBus提供了灰度发布的能力,同一个消费组中,允许不同消费者实例订阅不同的Topic,只有订阅了某个具体Topic的实例才能够收到这个Topic的消息,同消费组中没有订阅这个Topic的实例不会收到消息。 - -       -假设一个消费组有3个消费者实例,上线初期只涉及到Topic1和Topic2。当业务扩展,需要增加Topic3的订阅时,可以先灰度其中一个实例,验证Topic3在灰度实例上执行正常之后,逐步再替换其他实例。在这期间,实例1和实例2不会收到Topic3的消息。 - -
- -![avater](../../images/features/dark-launch-p1.png) - -
- ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) \ No newline at end of file diff --git a/docs/cn/features/3-circuit-break-mechanism.md b/docs/cn/features/3-circuit-break-mechanism.md deleted file mode 100644 index 06eec22ae3..0000000000 --- a/docs/cn/features/3-circuit-break-mechanism.md +++ /dev/null @@ -1,25 +0,0 @@ -## 3.熔断 -       -DeFiBus基于队列来做消费端的负载均衡,对同一个消费组,除广播模式外,每个队列只由一个消费者实例消费。当一个实例处理能力下降或者异常出现消息堆积时,为了避免堆积情况继续加剧,DeFiBus会触发队列的熔断,此时生产者实例在感知到队列熔断之后,会优先把消息发送到其他没有熔断的队列上,暂停往熔断队列上写入新消息。当堆积消除后,熔断被解除,生产者恢复往该队列发送消息。 - -       -DeFiBus对每个Topic定义了深度的属性,表示Topic的队列允许堆积的最大消息条数。消息堆积数表示队列中尚未下发给消费者实例的消息条数,可由队列中最新一条消息的offset与消费者实例已经获取到的消息的offset的差值计算。 -
- -![offset](../../../docs/images/features/circuit-break-p1.png) - -
- -       -当Consumer出现异常或者触发了流控,Consumer拉消息过程受阻,队列的DeliverOffset停止不前,新消息持续写入,MaxOffset不断变大,最终MaxOffset与DeliverOffset将超过Topic的最大深度限制,触发队列熔断。 - ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) diff --git a/docs/cn/features/4-invoke-service-nearby.md b/docs/cn/features/4-invoke-service-nearby.md deleted file mode 100644 index 209940cbfd..0000000000 --- a/docs/cn/features/4-invoke-service-nearby.md +++ /dev/null @@ -1,29 +0,0 @@ -## 4.服务就近 -       -为了保证高可用,服务的部署通常分布在多个机房、区域。我们希望服务之间能够就近调用,减少跨机房跨区域网络访问的时延问题。对此,DeFiBus在Broker和客户端上都增加了区域的属性来标识实例属于哪个区域。对于Producer,消息会优先发往同区域内的Broker集群上;对于Consumer,则优先监听同区域内的Queue;当一个区域内没有Consumer实例监听时,则由其他区域的Consumer实例跨区域监听。 - -### 就近发送 -       -在创建Producer时,通过设置```DeFiBusClientConfig.setClusterPrefix("your region")```来标识Producer实例所在的区域。Producer在每次发送消息会先选则一个Queue来作为发送的目标队列。当启用就近发送时,Producer优先选择与自己同区域内的Queue,当本区域内没有可用Queue时,则选择其他区域的Queue。 -
- -
- -### 就近监听 -       -就近监听指的是Consumer在做负载均衡分配Queue的时候,每个区域内的Queue只由该区域内的Consumer监听和消费,当且仅当一个区域内没有订阅该Topic的Consumer时,由其他区域订阅了该Topic的Consumer跨区域监听和消费这些Queue。虽然Consumer是在同区域内就近消费,但仍通过心跳维持跨区域的连接,以保证能够随时跨区域接管消费。 - -
- -
- ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) \ No newline at end of file diff --git a/docs/cn/features/5-multi-active.md b/docs/cn/features/5-multi-active.md deleted file mode 100644 index f24366630b..0000000000 --- a/docs/cn/features/5-multi-active.md +++ /dev/null @@ -1,18 +0,0 @@ -## 5.同城多中心多活 -       -同城多中心多活指的是应用的多活,在DeFiBus集群正常运行的情况下,应用部署在多个数据中心,一个数据中心的应用实例全部挂掉后,DeFiBus能够自动将应用流量切换到另一个数据中心的应用实例上,保证应用能够持续稳定地提供服务而不中断。同城多中心多活得益于DeFiBus的服务就近特性,结合应用部署的规划,使得正常情况下服务调用发生在同一个数据中心,当一个中心的应用出现故障时,能够有其他中心的实例接管服务。 - -
- -
- ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) \ No newline at end of file diff --git a/docs/cn/features/6-dynamic-adjust-queue.md b/docs/cn/features/6-dynamic-adjust-queue.md deleted file mode 100644 index 9c27b7deb1..0000000000 --- a/docs/cn/features/6-dynamic-adjust-queue.md +++ /dev/null @@ -1,35 +0,0 @@ -## 自动伸缩Queue -       -在同一个消费组内,每个队列只由一个实例消费。当队列数小于消费者实例数时,会有部分消费者实例分不到队列;反之,当队列数大于消费者实例数时,每个消费者需要消费多个队列。队列数不是消费者实例数的整数倍时,则会出现部分实例需要消费比同组内的其他实例更多的队列,出现负载不均衡问题。 - -       -DeFiBus提供了队列数量自动调整的特性。当有Consumer新注册或者去注册时,Broker触发队列的自动伸缩,根据当前在线的消费者实例个数,增加或者减少队列个数,使队列个数与消费者实例数保持一致。 - -       -当队列数需要增加时,首先调整Topic的ReadQueueNum,将可读的队列数扩增;10s之后,再调整Topic的WriteQueueNum,将可写的队列数扩增。这样使得新扩增的队列能够先被消费者感知并监听上,然后才让生产者感知到,往新队列上发送消息,是扩增操作更平滑。 - -
- -
- -       -当队列数需要减少时,首先调整Topic的WriteQueueNum,将可写的队列数缩减;5分钟(默认,可配置)后先检查即将被缩减的队列中是否有消息没有被消费完,如果有,则继续延迟缩减操作,使消费者能够继续消费完队列中的消息;如果没有,则调整ReadQueueNum,将可写的队列数缩减。 - -
- -
- -       -对于多个消费组订阅相同Topic并且是集群消费模式时,在计算扩缩的队列个数时,以最大的消费组的消费者实例数为准,保证拥有最多实例数的消费组内每个消费者实例都能够分到Queue进行消费。 - - ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) \ No newline at end of file diff --git a/docs/cn/features/7-isolation-mechanism.md b/docs/cn/features/7-isolation-mechanism.md deleted file mode 100644 index 298efc461d..0000000000 --- a/docs/cn/features/7-isolation-mechanism.md +++ /dev/null @@ -1,23 +0,0 @@ -## 隔离机制 -Producer在往Topic发送消息时,会按照MessageQueueSelector定义的选择策略,从Topic的所有MessageQueue中选择一个作为目标队列发送消息。 -当队列发生熔断,或者Broker故障导致队列发送消息异常时,如果没有对这些队列进行特殊处理,下次再轮到发这个队列的时候仍然可能失败。 - -DeFiBus提供异常队列的隔离机制,当往某个队列发送消息失败时,将队列标记为隔离状态,在隔离过期之前将不再往这个队列发送消息,避免再次失败,降低失败概率。 - -异常队列隔离机制分为两步: -**-发现并标记队列为隔离** -在发送回调中更新发送队列的健康状态,如果执行的是onSuccess分支,则标记队列为健康,去除队列的隔离标记;如果执行的是onException分支,则标记队列为隔离状态。 - -**-不选择隔离中的队列发送消息** -在MessageQueueSelector中实现隔离机制的过滤逻辑,每次进行队列的选择时,优先从没有标记为隔离的队列中选择。当所有队列都被标记为隔离时,则从所有队列中选择,保证每次都要选出一个队列。 - ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) \ No newline at end of file diff --git a/docs/cn/features/8-fault-tolerant.md b/docs/cn/features/8-fault-tolerant.md deleted file mode 100644 index f118c9d311..0000000000 --- a/docs/cn/features/8-fault-tolerant.md +++ /dev/null @@ -1,50 +0,0 @@ -## 8.容错机制 -       -在金融场景下,对可用性和稳定性的要求非常高,中间件对机器故障、网络故障、应用故障以及中间件本身的故障等常见故障场景需要有容错能力,降低故障带来的影响。 - -### 隔离机制 -##### 1. Producer端的隔离 -       -Producer在往Topic发送消息时,会按照MessageQueueSelector定义的选择策略,从Topic的所有MessageQueue中选择一个作为目标队列发送消息。 -当队列发生熔断,或者Broker故障导致队列发送消息异常时,如果没有对这些队列进行特殊处理,下次再轮到发这个队列的时候仍然可能失败。 - -       -DeFiBus提供异常队列的隔离机制,当往某个队列发送消息失败时,将队列标记为隔离状态,在隔离过期之前将不再往这个队列发送消息,避免再次失败,降低失败概率。 - -异常队列隔离机制分为两步: -**-发现并标记队列为隔离** -       -在发送回调中更新发送队列的健康状态,如果执行的是onSuccess分支,则标记队列为健康,去除队列的隔离标记;如果执行的是onException分支,则标记队列为隔离状态。 - -**-不选择隔离中的队列发送消息** -       -在MessageQueueSelector中实现隔离机制的过滤逻辑,每次进行队列的选择时,优先从没有标记为隔离的队列中选择。当所有队列都被标记为隔离时,则从所有队列中选择,保证每次都要选出一个队列。 - - -##### 2. Consumer端的隔离 - -       -Consumer由拉消息线程只负责把拉消息请求以异步发送的形式发送出去。在正常情况下,每次拉消息请求的执行都很快,不会有卡顿。一旦有Broker故障导致PullRequest的执行发生了卡顿,则该Consumer监听的所有Queue都会因为PullRequest执行的延迟而出现消息消费延迟。对于RR同步请求的场景,这种是不能够接受的。 - -       -创建连接采用的是同步建立连接的策略,线程执行创建新连接时必须等待连接创建完成或者连接超时。当有Broker故障连不上时,就算是异步发送,也会因为同步等待连接建立而阻塞。此时就会出现一个Broker的故障导致其他健康Broker的消息消费出现延迟。 - -       -DeFiBus在Consumer拉消息的过程中增加了对拉消息任务的隔离,此处的隔离指的是将疑似有问题的任务隔离到另外的线程中执行,保证拉消息线程能够正常处理其他正常的任务。当发现执行拉消息耗时超过设定的阈值时,将该拉消息任务对应的Broker列入“隔离名单”中,在隔离过期之前,隔离Broker的拉消息请求都转交给另外线程执行,避免阻塞拉消息主线程,从而避免故障的Broker影响健康Broker的消息消费时效。 - -### 连接空闲机制 - -       -当连接的读或者写空闲超过60秒时,将主动断开连接。 - - ---- -#### Links: -* [架构介绍](../../../README.md) -* [Request-Reply调用](docs/cn/features/1-request-response-call.md) -* [灰度发布](docs/cn/features/2-dark-launch.md) -* [熔断机制](docs/cn/features/3-circuit-break-mechanism.md) -* [服务就近](docs/cn/features/4-invoke-service-nearby.md) -* [应用多活](docs/cn/features/5-multi-active.md) -* [动态扩缩队列](docs/cn/features/6-dynamic-adjust-queue.md) -* [容错机制](docs/cn/features/8-fault-tolerant.md) \ No newline at end of file diff --git a/docs/cn/features/9-publish-type.md b/docs/cn/features/9-publish-type.md deleted file mode 100644 index 74c3446d77..0000000000 --- a/docs/cn/features/9-publish-type.md +++ /dev/null @@ -1,35 +0,0 @@ -## 2. 单播、多播、广播 - -       -DeFiBus支持单播、多播、广播消费模式。 - -### 单播 - -
- -![unicast](../../images/features/unicast.png) - -
- -单播模式下,topic只被一个消费组监听;接收消息时,消费组内有且仅有一个实例会收到消息。 - -### 多播 - -
- -![multicast](../../images/features/multicast.png) - -
- -多播模式下,topic被多个消费组监听;接收消息时,每个消费组内有且仅有一个实例会收到消息。 - - -### 广播 - -
- -![broadcast](../../images/features/broadcast.png) - -
- -广播模式下,监听此topic的每个消费组中的每个实例都需要收到消息。 \ No newline at end of file diff --git a/docs/cn/quickstart.md b/docs/cn/quickstart.md deleted file mode 100644 index bcff7fc088..0000000000 --- a/docs/cn/quickstart.md +++ /dev/null @@ -1,36 +0,0 @@ -# Quick start Instarction - -### dependencies -``` -64bit OS, Linux/Unix/Mac is recommended; -64bit JDK 1.8+; -Gradle 3.x; -4g+ free disk for Broker server -``` - -### download and build - -``` -download from git -unzip defibus-master.zip -cd defibus-master -gradle clean dist tar -x test - -You can get a tar.gz package in directory named 'build' -``` - -### Deployment - -deploy DeFiBusNamesrv -``` -tar -zxvf DeFiBus_1.0.0.tar.gz -cd bin -sh runnamesrv.sh -``` - -deploy DeFiBusBroker -``` -tar -zxvf DeFiBus_1.0.0.tar.gz -cd bin -sh runbroker.sh -``` diff --git a/docs/en/contribute/01-release.md b/docs/en/contribute/01-release.md new file mode 100644 index 0000000000..0810a75772 --- /dev/null +++ b/docs/en/contribute/01-release.md @@ -0,0 +1,731 @@ +# Release Creation Process + +:::caution +The documentation of Release Creation Process is WIP (Work-in-Progress). +::: + +## 理解 Apache 发布的内容和流程 + +Source Release 是 Apache 关注的重点,也是发布的必须内容;而 Binary Release 是可选项, + +请参考以下链接,找到更多关于 ASF 的发布指南: + +- [Apache Release Guide](http://www.apache.org/dev/release-publishing) +- [Apache Release Policy](http://www.apache.org/dev/release.html) +- [Maven Release Info](http://www.apache.org/dev/publishing-maven-artifacts.html) + + +## 本地构建环境准备 + +主要包括签名工具、Maven 仓库认证相关准备 + +### 1.安装GPG + +在[GnuPG官网](https://www.gnupg.org/download/index.html)下载安装包。GnuPG的1.x版本和2.x版本的命令有细微差别,下列说明以**GnuPG-2.x**版本为例 + +```sh +$ gpg --version #检查版本,应该为2.x +``` + +### 2.用gpg生成key + +根据提示,生成 key + +> 注意:请使用Apache邮箱生成GPG的Key + +```shell +$ gpg --full-gen-key +gpg (GnuPG) 2.0.12; Copyright (C) 2009 Free Software Foundation, Inc. +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Please select what kind of key you want: + (1) RSA and RSA (default) + (2) DSA and Elgamal + (3) DSA (sign only) + (4) RSA (sign only) +Your selection? 1 +RSA keys may be between 1024 and 4096 bits long. +What keysize do you want? (2048) 4096 +Requested keysize is 4096 bits +Please specify how long the key should be valid. + 0 = key does not expire + = key expires in n days + w = key expires in n weeks + m = key expires in n months + y = key expires in n years +Key is valid for? (0) +Key does not expire at all +Is this correct? (y/N) y + +GnuPG needs to construct a user ID to identify your key. + +Real name: ${输入用户名} +Email address: ${邮箱地址} +Comment: CODE SIGNING KEY +You selected this USER-ID: + "${输入用户名} (CODE SIGNING KEY) <${邮箱地址}>" + +Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O +You need a Passphrase to protect your secret key. # 填入密码,以后打包过程中会经常用到 +``` + +### 3.查看 key + +```shell +$ gpg --list-keys +pub rsa4096/579C25F5 2021-04-26 # 579C25F5就是key id +uid [ultimate] ${输入用户名} <${邮箱地址}> +sub rsa4096 2021-04-26 + +# 通过key id发送public key到keyserver +$ gpg --keyserver pgpkeys.mit.edu --send-key 579C25F5 +# 其中,pgpkeys.mit.edu为随意挑选的keyserver,keyserver列表为:https://sks-keyservers.net/status/,相互之间是自动同步的,选任意一个都可以。 +$ gpg --keyserver hkp://pgpkeys.mit.edu --recv-keys 579C25F5 # 验证是否同步到公网,网络不好可能需多试几次 +``` + +**注:如果有多个 public key,设置默认 key。**修改`~/.gnupg/gpg.conf` + +```sh +# If you have more than 1 secret key in your keyring, you may want to +# uncomment the following option and set your preferred keyid. +default-key 28681CB1 +``` + +**如果有多个 public key, 也可以删除无用的 key:** + +```shell +$ gpg --delete-secret-keys 29BBC3CB # 先删除私钥,指明key id +gpg (GnuPG) 2.2.27; Copyright (C) 2021 g10 Code GmbH +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +sec rsa4096/EE8DAE7D29BBC3CB 2021-04-27 mikexue + +Delete this key from the keyring? (y/N) y +This is a secret key! - really delete? (y/N) y +``` + +```shell +$ gpg --delete-keys 29BBC3CB # 删除公钥,指明key id +gpg (GnuPG) 2.2.27; Copyright (C) 2021 g10 Code GmbH +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + + +pub rsa4096/EE8DAE7D29BBC3CB 2021-04-27 mikexue + +Delete this key from the keyring? (y/N) y +``` + +由于公钥服务器没有检查机制,任何人都可以用你的名义上传公钥,所以没有办法保证服务器上的公钥的可靠性。 通常,你可以在网站上公布一个公钥指纹,让其他人核对下载到的公钥是否为真。 + +```shell +# fingerprint参数生成公钥指纹: +$gpg --fingerprint mikexue +pub rsa4096 2021-04-26 [SCA] + F84A 0041 D70B 37AF 9C7B F0B3 39F4 29D7 579C 25F5 +uid [ultimate] mikexue +sub rsa4096 2021-04-26 [E] +``` + +登录 [https://id.apache.org](https://id.apache.org/), 将上面的 fingerprint (即 F84A 0041 D70B 37AF 9C7B F0B3 39F4 29D7 579C 25F5) 粘贴到自己的用户信息中 OpenPGP Public Key Primary Fingerprint + + + +## 发布Apache Maven仓库 + +> 注:EventMesh使用Gradle构建,需修改gradle相关配置 + +### 1.导出私钥文件 + +```shell +$ gpg --export-secret-keys -o secring.gpg #私钥文件妥善保管,后面配置需要 +``` + +### 2.准备分支 + +从主干分支拉取新分支作为发布分支,如现在要发布$`{release_version}`版本,则从develop分支拉出新分支`${release_version}-release`,此后`${release_version}` Release Candidates涉及的修改及打标签等都在`${release_version}-release`分支进行,最终发布完成后合入主干分支。 + +### 3.更新版本说明 + +更新官网项目的如下文件,并提交至master分支: + +https://github.com/apache/incubator-eventmesh-site/tree/master/events/release-notes + +### 4.配置根项目下gradle.properties文件 + +```shell +group=org.apache.eventmesh +version=1.2.0-release +#40位公钥的最后8位 +signing.keyId=579C25F5 +#生成密钥时填的passphrase +signing.password= +#导出的私钥文件secring.gpg路径 +signing.secretKeyRingFile=../secring.gpg +#apache 账号 +apacheUserName= +#apache 密码 +apachePassWord= +``` + +### 5.检查子模块下gradle.properties文件 + +```shell +group=org.apache.eventmesh +version=${release_version} +``` + +### 6.检查并配置根项目下build.gradle文件 + +```shell +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + artifact packageSources + artifact packageJavadoc + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } + } + pom { + name = 'EventMesh' + description = 'Apache EventMesh' + url = 'https://github.com/apache/incubator-eventmesh' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'Apache EventMesh(incubating)' + name = 'Apache EventMesh(incubating) of ASF' + url = 'https://eventmesh.apache.org/' + } + } + scm { + connection = 'scm:git:git@github.com:apache/incubator-eventmesh.git' + developerConnection = 'scm:git:git@github.com:apache/incubator-eventmesh.git' + url = 'https://github.com/apache/incubator-eventmesh' + } + } + } + } + repositories { + maven { + def releasesRepoUrl = 'https://repository.apache.org/service/local/staging/deploy/maven2/' + def snapshotsRepoUrl = 'https://repository.apache.org/content/repositories/snapshots/' + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + credentials { + username apacheUserName + password apachePassWord + } + + } + } +} + +signing { + sign publishing.publications.mavenJava +} +``` + +### 7.上传发布包 + +执行如下命令,需要对jar、源码包、doc和pom等文件签名加密 + +```shell +$ gradle signMavenJavaPublication publish +``` + +上述命令执行成功后,待发布版本会自动上传到Apache的临时筹备仓库(staging repository)。所有被deploy到远程[maven仓库](http://repository.apache.org/)的Artifacts都会处于staging状态,访问https://repository.apache.org/#stagingRepositories, 使用Apache的LDAP账户登录后,就会看到上传的版本,`Repository`列的内容即为${STAGING.REPOSITORY}。 点击`Close`来告诉Nexus这个构建已经完成,只有这样该版本才是可用的。 如果电子签名等出现问题,`Close`会失败,可以通过`Activity`查看失败信息。 + + + +## 发布Apache SVN仓库 + +### 1.准备svn本机环境(Apache使用svn托管项目的发布内容) + +### 2.checkout到本地目录 + +```shell +$ svn checkout https://dist.apache.org/repos/dist/dev/incubator/eventmesh/ +# 假定本地目录为 ~/apache/eventmesh +``` + +### 3.添加gpg公钥 + +添加public key到[KEYS](https://dist.apache.org/repos/dist/dev/incubator/eventmesh/KEYS)文件并提交到SVN仓库(第一次做发布的人需要做这个操作,具体操作参考KEYS文件里的说明)。KEYS主要是让参与投票的人在本地导入,用来校验sign的正确性 + +Windows + +```sh +$ gpg --list-sigs | out-file -append KEYS -encoding utf8 +$ gpg --armor --export | out-file -append KEYS -encoding utf8 +``` + +> Mac OS/Linux + +```sh +$ (gpg --list-sigs && gpg --armor --export ) >> KEYS +``` + +### 4.添加待发布内容到SVN目录 + +```shell +$ cd ~/apache/eventmesh # eventmesh svn根目录 +$ mkdir ${release_version}-${rc_version} +``` + +#### 4.1 创建tag + +在`${release_version}-release`分支上创建tag,需带有rc版本,为预发布版本 + +```shell +$ git tag -a v{$release_version}-{$rc_version} -m "Tagging the ${release_version} first Release Candidate (Candidates start at zero)" +$ git push origin --tags +``` + +#### 4.2 打包源码 + +检查项目源码命名,将源码命名为`apache-eventmesh-${release_version}-incubating-src`,将源码打包为tar.gz格式 + +```shell +$ tar -czvf apache-eventmesh-${release_version}-incubating-source.tar.gz apache-eventmesh-${release_version}-incubating-src +``` + +#### 4.3 打包二进制 + +> 编译上一步打包的源码 + +检查编译后的文件命名,将二进制文件命名为`apache-eventmesh-${release_version}-incubating` + +> 注:需将源码根目录下的`NOTICE`文件,`DISCLAIMER-WIP`文件以及`tools/third-party-licenses`目录下的`LICENSE`文件拷贝到二进制的包中 + +```shell +$ gradle clean jar dist && gradle installPlugin && gradle tar -x test +$ tar -czvf apache-eventmesh-${release_version}-incubating-bin.tar.gz apache-eventmesh-${release_version}-incubating +``` + +压缩source包、bin包,并将相关的压缩包拷贝到svn本地仓库下`/apache/eventmesh/${release_version}-${rc_version}` + +### 5.生成签名/sha512文件 + +> 针对源码包与二进制包生成签名/sha512文件 + +```shell +$ for i in *.tar.gz; do echo $i; gpg --print-md SHA512 $i > $i.sha512 ; done #计算sha512 +$ for i in *.tar.gz; do echo $i; gpg --armor --output $i.asc --detach-sig $i ; done #计算签名 +``` + +### 6.提交到Apache svn + +```shell +$ cd ~/apache/eventmesh # eventmesh svn根目录 +$ svn status +$ svn commit -m 'prepare for ${release_version}-${rc_version}' +``` + + + +## 验证Release Candidates + +详细检查列表请参考官方的[check list](https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist) + +从以下地址下载要发布的Release Candidates到本地环境: + +```shell +https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version}/ +``` + +然后开始验证环节,验证包含但不限于以下内容和形式 + +### 1.检查签名和hash等信息 + +> 由于操作系统不同,检查的命令或有差异,具体可参考[官方检查步骤](https://www.apache.org/info/verification.html) + +#### 1.1检查sha512哈希 + +> Mac OS/Linux + +```shell +$ shasum -a apache-eventmesh-${release_version}-incubating-source.tar.gz +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-source.tar.gz.sha512文件内容作对比 +$ shasum -a apache-eventmesh-${release_version}-incubating-bin.tar.gz +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-bin.tar.gz.sha512文件内容作对比 +``` + +> Windows + +```shell +$ certUtil -hashfile apache-eventmesh-${release_version}-incubating-source.tar.gz SHA512 +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-source.tar.gz.sha512文件内容作对比 +$ certUtil -hashfile apache-eventmesh-${release_version}-incubating-bin.tar.gz SHA512 +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-bin.tar.gz.sha512文件内容作对比 +``` + +#### 1.2检查gpg签名 + +首先导入发布人公钥。从svn仓库导入KEYS到本地环境。(发布版本的人不需要再导入,帮助做验证的人需要导入,用户名填发版人的即可) + +```shell +$ curl https://dist.apache.org/repos/dist/dev/incubator/eventmesh/KEYS >> KEYS +$ gpg --import KEYS +$ gpg --edit-key "${发布人的gpg用户名}" + > trust + +Please decide how far you trust this user to correctly verify other users' keys +(by looking at passports, checking fingerprints from different sources, etc.) + + 1 = I don't know or won't say + 2 = I do NOT trust + 3 = I trust marginally + 4 = I trust fully + 5 = I trust ultimately + m = back to the main menu + +Your decision? 5 + + > save +``` + +然后使用如下命令检查签名 + +```shell +$ gpg --verify apache-eventmesh-${release_version}-incubating-source.tar.gz.asc apache-eventmesh-${release_version}-incubating-source-tar.gz +$ gpg --verify apache-eventmesh-${release_version}-incubating-bin.tar.gz.asc apache-eventmesh-${release_version}-incubating-bin.tar.gz +``` + +### 2.检查源码包的文件内容 + +解压缩`apache-eventmesh-${release_version}-incubating-source-tar.gz`,进行如下检查: + +- 检查源码包是否包含由于包含不必要文件,致使tar包过于庞大 +- 文件夹包含单词`incubating` +- 存在`LICENSE`和`NOTICE`文件 +- 存在`DISCLAIMER`文件 +- `NOTICE`文件中的年份正确 +- 只存在文本文件,不存在二进制文件 +- 所有文件的开头都有ASF许可证 +- 能够正确编译,单元测试可以通过 (./gradle build) (目前支持JAVA 8/gradle 7.0/idea 2021.1.1及以上) +- 检查是否有多余文件或文件夹,例如空文件夹等 + +### 3.检查二进制包的文件内容 + +- 文件夹包含单词`incubating` +- 存在`LICENSE`和`NOTICE`文件 +- 存在`DISCLAIMER`文件 +- `NOTICE`文件中的年份正确 +- 所有文本文件开头都有ASF许可证 +- 检查第三方依赖许可证: + - 第三方依赖的许可证兼容 + - 所有第三方依赖的许可证都在`LICENSE`文件中声名 + - 依赖许可证的完整版全部在`license`目录 + - 如果依赖的是Apache许可证并且存在`NOTICE`文件,那么这些`NOTICE`文件也需要加入到版本的`NOTICE`文件中 + +你可以参考此文章:[ASF第三方许可证策](https://apache.org/legal/resolved.html) + +## 发起投票 + +> EventMesh 仍在孵化阶段,需要进行两次投票 + +- EventMesh社区投票,发送邮件至:`dev@eventmesh.apache.org` +- incubator社区投票,发送邮件至:`general@incubator.apache.org` EventMesh毕业后,只需要在EventMesh社区投票 + +### 1.EventMesh社区投票阶段 + +1. EventMesh社区投票,发起投票邮件到`dev@eventmesh.apache.org`。PMC需要先按照文档检查版本的正确性,然后再进行投票。 经过至少72小时并统计到3个`+1 PMC member`票后,即可进入下一阶段的投票。 +2. 宣布投票结果,发起投票结果邮件到`dev@eventmesh.apache.org`。 + +### 2.EventMesh社区投票模板 + +标题: + +``` +[VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +正文: + +``` +Hello EventMesh Community, + + This is a call for vote to release Apache EventMesh (incubating) version ${release_version}-${rc_version}. + + Release notes: + https://github.com/apache/incubator-eventmesh/releases/tag/v${release_version}-${rc_version} + + The release candidates: + https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version}/ + + Maven artifacts are available in a staging repository at: + https://repository.apache.org/content/repositories/orgapacheeventmesh-{staging-id} + + Git tag for the release: + https://github.com/apache/incubator-eventmesh/tree/v${release_version}-${rc_version} + + Keys to verify the Release Candidate: + https://downloads.apache.org/incubator/eventmesh/KEYS + + Hash for the release tag: + #hashCode of this release tag + + GPG user ID: + ${YOUR.GPG.USER.ID} + + The vote will be open for at least 72 hours or until necessary number of votes are reached. + + Please vote accordingly: + + [ ] +1 approve + + [ ] +0 no opinion + + [ ] -1 disapprove with the reason + + Checklist for reference: + + [ ] Download links are valid. + + [ ] Checksums and PGP signatures are valid. + + [ ] Source code distributions have correct names matching the current release. + + [ ] LICENSE and NOTICE files are correct for each EventMesh repo. + + [ ] All files have license headers if necessary. + + [ ] No compiled archives bundled in source archive. + + More detail checklist please refer: + https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist + +Thanks, +Your EventMesh Release Manager +``` + +### 3.宣布投票结果模板 + +标题: + +``` +[RESULT][VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +正文: + +``` +Hello Apache EventMesh PPMC and Community, + + The vote closes now as 72hr have passed. The vote PASSES with + + xx (+1 non-binding) votes from the PPMC, + xx (+1 binding) votes from the IPMC, + xx (+1 non-binding) votes from the rest of the developer community, + and no further 0 or -1 votes. + + The vote thread: {vote_mail_address} + + I will now bring the vote to general@incubator.apache.org to get approval by the IPMC. + If this vote passes also, the release is accepted and will be published. + +Thank you for your support. +Your EventMesh Release Manager +``` + +### 4.Incubator社区投票阶段 + +1. Incubator社区投票,发起投票邮件到`general@incubator.apache.org`,需3个 `+1 IPMC Member`投票,方可进入下一阶段。 +2. 宣布投票结果,发起投票结果邮件到`general@incubator.apache.org` 并抄送至`dev@eventmesh.apache.org`。 + +### 5.Incubator社区投票模板 + +标题: + +``` +[VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +内容: + +``` +Hello Incubator Community, + + This is a call for a vote to release Apache EventMesh(Incubating) version ${release_version} ${rc_version} + + The Apache EventMesh community has voted on and approved a proposal to release + Apache EventMesh(Incubating) version ${release_version} ${rc_version} + + We now kindly request the Incubator PMC members review and vote on this + incubator release. + + EventMesh community vote thread: + • [投票链接] + + Vote result thread: + • [投票结果链接] + + The release candidate: + •https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version}/ + + Git tag for the release: + • https://github.com/apache/incubator-eventmesh/tree/${release_version}-${rc_version} + Release notes: + • https://github.com/apache/incubator-eventmesh/releases/tag/${release_version}-${rc_version} + + The artifacts signed with PGP key [填写你个人的KEY], corresponding to [填写你个人的邮箱], that can be found in keys file: + • https://downloads.apache.org/incubator/eventmesh/KEYS + + The vote will be open for at least 72 hours or until necessary number of votes are reached. + + Please vote accordingly: + + [ ] +1 approve + [ ] +0 no opinion + [ ] -1 disapprove with the reason + +Thanks, +On behalf of Apache EventMesh(Incubating) community +``` + +### 6.宣布投票结果模板 + +标题: + +``` +[RESULT][VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +内容: + +``` +Hi all, + + Thanks for reviewing and voting for Apache EventMesh(Incubating) version ${release_version} ${rc_version} release, I am happy to announce the release voting has passed with [投票结果数] binding votes, no +0 or -1 votes. + + Binding votes are from IPMC + - xxx + - xxx + - xxx + + Non-binding votes: + +1 xxx + +0 xxx + -1 xxx + + The voting thread is: + • [投票结果链接] + + Many thanks for all our mentors helping us with the release procedure, and all IPMC helped us to review and vote for Apache EventMesh(Incubating) release. I will be working on publishing the artifacts soon. + +Thanks, +On behalf of Apache EventMesh(Incubating) community +``` + +## 正式发布 + +### 1.合并分支 + +合并`${release_version}-release`分支的改动到`master`分支,合并完成后删除`release`分支 + +```shell +$ git checkout master +$ git merge origin/${release_version}-release +$ git pull +$ git push origin master +$ git push --delete origin ${release_version}-release +$ git branch -d ${release_version}-release +``` + +### 2.迁移源码与二进制包 + +将源码和二进制包从svn的`dev`目录移动到`release`目录 + +```shell +$ svn mv https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version} https://dist.apache.org/repos/dist/release/incubator/eventmesh/ -m "transfer packages for ${release_version}-${rc_version}" #移动源码包与二进制包 +$ svn delete https://dist.apache.org/repos/dist/release/incubator/eventmesh/KEYS -m "delete KEYS" #清除原有release目录下的KEYS +$ svn cp https://dist.apache.org/repos/dist/dev/incubator/eventmesh/KEYS https://dist.apache.org/repos/dist/release/incubator/eventmesh/ -m "transfer KEYS for ${release_version}-${rc_version}" #拷贝dev目录KEYS到release目录 +``` + +### 3.确认dev和release下的包是否正确 + +- 确认[dev](https://dist.apache.org/repos/dist/dev/incubator/eventmesh/)下的`${release_version}-${rc_version}`已被删除 +- 删除[release](https://dist.apache.org/repos/dist/release/incubator/eventmesh/)目录下上一个版本的发布包,这些包会被自动保存在[这里](https://archive.apache.org/dist/incubator/eventmesh/) + +```shell +$ svn delete https://dist.apache.org/repos/dist/release/incubator/eventmesh/${last_release_version} -m "Delete ${last_release_version}" +``` + +### 4.在Apache Staging仓库发布版本 + +- 登录http://repository.apache.org , 使用Apache账号登录 +- 点击左侧的Staging repositories, +- 搜索EventMesh关键字,选择你最近上传的仓库,投票邮件中指定的仓库 +- 点击上方的`Release`按钮,这个过程会进行一系列检查 + +> 等仓库同步到其他数据源,一般需要24小时 + +### 5.GitHub版本发布 + +1.Tag the commit (on which the vote happened) with the release version without `-${RELEASE_CANDIDATE}`. 例如:after a successful vote on `v1.2-rc5`, the hash will be tagged again with `v1.2` only. + +2.在 [GitHub Releases](https://github.com/apache/incubator-eventmesh/releases) 页面的 `${release_version}` 版本上点击 `Edit` + +编辑版本号及版本说明,并点击 `Publish release` + +### 6.更新下载页面 + +等待并确认新的发布版本同步至 Apache 镜像后,更新如下页面: + +https://eventmesh.apache.org/download/ + +https://eventmesh.apache.org/zh/download/ + +GPG签名文件和哈希校验文件的下载连接应该使用这个前缀:`https://downloads.apache.org/incubator/eventmesh/` + +> 注意:项目下载链接应该使用 https://www.apache.org/dyn/closer.lua 而不是 closer.cgi 或者 mirrors.cgi + +### 7.邮件通知版本发布完成 + +> 请确保Apache Staging仓库已发布成功,一般是在该步骤的24小时后发布邮件 + +发邮件到 `dev@eventmesh.apache.org` 、 `announce@apache.org`和`general@incubator.apache.org` + +标题: + +``` +[ANNOUNCE] Apache EventMesh (incubating) ${release_version} available +``` + +正文: + +``` +Hi all, + +Apache EventMesh (incubating) Team is glad to announce the new release of Apache EventMesh (incubating) ${release_version}. + +Apache EventMesh (incubating) is a dynamic cloud-native eventing infrastructure used to decouple the application and backend middleware layer, which supports a wide range of use cases that encompass complex multi-cloud, widely distributed topologies using diverse technology stacks. + +Download Links: https://eventmesh.apache.org/projects/eventmesh/download/ + +Release Notes: https://eventmesh.apache.org/events/release-notes/v${release_version}/ + +Website: https://eventmesh.apache.org/ + +EventMesh Resources: +- Issue: https://github.com/apache/incubator-eventmesh/issues +- Mailing list: dev@eventmesh.apache.org + + + +Apache EventMesh (incubating) Team +``` + diff --git a/docs/en/contribute/02-write-unit-test.md b/docs/en/contribute/02-write-unit-test.md new file mode 100644 index 0000000000..0c48e46bc6 --- /dev/null +++ b/docs/en/contribute/02-write-unit-test.md @@ -0,0 +1,77 @@ +# Unit Test Requirement + +- Each unit test case should use assertions instead of `System.out` output or `if` statement +- Each unit test case shouldn't call other cases or depend on the order of execution. +- Each unit test case should be repeatable and not depend on the external environment because the test might be executed in the continuous integration. +- The scope of each unit test should be small enough to help locate the problem at the method level. + +## Location and Naming Rules + +- The unit test should be placed in `src/test/java`. +- The unit test configuration file should be placed in `src/test/resources`. For example: + - Class to be tested: `src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBody.java` + - Unit test: `src/test/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBodyTest.java` + - Unit test configuration: `src/test/resources/configuration.properties` +- The package name of the unit test class should be identical to the class to be tested. +- The name of the unit test class should be `{class or interface to be tested}Test`. For example: + - Class to be tested: `EventMeshUtil` + - Unit test class: `EventMeshUtilTest` +- The name of each test case should be `test{method name}`. For example: + - Method to be tested: `addProp(String key, String val)` + - Unit test case: `testAddProp` + +## Assertion Usage + +### Common Assertion + +| Methods | Instructions | +| :-------------- | :-------------- | +| `assertEquals` | Determines whether two objects or primitive types are equal | +| `assertNotEquals` | Determines whether two objects or primitive types are not equal | +| `assertTrue` | Determines whether the given Boolean value is `true` | +| `assertFalse` | Determines whether the given Boolean value is `false` | +| `assertNull` | Determines whether the given object reference is `null` | +| `assertNotNull` | Determines whether the given object reference is not `null` | +| `assertAll` | When multiple decision logic are processed together if only one error is reported, the whole test will fail | + +### Example + +#### `assertEquals()` + +```java +configuration.init(); +Assert.assertEquals("value1", configuration.eventMeshEnv); +``` + +#### `assertTrue()` + +```java +BaseResponseHeader header = BaseResponseHeader.buildHeader("200"); +Assert.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); +``` + +#### `assertFalse()` + +```java +Class nacosRegistryServiceClass = NacosRegistryService.class; +Field initStatus = nacosRegistryServiceClass.getDeclaredField("INIT_STATUS"); +initStatus.setAccessible(true); +Object initStatusField = initStatus.get(nacosRegistryService); +Assert.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); +``` + +#### `assertNull()` + +```java +DefaultFullHttpResponse response = httpCommand.httpResponse(); +Assert.assertNull(response); +``` + +#### `assertNotNull()` + +```java +Codec.Decoder cd = new Codec.Decoder(); +ArrayList result = new ArrayList<>(); +cd.decode(null, buf, result); +Assert.assertNotNull(result.get(0)); +``` diff --git a/docs/en/contribute/03-new-contributor-guidelines.md b/docs/en/contribute/03-new-contributor-guidelines.md new file mode 100644 index 0000000000..8c63375c35 --- /dev/null +++ b/docs/en/contribute/03-new-contributor-guidelines.md @@ -0,0 +1,145 @@ + +# How to Contribution + +If you are a new contributor who wants to contribute to the eventmesh community, please read this document, which describes how to contribute to the community, and if you find any questions in the document, feel free to leave comments or suggestions. + +## Preparation + +### Development environment + +- You should have the JDK installed in your development environment. + +### Code Style + +Import [EventMesh CheckStyle](https://github.com/apache/incubator-eventmesh/blob/master/style/checkStyle.xml) file to your IDEA. + +For IDEA, you can import check style file by: +```shell + Editor -> Code Style -> Java -> Scheme -> Import Scheme -> CheckStyle Configuration +``` + +If you can't see CheckStyle Configuration section under Import Scheme, you can install CheckStyle-IDEA plugin first, and you will see it. + +You can also use `./gradlew check` to check the code style. +(Note: this command will check all file in project, when you submit a pr, the ci will only check the file has been changed in this pr). + +### Workflow + +Here are the workflow for contributors: + +1. Fork to your own + +2. Clone fork to local repository +```git +git clone git@github.com:yourgithub/incubator-eventmesh.git +``` + +3. Create a new branch and work on it +```git +git checkout -b fix_patch_xx +``` + +4. Keep your branch in sync +```git +git remote add upstream git@github.com:apache/incubator-eventmesh.git +git fetch upstream develop:upstream_develop +git rebase upstream_develop +``` + +5. Commit your changes (make sure your commit message concise) + +6. Push your commits to your forked repository + +7. Create a pull request + +## Explanation + +The original warehouse: https://github.com/apache/incubator-eventmesh The apache warehouse of eventmesh is called the original warehouse in the text. + +The Fork library: From https://github.com/apache/eventmesh fork to your own personal repository to become a fork library. + +So fork the original EventMesh repository into your own repository. + +## Development branch + +**The current development branch of eventmesh is Master. Please submit PR to this branch.** + +- We recommend that you create a new branch in your repository for development and submit the branch to the master branch of eventmesh. + +## Contribution Categories + +### Bug feedback or bug fixes + +- Whether it's a bug feedback or a fix, an issue needs to be created first to describe the bug in detail, so that the community can easily find and view the problem and code through the issue record. bug feedback issues usually need to contain a complete description of the bug information and reproducible scenarios. + +### Implementation of functions, refactoring + +- If you plan to implement a new feature (or refactoring), be sure to communicate with the eventmesh core development team via an Issue or other means, and describe the new feature (or refactoring), mechanism and scenario in detail during the communication process. + +### Documentation Improvement + +- You can find the eventmesh documentation at [evenmesh-docs](https://github.com/apache/incubator-eventmesh/tree/master/docs), and the documentation is supplemented or improved in a way that is also essential for eventmesh. + +## Contribution method + +There are two ways for new contributors to contribute to the eventmesh community: + +- If you find a bug in the eventmesh code that you want to fix, or if you provide a new feature for the eventmesh, submit an issue in the eventmesh and submit a pr to the eventmesh. + +- Other contributors in the eventmesh community have raised issues, the [`issue for first-time contributors`](https://github.com/apache/incubator-eventmesh/issues/888) sorted out by the community here are relatively simple PR, which can help you familiarize yourself with the process of making contributions to the eventmesh community. + +## Submit issue guidelines + +- If you don't know how to raise an issue on eventmesh, please read [about the issue](https://docs.github.com/cn/issues/tracking-your-work-with-issues/quickstart). + +- In the eventmesh community, there are issue templates that can be used for reference, if the type matches please use the template, if the issue template does not meet your requirements, you can open an empty issue template, for the issue please bring its matching feature labels. + +- For the name of the issue, please briefly describe your question or purpose in one sentence, and write in English for better global communication. + +## pull request (pr) submission guidelines + +- If you don't know how to initiate a pr for eventmesh, please see [about pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). + +- Whether it's a bug fix, or a new feature development (if this pr is a new feature development, then documentation updates about the new feature should be included in this pr), please submit a PR to the current development branch master. + +- The pr submission should follow the template provided by eventmesh as well as the need to write the submission information, a brief description of what the pr you are submitting does is sufficient, please see the [template for details](https://github.com/apache/incubator-eventmesh/blob/master/.github/PULL_REQUEST_TEMPLATE.md). + +- The pr you submit needs to be associated with the issue you are fixing, or the issue you are raising,so your PR title should start with [ISSUE #xx]. + +- If your change is about a typo or small optimize, you needn't create an Issue, just submit a PR and title with [MINOR]. + +**Note:** + + - A single pull request should not be too large. If heavy changes are required, it's better to separate the changes to a few individual PRs. + + - After creating a PR, one or more committers will help to review the pull request, after approve, this PR will be merged in to eventmesh repository, and the related Issue will be closed. + +## review + +### PR review + +All code should be well reviewed by one or more committers. Some principles: + +- Readability: Important code should be well-documented. Comply with our [code style](https://github.com/apache/incubator-eventmesh/blob/master/style/checkStyle.xml). + +- Elegance: New functions, classes or components should be well-designed. + +- Testability: Important code should be well-tested (high unit test coverage). + +### License review + +EventMesh follows [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) policy. All source files should +have the Apache License header added to the file header. EventMesh uses the [apache/skywalking-eyes](https://github.com/apache/skywalking-eyes) to check +the source file header. + +### PR merge + +After a PR is approved by at least one committer, it can be merged. Before the merge, the committer can make changes to the commits message, requiring the commits +message to be clear without duplication, and use Squash and Merge to make sure one PR should only contain one commits. +For large multi-person PR, use Merge to merge, and fix the commits by rebase before merging. + +## Community + +### Contact us + +Mail: dev@eventmesh.apache.org \ No newline at end of file diff --git a/docs/en/contribute/_category_.json b/docs/en/contribute/_category_.json new file mode 100644 index 0000000000..56d36f918e --- /dev/null +++ b/docs/en/contribute/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 5, + "label": "Contribute", + "collapsed": false +} diff --git a/docs/en/design-document/01-workflow.md b/docs/en/design-document/01-workflow.md new file mode 100644 index 0000000000..fecae1ee66 --- /dev/null +++ b/docs/en/design-document/01-workflow.md @@ -0,0 +1,261 @@ +# EventMesh Workflow + +## Business Problem + +Imaging you are building a simple Order Management System for an E-Commerce Store. The system should be able to receive and provision new orders from a store website. The provisioning process should be able to process all orders, handle payments, as well as process shipments. + +For high availability and high performance, you architect the system using event-driven architecture (EDA), and build microservice apps to handle store frontend, order management, payment processing, and shipment management. You deploy the whole system in a cloud environment. To handle high workloads, you leverage a messaging system to buffer the loads, and scale up multiple instances of microservices. The architecture could look similar to: + +![Workflow Use Case](../../images/design-document/workflow-use-case.jpg) + +While each microservice is acting on its own event channels, EventMesh plays a crucial role of doing Event Orchestration. + +We use [CNCF Serverless Workflow](https://serverlessworkflow.io/) to describe this Event Workflow Orchestration. + +## CNCF Serverless Workflow + +CNCF Serverless Workflow defines a vendor-neutral, open-source, and fully community-driven ecosystem for defining and running DSL-based workflows that target the Serverless technology domain. + +Serverless Workflow defines a Domain Specific Language (DSL) to describe stateful and stateless workflow-based orchestrations of serverless functions and microservices. + +More details could be found in its [official github site](https://github.com/serverlessworkflow/specification) + +## EventMesh Workflow + +We leverage Serverless Workflow DSL to describe the EventMesh workflow. Based on its spec, the workflow is consists of a series of workflow states used to describe the control-flow logic. At this time we only support event related workflow states. See the supported states in [Workflow DSL Design](#workflow-dsl-design-wip). + +A `workflow state` can include applicable `actions`, or services/functions that should be invoked during workflow execution. These `actions` can reference reusable `function` definitions which define how these functions/services should be invoked. They can also reference events that trigger event-based service invocations, and events to wait for that denote completion of such event-based service invocation completion. + +In EDA solution, we usually defined our event-driven microservice using AsyncAPI. Serverless workflow `function` definitions support defining invocation semantics using AsyncAPI. See [Using Funtions for AsyncAPI Service](https://github.com/serverlessworkflow/specification/blob/main/specification.md#using-functions-for-async-api-service-invocations) for more information. + +### AsyncAPI + +AsyncAPI is an open source initiative that seeks to improve the current state of Event-Driven Architectures (EDA). +Our long-term goal is to make working with EDAs as easy as it is to work with REST APIs. +That goes from documentation to code generation, discovery to event management. +Most of the processes you apply to your REST APIs nowadays would be applicable to your event-driven/asynchronous APIs too. + +See AsyncAPI detail in the [official site](https://www.asyncapi.com/docs/getting-started) + +### Workflow Example + +In this example, we build the event-driven workflow of the Order management system above. + +First, we need to define AsyncAPI definitions for our microservice apps. + +- Online Store App + +```yaml +asyncapi: 2.2.0 +info: + title: Online Store application + version: '0.1.0' +channels: + store/order: + subscribe: + operationId: newStoreOrder + message: + $ref : '#/components/NewOrder' + +``` + +- Order Service + +```yaml +asyncapi: 2.2.0 +info: + title: Order Service + version: '0.1.0' +channels: + order/inbound: + publish: + operationId: sendOrder + message: + $ref : '#/components/Order' + order/outbound: + subscribe: + operationId: processedOrder + message: + $ref : '#/components/Order' +``` + +- Payment Service + +```yaml +asyncapi: 2.2.0 +info: + title: Payment Service + version: '0.1.0' +channels: + payment/inbound: + publish: + operationId: sendPayment + message: + $ref : '#/components/OrderPayment' + payment/outbound: + subscribe: + operationId: paymentReceipt + message: + $ref : '#/components/OrderPayment' +``` + +- Shipment Service + +```yaml +asyncapi: 2.2.0 +info: + title: Shipment Service + version: '0.1.0' +channels: + shipment/inbound: + publish: + operationId: sendShipment + message: + $ref : '#/components/OrderShipment' +``` + +Once that is defined, we define the order workflow that describes our Order Management business logic. + +```yaml +id: storeorderworkflow +version: '1.0' +specVersion: '0.8' +name: Store Order Management Workflow +states: + - name: Receive New Order Event + type: event + onEvents: + - eventRefs: + - NewOrderEvent + actions: + - eventRef: + triggerEventRef: OrderServiceSendEvent + resultEventRef: OrderServiceResultEvent + - eventRef: + triggerEventRef: PaymentServiceSendEvent + resultEventRef: PaymentServiceResultEvent + transition: Check Payment Status + - name: Check Payment Status + type: switch + dataConditions: + - name: Payment Successfull + condition: "${ .payment.status == 'success' }" + transition: Send Order Shipment + - name: Payment Denied + condition: "${ .payment.status == 'denied' }" + end: true + defaultCondition: + end: true + - name: Send Order Shipment + type: operation + actions: + - eventRef: + triggerEventRef: ShipmentServiceSendEvent + end: true +events: + - name: NewOrderEvent + source: file://onlineStoreApp.yaml#newStoreOrder + type: asyncapi + kind: consumed + - name: OrderServiceSendEvent + source: file://orderService.yaml#sendOrder + type: asyncapi + kind: produced + - name: OrderServiceResultEvent + source: file://orderService.yaml#processedOrder + type: asyncapi + kind: consumed + - name: PaymentServiceSendEvent + source: file://paymentService.yaml#sendPayment + type: asyncapi + kind: produced + - name: PaymentServiceResultEvent + source: file://paymentService.yaml#paymentReceipt + type: asyncapi + kind: consumed + - name: ShipmentServiceSendEvent + source: file://shipmentService.yaml#sendShipment + type: asyncapi + kind: produced +``` + +The corresponding workflow diagram is the following: + +![Workflow Diagram](../../images/design-document/workflow-diagram.png) + +## EventMesh Workflow Engine + +In the following architecture diagram, the EventMesh Catalog, EventMesh Workflow Engine and EventMesh Runtime are running in three different processors. + +![Workflow Architecture](../../images/design-document/workflow-architecture.jpg) + +The steps running the workflow is the followings: + +1. Deploy the Publisher and Subscriber Apps in the environment. + Describe the App APIs using AsyncAPI, generate the asyncAPI yaml. + Register the Publisher and Subscriber Apps in EventMesh Catalog using AsyncAPI. + +2. Register the Serverless Workflow DSL in EventMesh Workflow Engine. + +3. EventMesh Workflow Engine query the EventMesh Catalog for Publisher and Subscribers required in Workflow DSL `function` + +4. Event-driven Apps are publish events to EventMesh Runtime to trigger the Workflow. EventMesh Workflow Engine also publish and subscribe events for orchestrating the events. + +### EventMesh Catalog Design + +EventMesh Catalog store the Publisher, Subscriber and Channel metadata. consists of the following modules: + +- AsyncAPI Parser + + Using the SDK provided by AsyncAPI community (see [tool list](https://www.asyncapi.com/docs/community/tooling)), + parse and validated the AsyncAPI yaml inputs, and generate the AsyncAPI definition. + +- Publisher, Channel, Subscriber Modules + + From the AsyncAPI definition store the Publisher, Subscriber and Channel information. + +### EventMesh Workflow Engine Design + +EventMesh Workflow Engine consists of the following modules: + +- Workflow Parser + + Using the SDK provided by Serverless Workflow community (see supported [SDKs](https://github.com/serverlessworkflow/specification#sdks)), + parse and validated the workflow DSL inputs, and generate workflow definition. + +- Workflow Module + + It manages a workflow instance life cycle, from create, start, stop to destroy. + +- State Module + + It manages workflow state life cycle. We support the event-related states, and the supported state list below is Work-in-Progress. + + | Workflow State | Description | + | --- | --- | + | Operation | Execute the AsyncAPI functions defined in the Actions | + | Event | Check if the defined Event matched, if so execute the defined AsyncAPI functions | + | Switch | Check the event is matched with the event-conditions, and execute teh defined AsyncAPI functions | + | Parallel | Execute the defined AsyncAPI functions in parallel | + | ForEach | Iterate the inputCollection and execute the defined AsyncAPI functions | + +- Action Module + + It managed the functions inside the action. + +- Function Module + + It manages the AsyncAPI functions by creating the publisher and/or subscriber in EventMesh Runtime, and manage the publisher/subscriber life cycle. + + | AsyncAPI Operation | EventMesh Runtime | + | --- | --- | + | Publish | Publisher | + | Subscribe | Subscriber | + +- Event Module + + It manages the CloudEvents data model, including event filter, correlation and transformation using the rules defined in the workflow DSL. + +- Retry Module + + It manages the retry logic of the event publishing into EventMesh Runtime. diff --git a/docs/en/design-document/02-runtime-protocol.md b/docs/en/design-document/02-runtime-protocol.md new file mode 100644 index 0000000000..1583e2fda0 --- /dev/null +++ b/docs/en/design-document/02-runtime-protocol.md @@ -0,0 +1,401 @@ +# EventMesh Runtime Protocol + +## TCP Protocol + +### Protocol Format + +|Name|Size|Description| +|-|-|-| +|Magic Code|9 bytes|Default: `EventMesh`| +|Protocol Version|4 bytes|Default: `0000`| +|Message Size|4 bytes|The total length of the message| +|Header Size|4 bytes|The length of the message header| +|Message Body||The content of the message| + +### Message Object in the Business Logic Layer + +#### Message Composition + +The `Package` class in the [`Package.java` file](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Package.java) is the TCP message object used in business logic layer. The class contains the `header` and `body` fields. + +```java +public class Package { + private Header header; + private Object body; +} + +public class Header { + private Command cmd; + private int code; + private String msg; + private String seq; +} +``` + +#### Specification + +- Message Header (the `header` field): The `cmd` field in the `Header` class specifies the different types of messages. +- Message Body (the `body` field): The type of the message body should be defined based on `cmd` field in the `Header` class. + +|Command|Type of Body| +|-|-| +| HEARTBEAT_REQUEST, HEARTBEAT_RESPONSE, HELLO_RESPONSE, CLIENT_GOODBYE_REQUEST, CLIENT_GOODBYE_RESPONSE, SERVER_GOODBYE_REQUEST, SERVER_GOODBYE_RESPONSE, LISTEN_REQUEST, LISTEN_RESPONSE, UNSUBSCRIBE_REQUEST, SUBSCRIBE_RESPONSE, UNSUBSCRIBE_RESPONSE, ASYNC_MESSAGE_TO_SERVER_ACK, BROADCAST_MESSAGE_TO_SERVER_ACK|N/A| +|HELLO_REQUEST|UserAgent| +|SUBSCRIBE_REQUEST|Subscription| +| REQUEST_TO_SERVER, REQUEST_TO_CLIENT, RESPONSE_TO_SERVER, RESPONSE_TO_CLIENT, ASYNC_MESSAGE_TO_SERVER, ASYNC_MESSAGE_TO_CLIENT, BROADCAST_MESSAGE_TO_SERVER, BROADCAST_MESSAGE_TO_CLIENT, ASYNC_MESSAGE_TO_CLIENT_ACK, BROADCAST_MESSAGE_TO_CLIENT_ACK, RESPONSE_TO_CLIENT_ACK, REQUEST_TO_CLIENT_ACK|OpenMessage| +|REDIRECT_TO_CLIENT|RedirectInfo| + +### Example of Client-Server Interaction + +```java +public enum Command { + // Heartbeat + HEARTBEAT_REQUEST(0), // Client send heartbeat request to server + HEARTBEAT_RESPONSE(1), // Server reply heartbeat response to client + + // Hello + HELLO_REQUEST(2), // Client send connect request to server + HELLO_RESPONSE(3), // Server reply connect response to client + + // Disconncet + CLIENT_GOODBYE_REQUEST(4), // Client send disconnect request to server + CLIENT_GOODBYE_RESPONSE(5), // Server reply disconnect response to client + SERVER_GOODBYE_REQUEST(6), // Server send disconncet request to client + SERVER_GOODBYE_RESPONSE(7), // Client reply disconnect response to server + + // Subscribe and UnSubscribe + SUBSCRIBE_REQUEST(8), // Slient send subscribe request to server + SUBSCRIBE_RESPONSE(9), // Server reply subscribe response to client + UNSUBSCRIBE_REQUEST(10), // Client send unsubscribe request to server + UNSUBSCRIBE_RESPONSE(11), // Server reply unsubscribe response to client + + // Listen + LISTEN_REQUEST(12), // Client send listen request to server + LISTEN_RESPONSE(13), // Server reply listen response to client + + // Send sync message + REQUEST_TO_SERVER(14), // Client (Producer) send sync message to server + REQUEST_TO_CLIENT(15), // Server push sync message to client(Consumer) + REQUEST_TO_CLIENT_ACK(16), // Client (Consumer) send ack of sync message to server + RESPONSE_TO_SERVER(17), // Client (Consumer) send reply message to server + RESPONSE_TO_CLIENT(18), // Server push reply message to client(Producer) + RESPONSE_TO_CLIENT_ACK(19), // Client (Producer) send acknowledgement of reply message to server + + // Send async message + ASYNC_MESSAGE_TO_SERVER(20), // Client send async msg to server + ASYNC_MESSAGE_TO_SERVER_ACK(21), // Server reply ack of async msg to client + ASYNC_MESSAGE_TO_CLIENT(22), // Server push async msg to client + ASYNC_MESSAGE_TO_CLIENT_ACK(23), // Client reply ack of async msg to server + + // Send broadcast message + BROADCAST_MESSAGE_TO_SERVER(24), // Client send broadcast msg to server + BROADCAST_MESSAGE_TO_SERVER_ACK(25), // Server reply ack of broadcast msg to client + BROADCAST_MESSAGE_TO_CLIENT(26), // Server push broadcast msg to client + BROADCAST_MESSAGE_TO_CLIENT_ACK(27), // Client reply ack of broadcast msg to server + + // Redirect + REDIRECT_TO_CLIENT(30), // Server send redirect instruction to client +} +``` + +### Client-Initiated Interaction + +|Scene|Client Request|Server Response| +|-|-|-| +| Hello | HELLO_REQUEST | HELLO_RESPONSE | | +| Heartbeat | HEARTBEAT_REQUEST | HEARTBEAT_RESPONSE | | +| Subscribe | SUBSCRIBE_REQUEST | SUBSCRIBE_RESPONSE | | +| Unsubscribe | UNSUBSCRIBE_REQUEST | UNSUBSCRIBE_RESPONSE | | +| Listen | LISTEN_REQUEST | LISTEN_RESPONSE | | +| Send sync message | REQUEST_TO_SERVER | RESPONSE_TO_CLIENT | | +| Send the response of sync message| RESPONSE_TO_SERVER | N/A | | +| Send async message | ASYNC_MESSAGE_TO_SERVER | ASYNC_MESSAGE_TO_SERVER_ACK | | +| Send broadcast message | BROADCAST_MESSAGE_TO_SERVER | BROADCAST_MESSAGE_TO_SERVER_ACK | | +| Client start to disconnect | CLIENT_GOODBYE_REQUEST | CLIENT_GOODBYE_RESPONSE | | + +### Server-Initiated Interaction + +|Scene|Server Request|Client Response|Remark| +|-|-| ------------------------------- | ---- | +| Push sync message to client | REQUEST_TO_CLIENT | REQUEST_TO_CLIENT_ACK | | +| Push the response message of sync message to client | RESPONSE_TO_CLIENT | RESPONSE_TO_CLIENT_ACK | | +| Push async message to client | ASYNC_MESSAGE_TO_CLIENT | ASYNC_MESSAGE_TO_CLIENT_ACK | | +| Push broadcast message to client | BROADCAST_MESSAGE_TO_CLIENT | BROADCAST_MESSAGE_TO_CLIENT_ACK | | +| Server start to disconnect | SERVER_GOODBYE_REQUEST | -- | | +| Server send redirect | REDIRECT_TO_CLIENT | -- | | + +### Type of Message + +#### Sync Message + +![Sync Message](../../images/design-document/sync-message.png) + +#### Async Message + +![Async Message](../../images/design-document/async-message.png) + +#### Boardcast Message + +![Boardcast Message](../../images/design-document/broadcast-message.png) + +## HTTP Protocol + +### Protocol Format + +The `EventMeshMessage` class in the [`EventMeshMessage.java` file](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-common/src/main/java/org/apache/eventmesh/common/EventMeshMessage.java) is the HTTP message definition of EventMesh Runtime. + +```java +public class EventMeshMessage { + private String bizSeqNo; + + private String uniqueId; + + private String topic; + + private String content; + + private Map prop; + + private final long createTime = System.currentTimeMillis(); +} +``` + +### HTTP Post Request + +#### Heartbeat Message + +##### Request Header + +| Key | Description | +| -------- | ---------------- | +| Env | Enviroment of Client | +| Region | Region of Client | +| Idc | IDC of Client | +| Dcn | DCN of Client | +| Sys | Subsystem ID of Client | +| Pid | Client Process ID | +| Ip | Client Ip | +| Username | Client username | +| Passwd | Client password | +| Version | Protocol version | +| Language | Develop language | +| Code | Request Code | + +##### Request Body + +|Key|Description| +|-|-| +|`clientType`|`ClientType.PUB` for Producer, `ClientType.SUB` for Consumer| +|`heartbeatEntities`|Topic, URL, etc.| + +#### Subscribe Message + +##### Request Header + +The request header of the Subscribe message is identical to the request header of the Heartbeat message. + +##### Request Body + +|Key|Description| +|-|-| +|`topic`|The topic that the client requested to subscribe to| +|`url`|The callback URL of the client| + +#### Unsubscribe Message + +##### Request Header + +The request header of the Unsubscribe message is identical to the request header of the Heartbeat message. + +##### Request Body + +The request body of the Unsubscribe message is identical to the request body of the Subscribe message. + +#### Send Async Message + +##### Request Header + +The request header of the Send Async message is identical to the request header of the Heartbeat message. + +##### Request Body + +|Key|Description| +|-|-| +|`topic`|Topic of the message| +|`content`|The content of the message| +|`ttl`|The time-to-live of the message| +|`bizSeqNo`|The biz sequence number of the message| +|`uniqueId`|The unique ID of the message| + +### Client-Initiated Interaction + +|Scene|Client Request|Server Response|Remark| +|-|-|-|-| +| Heartbeat | HEARTBEAT(203) | SUCCESS(0) or EVENTMESH_HEARTBEAT_ERROR(19) | | +| Subscribe | SUBSCRIBE(206) | SUCCESS(0) or EVENTMESH_SUBSCRIBE_ERROR(17) | | +| Unsubscribe | UNSUBSCRIBE(207) | SUCCESS(0) or EVENTMESH_UNSUBSCRIBE_ERROR(18) | | +| Send async message | MSG_SEND_ASYNC(104) | SUCCESS(0) or EVENTMESH_SEND_ASYNC_MSG_ERR(14) | | + +### Server-Initiated Interaction + +|Scene|Client Request|Server Response|Remark| +|-|-|-|-| +|Push async message to the client|HTTP_PUSH_CLIENT_ASYNC(105)|`retCode`|The push is successful if the `retCode` is `0`| + +## gRPC Protocol + +### Protobuf + +The `eventmesh-protocol-gprc` module contains the [protobuf definition file](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-client.proto) of the Evenmesh client. The `gradle build` command generates the gRPC codes, which are located in `/build/generated/source/proto/main`. The generated gRPC codes are used in `eventmesh-sdk-java` module. + +### Data Model + +#### Message + +The message data model used by `publish()`, `requestReply()` and `broadcast()` APIs is defined as: + +```protobuf +message RequestHeader { + string env = 1; + string region = 2; + string idc = 3; + string ip = 4; + string pid = 5; + string sys = 6; + string username = 7; + string password = 8; + string language = 9; + string protocolType = 10; + string protocolVersion = 11; + string protocolDesc = 12; +} + +message SimpleMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + string content = 4; + string ttl = 5; + string uniqueId = 6; + string seqNum = 7; + string tag = 8; + map properties = 9; +} + +message BatchMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + + message MessageItem { + string content = 1; + string ttl = 2; + string uniqueId = 3; + string seqNum = 4; + string tag = 5; + map properties = 6; + } + + repeated MessageItem messageItem = 4; +} + +message Response { + string respCode = 1; + string respMsg = 2; + string respTime = 3; +} +``` + +#### Subscription + +The subscription data model used by `subscribe()` and `unsubscribe()` APIs is defined as: + +```protobuf +message Subscription { + RequestHeader header = 1; + string consumerGroup = 2; + + message SubscriptionItem { + enum SubscriptionMode { + CLUSTERING = 0; + BROADCASTING = 1; + } + + enum SubscriptionType { + ASYNC = 0; + SYNC = 1; + } + + string topic = 1; + SubscriptionMode mode = 2; + SubscriptionType type = 3; + } + + repeated SubscriptionItem subscriptionItems = 3; + string url = 4; +} +``` + +#### Heartbeat + +The heartbeat data model used by the `heartbeat()` API is defined as: + +```protobuf +message Heartbeat { + enum ClientType { + PUB = 0; + SUB = 1; + } + + RequestHeader header = 1; + ClientType clientType = 2; + string producerGroup = 3; + string consumerGroup = 4; + + message HeartbeatItem { + string topic = 1; + string url = 2; + } + + repeated HeartbeatItem heartbeatItems = 5; +} +``` + +### Service Definition + +#### Event Publisher Service + +```protobuf +service PublisherService { + // Async event publish + rpc publish(SimpleMessage) returns (Response); + + // Sync event publish + rpc requestReply(SimpleMessage) returns (Response); + + // Batch event publish + rpc batchPublish(BatchMessage) returns (Response); +} +``` + +#### Event Consumer Service + +```protobuf +service ConsumerService { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + rpc subscribe(Subscription) returns (Response); + + // The subscribed event will be delivered through stream of Message + rpc subscribeStream(Subscription) returns (stream SimpleMessage); + + rpc unsubscribe(Subscription) returns (Response); +} +``` + +#### Client Hearthbeat Service + +```protobuf +service HeartbeatService { + rpc heartbeat(Heartbeat) returns (Response); +} +``` diff --git a/docs/en/design-document/03-stream.md b/docs/en/design-document/03-stream.md new file mode 100644 index 0000000000..421faf3af3 --- /dev/null +++ b/docs/en/design-document/03-stream.md @@ -0,0 +1,118 @@ +# EventMesh Stream + +## Overview of Event Streaming + +Event Streaming is an implementation of Pub/Sub architecture pattern,it consist of + +- Message or Event: Change of State. + +- Topic: Partition in messaging middle ware broker. + +- Consumer: Can subscribe to read events from broker topic. + +- Producer: Generate events + +Streaming of event is continuous flow of events in order to maintain order between events, events flow should be in a specific direction means from producers to consumers. + +## Requirements + +### Functional Requirements + +| Requirement ID | Requirement Description | Comments | +| -------------- | ----------------------- | -------- | +| F-1 | EventMesh users should be able to achieve Event Streaming functionality in EventMesh | Functionality | +| F-2 | EventMesh users can apply dynamic user specific logics for routing, filter, transformation etc | Functionality | + +## Design Details + +We are introduce EventMesh Stream component allow us to use programming model and binder abstractions +from Spring Cloud Stream natively within Apache Camel. + +[Spring-Cloud-Stream](https://spring.io/projects/spring-cloud-stream) Spring Cloud Stream is a framework for building +highly scalable event-driven microservices connected with shared messaging systems. + +[Apache Camel](https://camel.apache.org/) Camel is an Open Source integration framework that empowers you to quickly +and easily integrate various systems consuming or producing data. + +## Architecture + +![Stream Architecture](../../images/design-document/stream-architecture.png) + +## Design + +### EventMesh-Stream Component + +- Event +- Event Channel +- Event EndPoint +- Event Pipes & Filters +- Event Routes +- Event Converter + +#### Event + +> A event is the smallest unit for transmitting data in system. It structure divided into headers, body and attachments. + +#### Event Channel + +> A event channel is a logical channel in system, we are achieving by Spring Cloud Stream programming model, it has abstract functionality around messaging channels(As of now Spring `MessageChannel`). + +#### Event EndPoint + +> A event endpoint is the interface between an application and a messaging system. We can define two types of endpoint + +- Consumer endpoint - Appears at start of a route and read incoming events from an incoming channel. +- Producer endpoint - Appears at end of a route and write incoming events to an outgoing channel. + +#### Event Pipes & Filters + +> We can construct a route by creating chain of filters( Apache Camel `Processor`), where the output of one filter is fed into input for next filter in the pipeline. +The main advantage of the pipeline is that you can create complex event processing logic. + +#### Event Routes + +> A event router, is a type of filter on consumer and redirect them to the appropriate target endpoint based on a decision criteria. + +#### Event Converter + +> The event converter that modifies the contents of a event, translating it to a different format(i.e cloudevents -> Event (Camel) -> Binder Message(Spring Message) and vice versa). + +## EventMesh-Stream Component Interfaces + +### Component + +Component interface is the primary entry point, you can use Component object as a factory to create EndPoint objects. + +![Stream Component Interface](/images/design-document/stream-component-interface.png) + +### EndPoint + +EndPoint which is act as factories for creating Consumer, Producer and Event objects. + +- `createConsumer()` — Creates a consumer endpoint, which represents the source endpoint at the beginning of a route. +- `createProducer()` — Creates a producer endpoint, which represents the target endpoint at the end of a route. + +![Stream Component Routes](../../images/design-document/stream-component-routes.png) + +#### Producer + +User can create following types of producer +> Synchronous Producer-Processing thread blocks until the producer has finished the event processing. + +![Stream Sync Producer](../../images/design-document/stream-sync-producer.png) + +In future Producer Types: + +- Asynchronous Producer - Producer process the event in a sub-thread. + +#### Consumer + +User can create following types of consumer +> Event-driven consumer-the processing of an incoming request is initiated when message binder call a method in consumer. + +![Stream Event-Driven Consumer](../../images/design-document/stream-event-driven-consumer.png) + +In the Future + +- Scheduled poll consumer +- Custom polling consumer diff --git a/docs/en/design-document/04-schema-registry.md b/docs/en/design-document/04-schema-registry.md new file mode 100644 index 0000000000..2cab152651 --- /dev/null +++ b/docs/en/design-document/04-schema-registry.md @@ -0,0 +1,134 @@ +# EventMesh Schema Registry (OpenSchema) + +## Overview of Schema and Schema Registry + +### Schema + +A Schema stands for the description of serialization instances(string/stream/file/...) and has two properties. First, it is also in the format of serialization type. Second, it defines what requirements such serialized instances should satisfy. + +Besides describing a serialization instance, a Schema may also be used for validating whether an instance is legitimate. The reason is that it defines the ```type```(and other properties) of a serialized instance and inside keys. Taking JSON Schema for example, it could not only be referred when describing a JSON string, but also be used for validating whether a string satisfies properties defined in the schema[[1]](#References). + +Commonly, there are JSON Schema, Protobuf Schema, and Avro Schema. + +### Schema Registry + +Schema Registry is a server provides RESTful interfaces. It could receive and store Schemas from clients, as well as provide intrefaces for other clients to retrieve Schemas from it. + +It could be applied to validation process and (de-)serialization process. + +### Comparison of Schema Registry in Different Projects + +Project | Application +:---: | :--- +EMQ[[2]](#References) | Mainly in (de-)serialization process. Use "Schema Registry" and "Rule Matching" to transfer a message from one serialization format to another. +Pulsar[[3]](#References) | Mainly in validation process. Use "Schema Registry" to validate a message. +Confluentinc[[4]](#References) | In both validation and (de-)serialization process. + +## Overview of OpenSchema + +OpenSchema[[5]](#References) proposes a specification for data schema when exchanging the message and event in more and more modern cloud-native applications. It designs a RESTful interface for storing and retrieving such as Avro, JSON Schema, and Protobuf3 schemas from three aspects(subject/schema/compatibility). + +## Requirements(Goals) + +| Requirement ID | Requirement Description | Comments | +| :------------- | ------------------------------------------------------------ | ------------- | +| F-1 | In transmission, no message needs to contain schema information which bring efficiency. | Functionality | +| F-2 | The message content from producer could be validated whether serialized correctly according to schema. | Functionality | + +## Design Details + +### Architecture + +![OpenSchema](../../images/design-document/schema-registry-architecture.png) + +### Process of Transferring Messages under Schema Registry + +![Process](.././images/design-document/schema-registry-process.jpg) + +The highlevel process of messages transmission contains 10 steps as follows: + +- 1: Consumer subscribes "TOPIC" messages from EventMesh. +- 2: Producer registers a schema to EventMesh. +- 3: EventMesh registers a schema to Schema Registry. +- 4: Schema Registry returns the id of newly created schema; EventMesh caches such id and schema. +- 5: EventMesh returns the id of schema to Producer. +- 6: Producer patches the id in front of messages and send messages to EventMesh. +- 7: EventMesh validates the messages in the entry port and send it to EventStore; EventMesh retrieves messages from EventStore. +- 8: EventMesh unpatches the id and send it to Schema Registry(if such `` does not exists in local cache). +- 9: Schema Registry returns schema and EventMesh caches it. +- 10: EventMesh patches schema in front of messages and push it to consumer. + +## Current Progress + +### Status + +**Current state**: Developing + +**Discussion thread**: ISSUE #339 + +### Proposed Changes + +The proposal has two aspects. + +First is a separated Open Schema Registry, which includes storage and compatibility check for schema. +This proposal is under developing. + +Second is the integration of Open Schema in Eventmesh, which includes validation for schema. This proposal is to be developed. + +As for the first proposal, some developing statuses are as follows. + +#### Status Code and Exception Code + +No. | Status Code | Exception Code | Description | status +--- | :---: | :---: | :---: | :---: +1 | 401 | 40101 | Unauthorized Exception | ✔ +2 | 404 | 40401 | Schema Non- Exception | ✔ +3 | ^ | 40402 | Subject Non-exist Exception | ✔ +4 | ^ | 40403 | Version Non-exist Exception | ✔ +5 | 409 | 40901 | Compatibility Exception | ✔ +6 | 422 | 42201 | Schema Format Exception | ✔ +7 | ^ | 42202 | Subject Format Exception | ✔ +8 | ^ | 42203 | Version Format Exception | ✔ +9 | ^ | 42204 | Compatibility Format Exception | ✔ +10 | 500 | 50001 | Storage Service Exception | ✔ +11 | ^ | 50002 | Timeout Exception | ✔ + +#### API Development Status + +No. | Type | URL | response | exception | code | test +--- | --- | --- | --- | --- | --- | --- +1 | GET | /schemas/ids/{string: id} | `Schema.class` | 40101\40401\50001 | ✔ | ❌ +2 | GET | /schemas/ids/{string: id}/subjects | `SubjectAndVersion.class` | 40101\40401\50001 | ✔ | ❌ +3 | GET | /subjects | `List\` | 40101\50001 | ✔ | ❌ +4 | GET | /subjects/{string: subject}/versions | `List\` | 40101\40402\50001 | ✔ | ❌ +5 | DELETE | /subjects/(string: subject) | `List\` | 40101\40402\50001 | ✔ | ❌ +6 | GET | /subjects/(string: subject) | `Subject.class` | 40101\40402\50001 | ✔ | ❌ +7 | GET | /subjects/(string: subject)/versions/(version: version)/schema | `SubjectWithSchema.class` | 40101\40402\40403\50001 | ✔ | ❌ +8 | POST | /subjects/(string: subject)/versions | `SchemaIdResponse.class` | 40101\40901\42201\50001\50002 | - | ❌ +9 | POST | /subjects/(string: subject)/ | `Subject.class` | 40101\40901\42202\50001\50002 | ✔ | ❌ +10 | DELETE | /subjects/(string: subject)/versions/(version: version) | `int` | 40101\40402\40403\40901\50001| - | ❌ +11 | POST | /compatibility/subjects/(string: subject)/versions/(version: version) | `CompatibilityResultResponse.class` | 40101\40402\40403\42201\42203\50001| - | ❌ +12 | GET | /compatibility/(string: subject) | `Compatibility.class` | 40101\40402\50001 | ✔ | ❌ +13 | PUT | /compatibility/(string: subject) | `Compatibility.class` | 40101\40402\40901\42204\50001 | - | ❌ + +#### Overall Project Structure + +```SchemaController.java```+```SchemaService.java``` : ```OpenSchema 7.1.1~7.1.2 (API 1~2)``` + +```SubjectController.java```+```SubjectService.java``` : ```OpenSchema 7.2.1~7.2.8 (API 3~10)``` + +```CompatibilityController.java```+```CompatibilityService.java``` : ```OpenSchema 7.3.1~7.3.3 (API 11~13)``` + ```Check for Compatibility``` + +![Project Structure](../../images/design-document/schema-registry-project-structure.png) + +## References + +[1] [schema validator (github.com)](https://github.com/search?q=schema+validator) + +[2] [EMQ: Schema Registry](https://www.jianshu.com/p/33e0655c642b) + +[3] [Pulsar: Schema Registry](https://mp.weixin.qq.com/s/PaB66-Si00cX80py5ig5Mw) + +[4] [confluentinc/schema-registry](https://github.com/confluentinc/schema-registry) + +[5] [openmessaging/openschema](https://github.com/openmessaging/openschema) diff --git a/docs/en/design-document/05-metrics-export.md b/docs/en/design-document/05-metrics-export.md new file mode 100644 index 0000000000..bab18761e3 --- /dev/null +++ b/docs/en/design-document/05-metrics-export.md @@ -0,0 +1,47 @@ +# EventMesh Metrics (OpenTelemetry and Prometheus) + +## Introduction + +[EventMesh(incubating)](https://github.com/apache/incubator-eventmesh) is a dynamic cloud-native eventing infrastructure. + +## An overview of OpenTelemetry + +OpenTelemetry is a collection of tools, APIs, and SDKs. You can use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) for analysis in order to understand your software's performance and behavior. + +## An overview of Prometheus + +Power your metrics and alerting with a leading open-source monitoring solution. + +- Dimensional data +- Powerful queries +- Great visualization +- Efficient storage +- Simple operation +- Precise alerting +- Many client libraries +- Many integrations + +## Requirements + +### Functional Requirements + +| Requirement ID | Requirement Description | Comments | +| :------------- | ------------------------------------------------------------ | ------------- | +| F-1 | EventMesh users should be able to observe HTTP metrics from Prometheus | Functionality | +| F-2 | EventMesh users should be able to observe TCP metrics from Prometheus | Functionality | + +## Design Details + +use the meter instrument provided by OpenTelemetry to observe the metrics exist in EventMesh then export to Prometheus. + +1、Initialize a meter instrument + +2、set the Prometheus server + +3、different metrics observer built + +## Appendix + +### References + + diff --git a/docs/en/design-document/06-cloudevents.md b/docs/en/design-document/06-cloudevents.md new file mode 100644 index 0000000000..20a99d182a --- /dev/null +++ b/docs/en/design-document/06-cloudevents.md @@ -0,0 +1,106 @@ +# CloudEvents Integration + +## Introduction + +[CloudEvents](https://github.com/cloudevents/spec) is a specification for describing event data in common formats to provide interoperability across services, platforms and systems. + +As of May 2021, EventMesh contains the following major components: `eventmesh-runtime`, `eventmesh-sdk-java` and `eventmesh-connector-rocketmq`. +For a customer to use EventMesh, `eventmesh-runtime` can be deployed as microservices to transmit +customer's events between event producers and consumers. Customer's applications can then interact +with `eventmesh-runtime` using `eventmesh-sdk-java` to publish/subscribe for events on given topics. + +CloudEvents support has been a highly desired feature by EventMesh users. There are many reasons +for users to prefer using a SDK with CloudEvents support: + +- CloudEvents is a more widely accepted and supported way to describe events. `eventmesh-sdk-java` + currently uses the `LiteMessage` structure to describe events, which is less standardized. +- CloudEvents's Java SDK has a wider range of distribution methods. For example, EventMesh users + currently need to use the SDK tarball or build from source for every EventMesh release. With + CloudEvents support, it's easier for users to take a dependency on EventMesh's SDK using CloudEvents's public distributions (e.g. through a Maven configuration). +- CloudEvents's SDK supports multiple languages. Although EventMesh currently only supports a Java SDK, in future if more languages need to be supported, the extensions can be easier with experience on binding Java SDK with CloudEvents. + +## Requirements + +### Functional Requirements + +| Requirement ID | Requirement Description | Comments | +| -------------- | ----------------------- | -------- | +| F-1 | EventMesh users should be able to depend on a public SDK to publish/subscribe events in CloudEvents format | Functionality | +| F-2 | EventMesh users should continue to have access to existing EventMesh client features (e.g. load balancing) with an SDK that supports CloudEvent | Feature Parity | +| F-3 | EventMesh developers should be able to sync `eventmesh-sdk-java` and an SDK with CloudEvents support without much effort/pain | Maintainability | +| F-4 | EventMesh support pluggable protocols for developers integrate other protocols (e.g. CloudEvents\EventMesh Message\OpenMessage\MQTT ...) | Functionality | +| F-5 | EventMesh support the unified api for publish/subscribe events to/from event store | Functionality | + +### Performance Requirements + +| Requirement ID | Requirement Description | Comments | +| -------------- | ----------------------- | -------- | +| P-1 | Client side latency for SDK with CloudEvents support should be similar to current SDK | | + +## Design Details + +Binding with the CloudEvents Java SDK (similar to what Kafka already did, see Reference for more details) +should be an easy way to achieve the requirements. + +### Pluggable Protocols + +![Pluggable Protocols](../../images/design-document/cloudevents-pluggable-protocols.png) + +### Process of CloudEvents under EventMesh + +#### For TCP + +##### SDK side for publish + +- add the CloudEvents identifier in `package` header +- use `CloudEventBuilder` build the CloudEvent and put it into the `package` body + +##### SDK side for subscribe + +- add `convert` function under the `ReceiveMsgHook` interface, for converting the `package` body to the specific protocol with the identifier in `package` header +- different protocols should implement the `ReceiveMsgHook` interface + +##### Server side for publish + +- design the protocol convert api contains `decodeMessage` interface which convert the package's body to CloudEvent +- update `Session.upstreamMsg()` in `MessageTransferTask` change the input parameter Message to CloudEvent, the CloudEvent use the last step `decodeMessage` api convert +- update `SessionSender.send()` change the input parameter `Message` to `CloudEvent` +- update `MeshMQProducer` api support send `CloudEvents` in runtime +- support the implementation in `connector-plugin` for send `CloudEvents` to EventStore + +##### Server side for subscribe + +- support change the `RocketMessage` to `CloudEvent` in connector-plugin + +- overwrite the `AsyncMessageListener.consume()` function, change the input parameter `Message` to `CloudEvent` + +- update the `MeshMQPushConsumer.updateOffset()` implementation change the the input parameter `Message` to `CloudEvent` + +- update `DownStreamMsgContext` , change the input parameter `Message` to `CloudEvent`, update the `DownStreamMsgContext.ackMsg` + +#### For HTTP + +##### SDK side for publish + +- support `LiteProducer.publish(cloudEvent)` +- add the CloudEvents identifier in http request header + +##### SDK side for subscribe + +##### Server side for publish + +- support build the `HttpCommand.body` by pluggable protocol plugins according the protocol type in `HttpCommand` header +- support publish the CloudEvent in message processors + +##### Server side for subscribe + +- update the `EventMeshConsumer.subscribe()` + +- update `HandleMsgContext` , change the input parameter `Message` to `CloudEvent` +- update `AsyncHttpPushRequest.tryHTTPRequest()` + +## Appendix + +### References + +- diff --git a/docs/en/design-document/07-tracing.md b/docs/en/design-document/07-tracing.md new file mode 100644 index 0000000000..1b191965da --- /dev/null +++ b/docs/en/design-document/07-tracing.md @@ -0,0 +1,87 @@ +# Distributed Tracing + +## Overview of OpenTelemetry + +OpenTelemetry is a collection of tools, APIs, and SDKs. You can use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) for analysis in order to understand your software's performance and behavior. + +## Requirements + +- set tracer +- different exporter +- start and end span in server + +## Design Details + +- SpanProcessor: BatchSpanProcessor + +- Exporter: log(default), would be changed from properties + +```java +// Configure the batch spans processor. This span processor exports span in batches. +BatchSpanProcessor batchSpansProcessor = + BatchSpanProcessor.builder(exporter) + .setMaxExportBatchSize(512) // set the maximum batch size to use + .setMaxQueueSize(2048) // set the queue size. This must be >= the export batch size + .setExporterTimeout( + 30, TimeUnit.SECONDS) // set the max amount of time an export can run before getting + // interrupted + .setScheduleDelay(5, TimeUnit.SECONDS) // set time between two different exports + .build(); +OpenTelemetrySdk.builder() + .setTracerProvider( + SdkTracerProvider.builder().addSpanProcessor(batchSpansProcessor).build()) + .build(); +``` + +1. When using the method 'init()' of the class "EventMeshHTTPServer", the class "AbstractHTTPServer” will get the tracer + +```java +super.openTelemetryTraceFactory = new OpenTelemetryTraceFactory(eventMeshHttpConfiguration); +super.tracer = openTelemetryTraceFactory.getTracer(this.getClass().toString()); +super.textMapPropagator = openTelemetryTraceFactory.getTextMapPropagator(); +``` + +2. then the trace in class "AbstractHTTPServer” will work. + +## Problems + +### How to set different exporter in class 'OpenTelemetryTraceFactory'? (Solved) + +After I get the exporter type from properties, how to deal with it. + +The 'logExporter' only needs to new it. + +But the 'zipkinExporter' needs to new and use the "getZipkinExporter()" method. + +## Solutions + +### Solution of different exporter + +Use reflection to get an exporter. + +First of all, different exporter must implement the interface 'EventMeshExporter'. + +Then we get the exporter name from the configuration and reflect to the class. + +```java +//different spanExporter +String exporterName = configuration.eventMeshTraceExporterType; +//use reflection to get spanExporter +String className = String.format("org.apache.eventmesh.runtime.exporter.%sExporter",exporterName); +EventMeshExporter eventMeshExporter = (EventMeshExporter) Class.forName(className).newInstance(); +spanExporter = eventMeshExporter.getSpanExporter(configuration); +``` + +Additional, this will surround with try catch.If the specified exporter cannot be obtained successfully, the default exporter log will be used instead + +#### Improvement of different exporter + +SPI (To be completed) + +## Appendix + +### References + + + + diff --git a/docs/en/design-document/08-spi.md b/docs/en/design-document/08-spi.md new file mode 100644 index 0000000000..94da666e7f --- /dev/null +++ b/docs/en/design-document/08-spi.md @@ -0,0 +1,113 @@ +# Service Provider Interface + +## Introduction + +In order to improve scalability,EventMesh introduce the SPI(Service Provider Interface)mechanism, which can help to automatically find the concrete implementation +class of the extended interface at runtime and load it dynamically. In EventMesh, all extension modules are implemented by using plugin. +User can develop custom plugins by simply implementing extended interfaces, and select the plugin to be run at runtime by simply declare at configuration. + +## eventmesh-spi module + +The implementation of SPI is at eventmesh-spi module, there are three main classes `EventMeshSPI`, `EventMeshExtensionFactory` and `ExtensionClassLoader`. + +### EventMeshSPI + +EventMeshSPI is an SPI declaration annotation, all extended interface that want to be implemented should be declared by @EventMeshSPI. + +```java +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface EventMeshSPI { + /** + * If true, the spi instance is singleton + */ + boolean isSingleton() default false; +} +``` + +Use annotation to declare the interface is an SPI extended interface can improve the readability of the code. +On the other hand, @EventMeshSPI contains a isSingleton attribute which used to declare whether the extension instance is a singleton. +If this attribute is true, that means the instance of this interface will be singleton. + +### EventMeshExtensionFactory + +EventMeshExtensionFactory is a factory used to get the SPI extension instance which contains a static method `getExtension(Class extensionType, String extensionName)`. + +```java +public enum EventMeshExtensionFactory { + /** + * @param extensionType extension plugin class type + * @param extensionName extension instance name + * @param the type of the plugin + * @return plugin instance + */ + public static T getExtension(Class extensionType, String extensionName) { + /* ... */ + } +} +``` + +If you want to get the extension instance, you should use EventMeshExtensionFactory. + +### ExtensionClassLoader + +ExtensionClassLoader is used to load extension instance classed, it has two subclass MetaInfExtensionClassLoader and JarExtensionClassLoader. + +```java +/** + * Load extension class + *
    + *
  • {@link MetaInfExtensionClassLoader}
  • + *
  • {@link JarExtensionClassLoader}
  • + *
+ */ +public interface ExtensionClassLoader { + /** + * load + * + * @param extensionType extension type class + * @param extension type + * @return extension instance name to extension instance class + */ + Map> loadExtensionClass(Class extensionType); +} +``` + +MetaInfExtensionClassLoader used to load class from classPath, and JarExtensionClassLoader used to load class from extension jar on the plugin directory. +In the future, we might support the implementation to load from the maven repository. + +## SPI use case + +The following is an example of how to use the SPI to declare a plugin. + +First, we create an eventmesh-connector-api module, and define the extension interface MeshMQProducer, and we use @EventMeshSPI on the MeshMQProducer, +which indicates the MeshMQProducer is an SPI interface. + +```java +@EventMeshSPI(isSingleton = false) +public interface MeshMQProducer extends Producer { + /* ... */ +} +``` + +Then we create an eventmesh-connector-rocketmq module, which contains the concrete implementation named RocketMQProducerImpl. + +```java +public class RocketMQProducerImpl implements MeshMQProducer { + /* ... */ +} +``` + +At the same time, we need to create a file with the full qualified name of the SPI interface under the resource/META-INF/eventmesh directory +in the eventmesh-connector-rocketmq module. + +org.apache.eventmesh.api.producer.Producer + +The content of the file is the extension instance name and the corresponding instance full class name + +```properties +rocketmq=org.apache.eventmesh.connector.rocketmq.producer.RocketMQProducerImpl +``` + +At this point, an SPI expansion module is complete. We can use `EventMeshExtensionFactory.getExtension(MeshMQProducer.class, "rocketmq")` to get the `RocketMQProducerImpl` instance. diff --git a/docs/en/design-document/_category_.json b/docs/en/design-document/_category_.json new file mode 100644 index 0000000000..f9283e2f00 --- /dev/null +++ b/docs/en/design-document/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 6, + "label": "Design Document", + "collapsed": false +} diff --git a/docs/en/features/architecture.md b/docs/en/features/architecture.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/en/features/request-response-call.md b/docs/en/features/request-response-call.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/en/instruction/01-store-with-docker.md b/docs/en/instruction/01-store-with-docker.md new file mode 100644 index 0000000000..82529089f1 --- /dev/null +++ b/docs/en/instruction/01-store-with-docker.md @@ -0,0 +1,71 @@ +# Guidelines of eventmesh-store with Docker + +## Dependencies + +``` +64-bit OS,we recommend Linux/Unix; +64-bit JDK 1.8+; +Gradle 7.0+, we recommend 7.0.* +4g+ available disk to deploy eventmesh-store +If you choose standalone mode, you could skip this file and go to the next step: Start Eventmesh-Runtime; if not, you could choose RocketMQ as the store layer. +``` + + +## Download + +Download the Binary code (recommended: 4.9.*) from [RocketMQ Official](https://rocketmq.apache.org/dowloading/releases/). Here we take 4.9.2 as an example. + +``` +unzip rocketmq-all-4.9.2-bin-release.zip +cd rocketmq-4.9.2/ +``` + + +## Deploy + +- #### Start Name Server + +``` +nohup sh bin/mqnamesrv & +tail -f ~/logs/rocketmqlogs/namesrv.log +``` + +- #### Start Broker + +``` +nohup sh bin/mqbroker -n localhost:9876 & +tail -f ~/logs/rocketmqlogs/broker.log +``` + +The deployment of eventmesh-store has finished, please go to the next step: [Start Eventmesh-Runtime](docs/en/instruction/02-runtime.md) + + + +## Deploy +Pull RocketMQ image from Docker Hub: + +```shell +#获取namesrv镜像 +sudo docker pull rocketmqinc/rocketmq-namesrv:4.5.0-alpine +#获取broker镜像 +sudo docker pull rocketmqinc/rocketmq-broker:4.5.0-alpine +``` + +Start namesrv and broker + +```shell +#运行namerv容器 +sudo docker run -d -p 9876:9876 -v `pwd` /data/namesrv/logs:/root/logs -v `pwd`/data/namesrv/store:/root/store --name rmqnamesrv rocketmqinc/rocketmq-namesrv:4.5.0-alpine sh mqnamesrv + +#运行broker容器 +sudo docker run -d -p 10911:10911 -p 10909:10909 -v `pwd`/data/broker/logs:/root/logs -v `pwd`/data/broker/store:/root/store --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" rocketmqinc/rocketmq-broker:4.5.0-alpine sh mqbroker -c ../conf/broker.conf +``` + +Please note that the **rocketmq-broker ip** is **pod ip**. If you want to modify this ip, you can set it your custom value in **broker.conf**。 + + +By now, the deployment of eventmesh-store has finished, please go to the next step: [Start Eventmesh-Runtime Using Docker](docs/en/instruction/02-runtime-with-docker.md) + + +## Reference +For more details about RocketMQ,please refer to diff --git a/docs/en/instruction/01-store.md b/docs/en/instruction/01-store.md new file mode 100644 index 0000000000..d5b5eb9c19 --- /dev/null +++ b/docs/en/instruction/01-store.md @@ -0,0 +1,44 @@ +# Guidelines of eventmesh-store + +## Dependencies + +``` +64-bit OS,we recommend Linux/Unix; +64-bit JDK 1.8+; +Gradle 7.0+, we recommend 7.0.* +4g+ available disk to deploy eventmesh-store +If you choose standalone mode, you could skip this file and go to the next step: Start Eventmesh-Runtime; if not, you could choose RocketMQ as the store layer. +``` + + +## Download + +Download the Binary code (recommended: 4.9.*) from [RocketMQ Official](https://rocketmq.apache.org/dowloading/releases/). Here we take 4.9.2 as an example. + +``` +unzip rocketmq-all-4.9.2-bin-release.zip +cd rocketmq-4.9.2/ +``` + + +## Deploy + +- #### Start Name Server + +``` +nohup sh bin/mqnamesrv & +tail -f ~/logs/rocketmqlogs/namesrv.log +``` + +- #### Start Broker + +``` +nohup sh bin/mqbroker -n localhost:9876 & +tail -f ~/logs/rocketmqlogs/broker.log +``` + +The deployment of eventmesh-store has finished, please go to the next step: [Start Eventmesh-Runtime](docs/en/instruction/02-runtime.md) + + +## Reference +For more details about RocketMQ,please refer to diff --git a/docs/en/instruction/02-runtime-with-docker.md b/docs/en/instruction/02-runtime-with-docker.md new file mode 100644 index 0000000000..7da3e2a433 --- /dev/null +++ b/docs/en/instruction/02-runtime-with-docker.md @@ -0,0 +1,107 @@ +# EventMesh Runtime (Docker) + +The documentation introduces the steps to install the latest release of EventMesh Runtime with Docker and connect to Apache RocketMQ. It's recommended to use a Linux-based system with [Docker Engine](https://docs.docker.com/engine/install/). Please follow the [Docker tutorial](https://docs.docker.com/get-started/) to get familiar with the basic concepts (registry, volume, etc.) and commands of Docker. + + +## Dependencies +``` +64-bit OS,we recommend Linux/Unix; +64-bit JDK 1.8+; +Gradle 7.0+, we recommend 7.0.* +4g+ available disk to deploy eventmesh-store +If you choose standalone mode, you could skip this file and go to the next step: Start Eventmesh-Runtime; if not, you could choose RocketMQ as the store layer. +``` + +## Pull EventMesh Image + +Download the pre-built image of [`eventmesh`](https://hub.docker.com/r/eventmesh/eventmesh) from Docker Hub with `docker pull`: + +```console +$ sudo docker pull eventmesh/eventmesh:v1.4.0 +``` + +To verify that the `eventmesh/eventmesh` image is successfully installed, list the downloaded images with `docker images`: + +```console +$ sudo docker images +eventmesh/eventmesh v1.4.0 6e2964599c78 2 weeks ago 937MB +``` + +## Edit Configuration + +Edit the `eventmesh.properties` to change the configuration (e.g. TCP port, client blacklist) of EventMesh Runtime. To integrate RocketMQ as a connector, these two configuration files should be created: `eventmesh.properties` and `rocketmq-client.properties`. + +```shell +sudo mkdir -p /data/eventmesh/rocketmq/conf +cd /data/eventmesh/rocketmq/conf +sudo touch eventmesh.properties +sudo touch rocketmq-client.properties +``` + +### `eventmesh.properties` + +The `eventmesh.properties` file contains the properties of EventMesh runtime environment and integrated plugins. Please refer to the [default configuration file](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-runtime/conf/eventmesh.properties) for the available configuration keys. + +```shell +sudo vim eventmesh.properties +``` + +| Configuration Key | Default Value | Description | +|-|-|-| +| `eventMesh.server.http.port` | 10105 | EventMesh HTTP server port | +| `eventMesh.server.tcp.port` | 10000 | EventMesh TCP server port | +| `eventMesh.server.grpc.port` | 10205 | EventMesh gRPC server port | + +### `rocketmq-client.properties` + +The `rocketmq-client.properties` file contains the properties of the Apache RocketMQ nameserver. + +```shell +sudo vim rocketmq-client.properties +``` + +Please refer to the [default configuration file](https://github.com/apache/incubator-eventmesh/blob/1.3.0/eventmesh-runtime/conf/rocketmq-client.properties) and change the value of `eventMesh.server.rocketmq.namesrvAddr` to the nameserver address of RocketMQ. + +| Configuration Key | Default Value | Description | +|-|-|-| +| `eventMesh.server.rocketmq.namesrvAddr` | `127.0.0.1:9876;127.0.0.1:9876` | The address of RocketMQ nameserver | + +## Run and Manage EventMesh Container + +Run an EventMesh container from the `eventmesh/eventmesh` image with the `docker run` command. The `-p` option of the command binds the container port with the host machine port. The `-v` option of the command mounts the configuration files from files in the host machine. + +```shell +sudo docker run -d -p 10000:10000 -p 10105:10105 \ +-v /data/eventmesh/rocketmq/conf/eventmesh.properties:/data/app/eventmesh/conf/eventmesh.properties \ +-v /data/eventmesh/rocketmq/conf/rocketmq-client.properties:/data/app/eventmesh/conf/rocketmq-client.properties \ +eventmesh/eventmesh:v1.4.0 +``` + +The `docker ps` command lists the details (id, name, status, etc.) of the running containers. The container id is the unique identifier of the container. + +```console +$ sudo docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + eventmesh/eventmesh:v1.4.0 "/bin/sh -c 'sh star…" About a minute ago Up About a minute 0.0.0.0:10000->10000/tcp, :::10000->10000/tcp, 0.0.0.0:10105->10105/tcp, :::10105->10105/tcp +``` + +To connect to the EventMesh container: + +```shell +sudo docker exec -it [container id or name] /bin/bash +``` + +To read the log of the EventMesh container: + +```shell +tail -f ../logs/eventmesh.out +``` + +To stop or remove the container: + +```shell +sudo docker stop [container id or name] + +sudo docker rm -f [container id or name] +``` + diff --git a/docs/en/instruction/02-runtime.md b/docs/en/instruction/02-runtime.md new file mode 100644 index 0000000000..900f86864a --- /dev/null +++ b/docs/en/instruction/02-runtime.md @@ -0,0 +1,107 @@ +# EventMesh Runtime + +EventMesh Runtime is the core component of Apache EventMesh (Incubating). It is the middleware that transmits events between producers and consumers. The documentation introduces the step to install and start the latest release of EventMesh Runtime in the local or test environment. The EventMesh Runtime requires a Linux-based system with JDK (Java Development Kit) 8+. + +Here, we take JDK 8 as an example. JDK 8 could be installed with the system package manager or the [openjdk:8-jdk](https://hub.docker.com/_/openjdk) Docker image. + + +## 1 Run on your local machine + +### 1.1 Dependencies + +``` +64-bit OS,we recommend Linux/Unix; +64-bit JDK 1.8+; +Gradle 7.0+, we recommend 7.0.* +4g+ available disk to deploy eventmesh-store +If you choose standalone mode, you could skip this file and go to the next step: Start Eventmesh-Runtime; if not, you could choose RocketMQ as the store layer. +``` + +### 1.2 Download Source Code + +Gradle is the build automation tool used by Apache EventMesh (Incubating). Please refer to the [offical guide](https://docs.gradle.org/current/userguide/installation.html) to install the latest release of Gradle. + +Download and extract the source code of the latest release from [EventMesh download](https://eventmesh.apache.org/download). + +```console +wget https://dlcdn.apache.org/incubator/eventmesh/{version}-incubating/apache-eventmesh-{version}-incubating-source.tar.gz + +tar -xvzf apache-eventmesh-1.5.0-incubating-source.tar.gz +``` + +Build the source code with Gradle. + +```console +cd apache-eventmesh-1.5.0-incubating-source +gradle clean dist +``` + +Edit the `eventmesh.properties` to change the configuration (e.g. TCP port, client blacklist) of EventMesh Runtime. + +```console +cd dist +vim conf/eventmesh.properties +``` + +Execute the `start.sh` script to start the EventMesh Runtime server. + +```console +bash bin/start.sh +``` + +### 1.3 Build and Load Plugins + +Apache EventMesh (Incubating) introduces the SPI (Service Provider Interface) mechanism, which enables EventMesh to discover and load the plugins at runtime. The plugins could be installed with these methods: + +- Gradle Dependencies: Declare the plugins as the build dependencies in `eventmesh-starter/build.gradle`. + +```gradle +dependencies { + implementation project(":eventmesh-runtime") + + // Example: Load the RocketMQ plugin + implementation project(":eventmesh-connector-plugin:eventmesh-connector-rocketmq") +} +``` + +- Plugin directory: EventMesh loads the plugins in the `dist/plugin` directory based on `eventmesh.properties`. The `installPlugin` task of Gradle builds and moves the plugins into the `dist/plugin` directory. + +```console +gradle installPlugin +``` + + +## 2 Remote deployment +### 2.1 Dependencies + +``` +64-bit OS,we recommend Linux/Unix; +64-bit JDK 1.8+; +Gradle 7.0+, we recommend 7.0.* +4g+ available disk to deploy eventmesh-store +If you choose standalone mode, you could skip this file and go to the next step: Start Eventmesh-Runtime; if not, you could choose RocketMQ as the store layer. +``` + +### 2.2 Download +Download and extract the executable binaries of the latest release from [EventMesh download](https://eventmesh.apache.org/download). + +```console +wget https://github.com/apache/incubator-eventmesh/releases/download/v1.4.0/apache-eventmesh-1.4.0-incubating-bin.tar.gz + +tar -xvzf apache-eventmesh-1.5.0-incubating-bin.tar.gz +``` + +### 2.3 Deploy +Edit the `eventmesh.properties` to change the configuration (e.g. TCP port, client blacklist) of EventMesh Runtime. The executable binaries contain all plugins in the bundle, thus there's no need to build them from source code. + +```console +cd apache-eventmesh-1.5.0-incubating +vim conf/eventmesh.properties +``` + +Execute the `start.sh` script to start the EventMesh Runtime server. + +```console +bash bin/start.sh +``` + diff --git a/docs/en/instruction/03-demo.md b/docs/en/instruction/03-demo.md new file mode 100644 index 0000000000..8545e05fb7 --- /dev/null +++ b/docs/en/instruction/03-demo.md @@ -0,0 +1,152 @@ +# Run our demos + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java) + +> EventMesh-sdk-java as the client,and comminucate with eventmesh-runtime,to finish the message sub and pub +> +> EventMesh-sdk-java support both async and broadcast. +> +> EventMesh-sdk-java support HTT, TCP and gRPC. + +The test demos of TCP, HTTP 和 GRPC are in the module **eventmesh-examples** + +## 1 TCP DEMO + +### 1.1 ASYNC + +- Start consumer to subscribe the topic (we have created the TEST-TOPIC-TCP-ASYNC by default, you can also create other topic to test) + +``` +Run the main method of org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribe +``` + +- Start producer to publish async message + +``` +Run the main method of org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublish +``` + +### 1.2 BROADCAST + +- Start subscriber to subscribe the topic (we have created the TEST-TOPIC-TCP-BROADCAST by default, you can also create other topic to test) + +``` +Run the main method of org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribeBroadcast +``` + +- Start publisher to publish async message + +``` +Run the main method of org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublishBroadcast +``` + +More information about EventMesh-TCP, please refer to [EventMesh TCP](docs/zh/sdk-java/03-tcp.md) + + +## 2 HTTP DEMO + + +### 2.1 ASYNC + +- The subscriber is a SpringBoot demo, so run this demo to start subscriber (we have created the topic TEST-TOPIC-HTTP-ASYNCT by default, you can also create other topic to test) + +``` +Run the main method of org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication +``` + +- Start publisher to publish message + +``` +Run the main method of org.apache.eventmesh.http.demo.pub.eventmeshmessage.AsyncPublishInstance +``` +More information about EventMesh-HTTP, please refer to [EventMesh HTTP](docs/zh/sdk-java/02-http.md) + +## 3 GRPC DEMO + +### 3.1 ASYNC PUBLISH & WEBHOOK SUBSCRIBE + +- Start publisher to publish message (we have created the topic TEST-TOPIC-GRPC-ASYNC by default, you can also create other topic to test) + +``` +Run the main method of org.apache.eventmesh.grpc.pub.eventmeshmessage.AsyncPublishInstance +``` + +- Start webhook subscriber + +``` +Run the main method of org.apache.eventmesh.grpc.sub.app.SpringBootDemoApplication +``` + +### 3.2 SYNC PUBLISH & STREAM SUBSCRIBE + +- Start Request-Reply publisher to publish message (we have created the topic TEST-TOPIC-GRPC-RR by default, you can also create other topic to test) + +``` +Run the main method of org.apache.eventmesh.grpc.pub.eventmeshmessage.RequestReplyInstance +``` + +- Start stream subscriber + +``` +Run the main method of org.apache.eventmesh.grpc.sub.EventmeshAsyncSubscribe +``` + +### 3.3 PUBLISH BATCH MESSAGE + +- Start publisher to publish batch message (we have created the TEST-TOPIC-GRPC-ASYNC by default, you can also create other topic to test) + +``` +Run the main method of org.apache.eventmesh.grpc.pub.eventmeshmessage.BatchPublishInstance +``` + +More information about EventMesh-gRPC, please refer to [EventMesh gRPC](docs/zh/sdk-java/04-grpc.md) + +## 4 Run these demos by yourself + +Please refer to [EventMesh Store](docs/zh/instruction/01-store.md) and [EventMesh Runtime](docs/zh/instruction/02-runtime.md) to finish the necessary deployment before try our demo + +After finishing the deployment of store and runtime, you can run our demos in module `eventmesh-examples`: + +### TCP Sub + + ```shell + cd bin + sh tcp_eventmeshmessage_sub.sh + ``` + +### TCP Pub + + ```shell + cd bin + sh tcp_pub_eventmeshmessage.sh + ``` + +### TCP Sub Broadcast + + ```shell + cd bin + sh tcp_sub_eventmeshmessage_broadcast.sh + ``` + +### TCP Pub Broadcast + + ```shell + cd bin + sh tcp_pub_eventmeshmessage_broadcast.sh + ``` + +### HTTP Sub + + ```shell + cd bin + sh http_sub.sh + ``` + +### HTTP Pub + + ```shell + cd bin + sh http_pub_eventmeshmessage.sh + ``` + +You can review the log in the folder `/logs` diff --git a/docs/en/instruction/_category_.json b/docs/en/instruction/_category_.json new file mode 100644 index 0000000000..690c6eb204 --- /dev/null +++ b/docs/en/instruction/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 2, + "label": "Installation and Deployment", + "collapsed": false +} diff --git a/docs/en/introduction.md b/docs/en/introduction.md new file mode 100644 index 0000000000..991f81e10e --- /dev/null +++ b/docs/en/introduction.md @@ -0,0 +1,42 @@ +--- +sidebar_position: 0 +--- + +# Introduction to EventMesh + +[![CI status](https://img.shields.io/github/workflow/status/apache/incubator-eventmesh/Continuous%20Integration?logo=github&style=for-the-badge)](https://github.com/apache/incubator-eventmesh/actions/workflows/ci.yml) +[![CodeCov](https://img.shields.io/codecov/c/gh/apache/incubator-eventmesh/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/apache/incubator-eventmesh) +[![Code Quality: Java](https://img.shields.io/lgtm/grade/java/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18&style=for-the-badge)](https://lgtm.com/projects/g/apache/incubator-eventmesh/context:java) +[![Total Alerts](https://img.shields.io/lgtm/alerts/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18&style=for-the-badge)](https://lgtm.com/projects/g/apache/incubator-eventmesh/alerts/) +[![License](https://img.shields.io/github/license/apache/incubator-eventmesh?style=for-the-badge)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![GitHub Release](https://img.shields.io/github/v/release/apache/eventmesh?style=for-the-badge)](https://github.com/apache/incubator-eventmesh/releases) +[![Slack Status](https://img.shields.io/badge/slack-join_chat-blue.svg?logo=slack&style=for-the-badge)](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-16y1n77va-q~JepYy3RqpkygDYmQaQbw) + +**Apache EventMesh (Incubating)** is a dynamic event-driven application runtime used to decouple the application and backend middleware layer, which supports a wide range of use cases that encompass complex multi-cloud, widely distributed topologies using diverse technology stacks. + +## Features + +- **Communication Protocol**: EventMesh could communicate with clients with TCP, HTTP, or gRPC. +- **CloudEvents**: EventMesh supports the [CloudEvents](https://cloudevents.io) specification as the format of the events. CloudEvents is a specification for describing event data in common formats to provide interoperability across services, platforms, and systems. +- **Schema Registry**: EventMesh implements a schema registry that receives and stores schemas from clients and provides an interface for other clients to retrieve schemas. +- **Observability**: EventMesh exposed a range of metrics, such as the average latency of the HTTP protocol and the number of delivered messages. The metrics could be collected and analyzed with Prometheus or OpenTelemetry. +- **Event Workflow Orchestration**: EventMesh Workflow could receive an event and decide which command to trigger next based on the workflow definitions and the current workflow state. The workflow definition could be written with the [Serverless Workflow](https://serverlessworkflow.io) DSL. + +## Components + +Apache EventMesh (Incubating) consists of multiple components that integrate different middlewares and messaging protocols to enhance the functionalities of the application runtime. + +- **eventmesh-runtime**: The middleware that transmits events between producers and consumers, which supports cloud-native apps and microservices. +- **eventmesh-sdk-java**: The Java SDK that supports HTTP, TCP, and [gRPC](https://grpc.io) protocols. +- **eventmesh-connector-plugin**: The collection of plugins that connects middlewares such as [Apache Kafka](https://kafka.apache.org), [Apache RocketMQ](https://rocketmq.apache.org), [Apache Pulsar](https://pulsar.apache.org/), and [Redis](https://redis.io). +- **eventmesh-registry-plugin**: The collection of plugins that integrate service registries such as [Nacos](https://nacos.io) and [etcd](https://etcd.io). +- **eventmesh-security-plugin**: The collection of plugins that implement security mechanisms, such as ACL (access control list), authentication, and authorization. +- **eventmesh-protocol-plugin**: The collection of plugins that implement messaging protocols, such as [CloudEvents](https://cloudevents.io) and [MQTT](https://mqtt.org). +- **eventmesh-admin**: The control plane that manages clients, topics, and subscriptions. + +## Contributors + +Each contributor has played an important role in promoting the robust development of Apache EventMesh (Incubating). We sincerely appreciate all contributors who have contributed code and documents. The following is the list of contributors in EventMesh-related repositories. + +- [apache/incubator-eventmesh](https://github.com/apache/incubator-eventmesh/graphs/contributors) +- [apache/incubator-eventmesh-site](https://github.com/apache/incubator-eventmesh-site/graphs/contributors) diff --git a/docs/en/metrics-tracing/01-prometheus.md b/docs/en/metrics-tracing/01-prometheus.md new file mode 100644 index 0000000000..1bc6e0e554 --- /dev/null +++ b/docs/en/metrics-tracing/01-prometheus.md @@ -0,0 +1,24 @@ +# Observe Metrics with Prometheus + +## Prometheus + +[Prometheus](https://prometheus.io/docs/introduction/overview/) is an open-source system monitoring and alerting toolkit that collects and stores the metrics as time-series data. EventMesh exposes a collection of metrics data that could be scraped and analyzed by Prometheus. Please follow [the "First steps with Prometheus" tutorial](https://prometheus.io/docs/introduction/first_steps/) to download and install the latest release of Prometheus. + +## Edit Prometheus Configuration + +The `eventmesh-runtime/conf/prometheus.yml` configuration file specifies the port of the metrics HTTP endpoint. The default metrics port is `19090`. + +```properties +eventMesh.metrics.prometheus.port=19090 +``` + +Please refer to [the Prometheus configuration guide](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) to add the EventMesh metrics as a scrape target in the configuration file. Here's the minimum configuration that creates a job with the name `eventmesh` and the endpoint `http://localhost:19090`: + +```yaml +scrape_configs: + - job_name: "eventmesh" + static_configs: + - targets: ["localhost:19090"] +``` + +Please navigate to the Prometheus dashboard (e.g. `http://localhost:9090`) to view the list of metrics exported by EventMesh, which are prefixed with `eventmesh_`. diff --git a/docs/en/metrics-tracing/02-zipkin.md b/docs/en/metrics-tracing/02-zipkin.md new file mode 100644 index 0000000000..f4d07252d7 --- /dev/null +++ b/docs/en/metrics-tracing/02-zipkin.md @@ -0,0 +1,38 @@ +# Collect Trace with Zipkin + +## Zipkin + +Distributed tracing is a method used to profile and monitor applications built with microservices architecture. Distributed tracing helps pinpoint where failures occur and what causes poor performance. + +[Zipkin](https://zipkin.io) is a distributed tracing system that helps collect timing data needed to troubleshoot latency problems in service architectures. EventMesh exposes a collection of trace data that could be collected and analyzed by Zipkin. Please follow [the "Zipkin Quickstart" tutorial](https://zipkin.io/pages/quickstart.html) to download and install the latest release of Zipkin. + +## Configuration + +To enable the trace exporter of EventMesh Runtime, set the `eventMesh.server.trace.enabled` field in the `conf/eventmesh.properties` file to `true`. + +```conf +# Trace plugin +eventMesh.server.trace.enabled=true +eventMesh.trace.plugin=zipkin +``` + +To customize the behavior of the trace exporter such as timeout or export interval, edit the `exporter.properties` file. + +```conf +# Set the maximum batch size to use +eventmesh.trace.max.export.size=512 +# Set the queue size. This must be >= the export batch size +eventmesh.trace.max.queue.size=2048 +# Set the max amount of time an export can run before getting(TimeUnit=SECONDS) +eventmesh.trace.export.timeout=30 +# Set time between two different exports (TimeUnit=SECONDS) +eventmesh.trace.export.interval=5 +``` + +To send the exported trace data to Zipkin, edit the `eventmesh.trace.zipkin.ip` and `eventmesh.trace.zipkin.port` fields in the `conf/zipkin.properties` file to match the configuration of the Zipkin server. + +```conf +# Zipkin's IP and Port +eventmesh.trace.zipkin.ip=localhost +eventmesh.trace.zipkin.port=9411 +``` diff --git a/docs/en/metrics-tracing/_category_.json b/docs/en/metrics-tracing/_category_.json new file mode 100644 index 0000000000..72c4414d12 --- /dev/null +++ b/docs/en/metrics-tracing/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 4, + "label": "Metrics and Tracing", + "collapsed": false +} diff --git a/docs/en/roadmap.md b/docs/en/roadmap.md new file mode 100644 index 0000000000..e890da3ffc --- /dev/null +++ b/docs/en/roadmap.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 1 +--- + +# Development Roadmap + +The development roadmap of Apache EventMesh (Incubating) is an overview of the planned features and milestones involved in the next several releases. The recent features and bug fixes are documented in the [release notes](https://eventmesh.apache.org/events/release-notes/v1.4.0). The order of the features listed below doesn't correspond to their priorities. + +## List of Features and Milestones + +| Status | Description | Reference | +| --- | --- | --- | +| **Implemented** | gRPC Integration | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/417) | +| **In Progress** | Event Governance for Choreography | [GitHub Issue](https://github.com/apache/incubator-eventmesh/blob/master/docs/en/features/eventmesh-workflow-design.md) | +| Planned | Knative Eventing Infrastructure | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/790), [GSoC '22](https://issues.apache.org/jira/browse/COMDEV-463) | +| Planned | Dashboard | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/700), [GSoC '22](https://issues.apache.org/jira/browse/COMDEV-465) | +| Planned | Event Streaming | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/676) | +| Planned | Federated Connector | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/577) | +| Planned | Transaction Event | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/697) | +| Planned | Event Query Language (EQL)| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/778) | +| Planned | Metadata consistency persistent| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/817) | +| Planned | Go SDK | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/762) | +| Planned | Rust SDK | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/815) | +| Planned | WebAssembly Runtime| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/576) | +| Planned | Filter Chain | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/664) | +| Planned | Kafka-based EventStore| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/199) | +| Planned | Redis-based EventStore| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/389) | diff --git a/docs/en/sdk-java/02-http.md b/docs/en/sdk-java/02-http.md new file mode 100644 index 0000000000..bf2e5c6efa --- /dev/null +++ b/docs/en/sdk-java/02-http.md @@ -0,0 +1,115 @@ +# HTTP Protocol + +EventMesh SDK for Java implements the HTTP producer and consumer of asynchronous messages. Both the producer and consumer require an instance of `EventMeshHttpClientConfig` class that specifies the configuration of EventMesh HTTP client. The `liteEventMeshAddr`, `userName`, and `password` fields should match the `eventmesh.properties` file of EventMesh runtime. + +```java +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +public class HTTP { + public static void main(String[] args) throws Exception { + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr("localhost:10105") + .producerGroup("TEST_PRODUCER_GROUP") + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())) + .userName("eventmesh") + .password("password") + .build(); + /* ... */ + } +} +``` + +## HTTP Consumer + +The `EventMeshHttpConsumer` class implements the `heartbeat`, `subscribe`, and `unsubscribe` methods. The `subscribe` method accepts a list of `SubscriptionItem` that defines the topics to be subscribed and a callback URL. + +```java +import org.apache.eventmesh.client.http.consumer.EventMeshHttpConsumer; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import com.google.common.collect.Lists; + +public class HTTP { + final String url = "http://localhost:8080/callback"; + final List topicList = Lists.newArrayList( + new SubscriptionItem("eventmesh-async-topic", SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC) + ); + + public static void main(String[] args) throws Exception { + /* ... */ + eventMeshHttpConsumer = new EventMeshHttpConsumer(eventMeshClientConfig); + eventMeshHttpConsumer.heartBeat(topicList, url); + eventMeshHttpConsumer.subscribe(topicList, url); + /* ... */ + eventMeshHttpConsumer.unsubscribe(topicList, url); + } +} +``` + +The EventMesh runtime will send a POST request that contains the message in the [CloudEvents format](https://github.com/cloudevents/spec) to the callback URL. The [`SubController.java` file](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/controller/SubController.java) implements a Spring Boot controller that receives and parses the callback messages. + +## HTTP Producer + +The `EventMeshHttpProducer` class implements the `publish` method. The `publish` method accepts the message to be published and an optional timeout value. The message should be an instance of either of these classes: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` +- `io.openmessaging.api.Message` + +```java +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.utils.JsonUtils; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class HTTP { + public static void main(String[] args) throws Exception { + /* ... */ + EventMeshHttpProducer eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject("eventmesh-async-topic") + .withSource(URI.create("/")) + .withDataContentType("application/cloudevents+json") + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + eventMeshHttpProducer.publish(event); + } +} +``` + +## Using Curl Command + +You can also publish/subscribe event without eventmesh SDK. + +### Publish + +```shell +curl -H "Content-Type:application/json" -X POST -d '{"name": "admin", "pass":"12345678"}' http://127.0.0.1:10105/eventmesh/publish/TEST-TOPIC-HTTP-ASYNC +``` + +After you start the eventmesh runtime server, you can use the curl command publish the event to the specific topic with the HTTP POST method and the package body must be in JSON format. The publish url like (http://127.0.0.1:10105/eventmesh/publish/TEST-TOPIC-HTTP-ASYNC), and you will get the publish successful result. + +### Subscribe + +```shell +curl -H "Content-Type:application/json" -X POST -d '{"url": "http://127.0.0.1:8088/sub/test", "consumerGroup":"TEST-GROUP", "topic":[{"mode":"CLUSTERING","topic":"TEST-TOPIC-HTTP-ASYNC","type":"ASYNC"}]}' http://127.0.0.1:10105/eventmesh/subscribe/local +``` + +After you start the eventmesh runtime server, you can use the curl command to subscribe the specific topic list with the HTTP POST method, and the package body must be in JSON format. The subscribe url like (http://127.0.0.1:10105/eventmesh/subscribe/local), and you will get the subscribe successful result. You should pay attention to the `url` field in the package body, which means you need to set up an HTTP service at the specified URL, you can see the example in the `eventmesh-examples` module. + diff --git a/docs/en/sdk-java/03-tcp.md b/docs/en/sdk-java/03-tcp.md new file mode 100644 index 0000000000..1643a41dca --- /dev/null +++ b/docs/en/sdk-java/03-tcp.md @@ -0,0 +1,118 @@ +# TCP Protocol + +EventMesh SDK for Java implements the TCP producer and consumer of synchronous, asynchronous, and broadcast messages. Both the producer and consumer require an instance of `EventMeshTCPClientConfig` class that specifies the configuration of EventMesh TCP client. The `host` and `port` fields should match the `eventmesh.properties` file of EventMesh runtime. + +```java +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import io.cloudevents.CloudEvent; + +public class AsyncSubscribe implements ReceiveMsgHook { + public static void main(String[] args) throws InterruptedException { + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + /* ... */ + } +} +``` + +## TCP Consumer + +The consumer should implement the `ReceiveMsgHook` class, which is defined in [`ReceiveMsgHook.java`](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/ReceiveMsgHook.java). + +```java +public interface ReceiveMsgHook { + Optional handle(ProtocolMessage msg); +} +``` + +The `EventMeshTCPClient` class implements the `subscribe` method. The `subscribe` method accepts the topic, the `SubscriptionMode`, and the `SubscriptionType`. The `handle` method will be invoked when the consumer receives a message from the topic it subscribes. If the `SubscriptionType` is `SYNC`, the return value of `handle` will be sent back to the producer. + +```java +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import io.cloudevents.CloudEvent; + +public class TCPConsumer implements ReceiveMsgHook { + public static TCPConsumer handler = new TCPConsumer(); + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + client = EventMeshTCPClientFactory.createEventMeshTCPClient( + eventMeshTcpClientConfig, + CloudEvent.class + ); + client.init(); + + client.subscribe( + "eventmesh-sync-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.SYNC + ); + + client.registerSubBusiHandler(handler); + client.listen(); + } + + @Override + public Optional handle(CloudEvent message) { + log.info("Messaged received: {}", message); + return Optional.of(message); + } +} +``` + +## TCP Producer + +### Asynchronous Producer + +The `EventMeshTCPClient` class implements the `publish` method. The `publish` method accepts the message to be published and an optional timeout value and returns the response message from the consumer. + +```java +/* ... */ +client = EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); +client.init(); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); +client.publish(event, 1000); +``` + +### Synchronous Producer + +The `EventMeshTCPClient` class implements the `rr` method. The `rr` method accepts the message to be published and an optional timeout value and returns the response message from the consumer. + +```java +/* ... */ +client = EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); +client.init(); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + +Package response = client.rr(event, 1000); +CloudEvent replyEvent = EventFormatProvider + .getInstance() + .resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(response.getBody().toString().getBytes(StandardCharsets.UTF_8)); +``` diff --git a/docs/en/sdk-java/04-grpc.md b/docs/en/sdk-java/04-grpc.md new file mode 100644 index 0000000000..81f03a8d83 --- /dev/null +++ b/docs/en/sdk-java/04-grpc.md @@ -0,0 +1,174 @@ +# gRPC Protocol + +EventMesh SDK for Java implements the gRPC producer and consumer of synchronous, asynchronous, and broadcast messages. Both the producer and consumer require an instance of `EventMeshGrpcClientConfig` class that specifies the configuration of EventMesh gRPC client. The `liteEventMeshAddr`, `userName`, and `password` fields should match the `eventmesh.properties` file of EventMesh runtime. + +```java +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import io.cloudevents.CloudEvent; + +public class CloudEventsAsyncSubscribe implements ReceiveMsgHook { + public static void main(String[] args) throws InterruptedException { + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr("localhost") + .serverPort(10205) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + /* ... */ + } +} +``` + +## gRPC Consumer + +### Stream Consumer + +The EventMesh runtime sends the message from producers to the stream consumer as a series of event streams. The consumer should implement the `ReceiveMsgHook` class, which is defined in [`ReceiveMsgHook.java`](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/ReceiveMsgHook.java). + +```java +public interface ReceiveMsgHook { + Optional handle(T msg) throws Throwable; + String getProtocolType(); +} +``` + +The `EventMeshGrpcConsumer` class implements the `registerListener`, `subscribe`, and `unsubscribe` methods. The `subscribe` method accepts a list of `SubscriptionItem` that defines the topics to be subscribed to. The `registerListener` accepts an instance of a class that implements the `ReceiveMsgHook`. The `handle` method will be invoked when the consumer receives a message from the topic it subscribes. If the `SubscriptionType` is `SYNC`, the return value of `handle` will be sent back to the producer. + +```java +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import io.cloudevents.CloudEvent; + +public class CloudEventsAsyncSubscribe implements ReceiveMsgHook { + public static CloudEventsAsyncSubscribe handler = new CloudEventsAsyncSubscribe(); + public static void main(String[] args) throws InterruptedException { + /* ... */ + SubscriptionItem subscriptionItem = new SubscriptionItem( + "eventmesh-async-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.ASYNC + ); + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + eventMeshGrpcConsumer.registerListener(handler); + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + /* ... */ + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(CloudEvent message) { + log.info("Messaged received: {}", message); + return Optional.empty(); + } + + @Override + public String getProtocolType() { + return EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME; + } +} +``` + +### Webhook Consumer + +The `subscribe` method of the `EventMeshGrpcConsumer` class accepts a list of `SubscriptionItem` that defines the topics to be subscribed and an optional callback URL. If the callback URL is provided, the EventMesh runtime will send a POST request that contains the message in the [CloudEvents format](https://github.com/cloudevents/spec) to the callback URL. The [`SubController.java` file](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/controller/SubController.java) implements a Spring Boot controller that receives and parses the callback messages. + +```java +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; + +@Component +public class SubService implements InitializingBean { + final String url = "http://localhost:8080/callback"; + + public void afterPropertiesSet() throws Exception { + /* ... */ + eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + eventMeshGrpcConsumer.init(); + + SubscriptionItem subscriptionItem = new SubscriptionItem( + "eventmesh-async-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.ASYNC + ); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem), url); + /* ... */ + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem), url); + } +} +``` + +## gRPC Producer + +### Asynchronous Producer + +The `EventMeshGrpcProducer` class implements the `publish` method. The `publish` method accepts the message to be published and an optional timeout value. The message should be an instance of either of these classes: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +```java +/* ... */ +EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); +eventMeshGrpcProducer.init(); + +Map content = new HashMap<>(); +content.put("content", "testAsyncMessage"); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); +eventMeshGrpcProducer.publish(event); +``` + +### Synchronous Producer + +The `EventMeshGrpcProducer` class implements the `requestReply` method. The `requestReply` method accepts the message to be published and an optional timeout value. The method returns the message returned from the consumer. The message should be an instance of either of these classes: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +### Batch Producer + +The `EventMeshGrpcProducer` class overloads the `publish` method, which accepts a list of messages to be published and an optional timeout value. The messages in the list should be an instance of either of these classes: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +```java +/* ... */ +List cloudEventList = new ArrayList<>(); +for (int i = 0; i < 5; i++) { + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + + cloudEventList.add(event); +} + +eventMeshGrpcProducer.publish(cloudEventList); +/* ... */ +``` diff --git a/docs/en/sdk-java/_category_.json b/docs/en/sdk-java/_category_.json new file mode 100644 index 0000000000..e93d4cdd8a --- /dev/null +++ b/docs/en/sdk-java/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 3, + "label": "EventMesh SDK for Java", + "collapsed": false +} diff --git a/docs/en/sdk-java/intro.md b/docs/en/sdk-java/intro.md new file mode 100644 index 0000000000..42b9c41942 --- /dev/null +++ b/docs/en/sdk-java/intro.md @@ -0,0 +1,29 @@ +# Installation + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java/badge.svg?style=for-the-badge)](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java) + +EventMesh SDK for Java is a collection of Java libraries to integrate EventMesh in a Java application. The SDK supports sending and receiving synchronous messages, asynchronous messages, and broadcast messages in TCP, HTTP, and gRPC protocols. The SDK implements EventMesh Message, CloudEvents, and OpenMessaging formats. The demo project is available in the [`eventmesh-example`](https://github.com/apache/incubator-eventmesh/tree/master/eventmesh-examples) module. + +## Gradle + +To install EventMesh SDK for Java with Gradle, declare `org.apache.eventmesh:eventmesh-sdk-java` as `implementation` in the dependencies block of the module's `build.gradle` file. + +```groovy +dependencies { + implementation 'org.apache.eventmesh:eventmesh-sdk-java:1.4.0' +} +``` + +## Maven + +To install EventMesh SDK for Java with Maven, declare `org.apache.eventmesh:eventmesh-sdk-java` as a dependency in the dependencies block of the project's `pom.xml` file. + +```xml + + + org.apache.eventmesh + eventmesh-sdk-java + 1.4.0 + + +``` diff --git a/docs/images/contact/wechat-assistant.jpg b/docs/images/contact/wechat-assistant.jpg new file mode 100644 index 0000000000..1ab02631fa Binary files /dev/null and b/docs/images/contact/wechat-assistant.jpg differ diff --git a/docs/images/contact/wechat-official.jpg b/docs/images/contact/wechat-official.jpg new file mode 100644 index 0000000000..deb5bfa29e Binary files /dev/null and b/docs/images/contact/wechat-official.jpg differ diff --git a/docs/images/design-document/async-message.png b/docs/images/design-document/async-message.png new file mode 100644 index 0000000000..4ad6ac4e03 Binary files /dev/null and b/docs/images/design-document/async-message.png differ diff --git a/docs/images/design-document/broadcast-message.png b/docs/images/design-document/broadcast-message.png new file mode 100644 index 0000000000..7c3be10c30 Binary files /dev/null and b/docs/images/design-document/broadcast-message.png differ diff --git a/docs/images/design-document/cloudevents-pluggable-protocols.png b/docs/images/design-document/cloudevents-pluggable-protocols.png new file mode 100644 index 0000000000..5b8b858f10 Binary files /dev/null and b/docs/images/design-document/cloudevents-pluggable-protocols.png differ diff --git a/docs/images/design-document/schema-registry-architecture.png b/docs/images/design-document/schema-registry-architecture.png new file mode 100644 index 0000000000..8de3fc3e05 Binary files /dev/null and b/docs/images/design-document/schema-registry-architecture.png differ diff --git a/docs/images/design-document/schema-registry-process.jpg b/docs/images/design-document/schema-registry-process.jpg new file mode 100644 index 0000000000..f914a81f0d Binary files /dev/null and b/docs/images/design-document/schema-registry-process.jpg differ diff --git a/docs/images/design-document/schema-registry-project-structure.png b/docs/images/design-document/schema-registry-project-structure.png new file mode 100644 index 0000000000..c12ac2b3e4 Binary files /dev/null and b/docs/images/design-document/schema-registry-project-structure.png differ diff --git a/docs/images/design-document/stream-architecture.png b/docs/images/design-document/stream-architecture.png new file mode 100644 index 0000000000..50d2ff9100 Binary files /dev/null and b/docs/images/design-document/stream-architecture.png differ diff --git a/docs/images/design-document/stream-component-interface.png b/docs/images/design-document/stream-component-interface.png new file mode 100644 index 0000000000..f8865f7d59 Binary files /dev/null and b/docs/images/design-document/stream-component-interface.png differ diff --git a/docs/images/design-document/stream-component-routes.png b/docs/images/design-document/stream-component-routes.png new file mode 100644 index 0000000000..98c8eb7509 Binary files /dev/null and b/docs/images/design-document/stream-component-routes.png differ diff --git a/docs/images/design-document/stream-event-driven-consumer.png b/docs/images/design-document/stream-event-driven-consumer.png new file mode 100644 index 0000000000..4be17f4746 Binary files /dev/null and b/docs/images/design-document/stream-event-driven-consumer.png differ diff --git a/docs/images/design-document/stream-sync-producer.png b/docs/images/design-document/stream-sync-producer.png new file mode 100644 index 0000000000..bb8771cfe5 Binary files /dev/null and b/docs/images/design-document/stream-sync-producer.png differ diff --git a/docs/images/design-document/sync-message.png b/docs/images/design-document/sync-message.png new file mode 100644 index 0000000000..b1c462fa51 Binary files /dev/null and b/docs/images/design-document/sync-message.png differ diff --git a/docs/images/design-document/tcp-protocol.png b/docs/images/design-document/tcp-protocol.png new file mode 100644 index 0000000000..d3c1249d53 Binary files /dev/null and b/docs/images/design-document/tcp-protocol.png differ diff --git a/docs/images/design-document/webhook/webhook-github-add.png b/docs/images/design-document/webhook/webhook-github-add.png new file mode 100644 index 0000000000..55e19cb614 Binary files /dev/null and b/docs/images/design-document/webhook/webhook-github-add.png differ diff --git a/docs/images/design-document/webhook/webhook-github-info.png b/docs/images/design-document/webhook/webhook-github-info.png new file mode 100644 index 0000000000..978b64eb90 Binary files /dev/null and b/docs/images/design-document/webhook/webhook-github-info.png differ diff --git a/docs/images/design-document/webhook/webhook-github-setting.png b/docs/images/design-document/webhook/webhook-github-setting.png new file mode 100644 index 0000000000..fa151313ce Binary files /dev/null and b/docs/images/design-document/webhook/webhook-github-setting.png differ diff --git a/docs/images/design-document/webhook/webhook-github-webhooks.png b/docs/images/design-document/webhook/webhook-github-webhooks.png new file mode 100644 index 0000000000..978b64eb90 Binary files /dev/null and b/docs/images/design-document/webhook/webhook-github-webhooks.png differ diff --git a/docs/images/design-document/workflow-architecture.jpg b/docs/images/design-document/workflow-architecture.jpg new file mode 100644 index 0000000000..1bbb691c07 Binary files /dev/null and b/docs/images/design-document/workflow-architecture.jpg differ diff --git a/docs/images/design-document/workflow-diagram.png b/docs/images/design-document/workflow-diagram.png new file mode 100644 index 0000000000..0c2c825dcc Binary files /dev/null and b/docs/images/design-document/workflow-diagram.png differ diff --git a/docs/images/design-document/workflow-use-case.jpg b/docs/images/design-document/workflow-use-case.jpg new file mode 100644 index 0000000000..124e7ec233 Binary files /dev/null and b/docs/images/design-document/workflow-use-case.jpg differ diff --git a/docs/images/eventmesh-arch.png b/docs/images/eventmesh-arch.png deleted file mode 100644 index 55ce5ddbb6..0000000000 Binary files a/docs/images/eventmesh-arch.png and /dev/null differ diff --git a/docs/images/eventmesh-architecture.png b/docs/images/eventmesh-architecture.png new file mode 100644 index 0000000000..5405afc593 Binary files /dev/null and b/docs/images/eventmesh-architecture.png differ diff --git a/docs/images/eventmesh-bridge.png b/docs/images/eventmesh-bridge.png new file mode 100644 index 0000000000..b8d1220f20 Binary files /dev/null and b/docs/images/eventmesh-bridge.png differ diff --git a/docs/images/eventmesh-define.png b/docs/images/eventmesh-define.png deleted file mode 100644 index f0c62d1b4d..0000000000 Binary files a/docs/images/eventmesh-define.png and /dev/null differ diff --git a/docs/images/eventmesh-orchestration.png b/docs/images/eventmesh-orchestration.png new file mode 100644 index 0000000000..40b28208a5 Binary files /dev/null and b/docs/images/eventmesh-orchestration.png differ diff --git a/docs/images/favicon.ico b/docs/images/favicon.ico new file mode 100644 index 0000000000..b6b6c2c6ef Binary files /dev/null and b/docs/images/favicon.ico differ diff --git a/docs/images/features/RR-call-p1.png b/docs/images/features/RR-call-p1.png deleted file mode 100644 index 2232df3e1f..0000000000 Binary files a/docs/images/features/RR-call-p1.png and /dev/null differ diff --git a/docs/images/features/a-distributing-architecture-in-financial-EN.png b/docs/images/features/a-distributing-architecture-in-financial-EN.png deleted file mode 100644 index 7e7b3d7f8d..0000000000 Binary files a/docs/images/features/a-distributing-architecture-in-financial-EN.png and /dev/null differ diff --git a/docs/images/features/a-distributing-architecture-in-financial.png b/docs/images/features/a-distributing-architecture-in-financial.png deleted file mode 100644 index d7eeb9d246..0000000000 Binary files a/docs/images/features/a-distributing-architecture-in-financial.png and /dev/null differ diff --git a/docs/images/features/adjust-queue-expand-p1.png b/docs/images/features/adjust-queue-expand-p1.png deleted file mode 100644 index 2660f3139b..0000000000 Binary files a/docs/images/features/adjust-queue-expand-p1.png and /dev/null differ diff --git a/docs/images/features/adjust-queue-shrink-p1.png b/docs/images/features/adjust-queue-shrink-p1.png deleted file mode 100644 index e4dc500f96..0000000000 Binary files a/docs/images/features/adjust-queue-shrink-p1.png and /dev/null differ diff --git a/docs/images/features/architecture-p1.png b/docs/images/features/architecture-p1.png deleted file mode 100644 index cda0b0433a..0000000000 Binary files a/docs/images/features/architecture-p1.png and /dev/null differ diff --git a/docs/images/features/broadcast.png b/docs/images/features/broadcast.png deleted file mode 100644 index 2cf528d988..0000000000 Binary files a/docs/images/features/broadcast.png and /dev/null differ diff --git a/docs/images/features/circuit-break-p1.png b/docs/images/features/circuit-break-p1.png deleted file mode 100644 index b3f55f75cd..0000000000 Binary files a/docs/images/features/circuit-break-p1.png and /dev/null differ diff --git a/docs/images/features/dark-launch-p1.png b/docs/images/features/dark-launch-p1.png deleted file mode 100644 index 08c04430b6..0000000000 Binary files a/docs/images/features/dark-launch-p1.png and /dev/null differ diff --git a/docs/images/features/invoke_nearby-p1.png b/docs/images/features/invoke_nearby-p1.png deleted file mode 100644 index 2aa0afe961..0000000000 Binary files a/docs/images/features/invoke_nearby-p1.png and /dev/null differ diff --git a/docs/images/features/multicast.png b/docs/images/features/multicast.png deleted file mode 100644 index 9643044457..0000000000 Binary files a/docs/images/features/multicast.png and /dev/null differ diff --git a/docs/images/features/subscribe-nearby-p1.png b/docs/images/features/subscribe-nearby-p1.png deleted file mode 100644 index d3a141922f..0000000000 Binary files a/docs/images/features/subscribe-nearby-p1.png and /dev/null differ diff --git a/docs/images/features/tongchengduohuo-p1.png b/docs/images/features/tongchengduohuo-p1.png deleted file mode 100644 index 663186ae1c..0000000000 Binary files a/docs/images/features/tongchengduohuo-p1.png and /dev/null differ diff --git a/docs/images/features/unicast.png b/docs/images/features/unicast.png deleted file mode 100644 index 1be62694eb..0000000000 Binary files a/docs/images/features/unicast.png and /dev/null differ diff --git a/docs/images/incubator-logo.png b/docs/images/incubator-logo.png new file mode 100644 index 0000000000..759252f001 Binary files /dev/null and b/docs/images/incubator-logo.png differ diff --git a/docs/images/logo.png b/docs/images/logo.png new file mode 100644 index 0000000000..e8545510d1 Binary files /dev/null and b/docs/images/logo.png differ diff --git a/docs/images/qqgroup-crcode.png b/docs/images/qqgroup-crcode.png deleted file mode 100644 index 10ca3c2aeb..0000000000 Binary files a/docs/images/qqgroup-crcode.png and /dev/null differ diff --git a/docs/images/wechat_helper.png b/docs/images/wechat_helper.png deleted file mode 100644 index 35c21a3f98..0000000000 Binary files a/docs/images/wechat_helper.png and /dev/null differ diff --git a/docs/zh/contribute/01-release.md b/docs/zh/contribute/01-release.md new file mode 100644 index 0000000000..0810a75772 --- /dev/null +++ b/docs/zh/contribute/01-release.md @@ -0,0 +1,731 @@ +# Release Creation Process + +:::caution +The documentation of Release Creation Process is WIP (Work-in-Progress). +::: + +## 理解 Apache 发布的内容和流程 + +Source Release 是 Apache 关注的重点,也是发布的必须内容;而 Binary Release 是可选项, + +请参考以下链接,找到更多关于 ASF 的发布指南: + +- [Apache Release Guide](http://www.apache.org/dev/release-publishing) +- [Apache Release Policy](http://www.apache.org/dev/release.html) +- [Maven Release Info](http://www.apache.org/dev/publishing-maven-artifacts.html) + + +## 本地构建环境准备 + +主要包括签名工具、Maven 仓库认证相关准备 + +### 1.安装GPG + +在[GnuPG官网](https://www.gnupg.org/download/index.html)下载安装包。GnuPG的1.x版本和2.x版本的命令有细微差别,下列说明以**GnuPG-2.x**版本为例 + +```sh +$ gpg --version #检查版本,应该为2.x +``` + +### 2.用gpg生成key + +根据提示,生成 key + +> 注意:请使用Apache邮箱生成GPG的Key + +```shell +$ gpg --full-gen-key +gpg (GnuPG) 2.0.12; Copyright (C) 2009 Free Software Foundation, Inc. +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Please select what kind of key you want: + (1) RSA and RSA (default) + (2) DSA and Elgamal + (3) DSA (sign only) + (4) RSA (sign only) +Your selection? 1 +RSA keys may be between 1024 and 4096 bits long. +What keysize do you want? (2048) 4096 +Requested keysize is 4096 bits +Please specify how long the key should be valid. + 0 = key does not expire + = key expires in n days + w = key expires in n weeks + m = key expires in n months + y = key expires in n years +Key is valid for? (0) +Key does not expire at all +Is this correct? (y/N) y + +GnuPG needs to construct a user ID to identify your key. + +Real name: ${输入用户名} +Email address: ${邮箱地址} +Comment: CODE SIGNING KEY +You selected this USER-ID: + "${输入用户名} (CODE SIGNING KEY) <${邮箱地址}>" + +Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O +You need a Passphrase to protect your secret key. # 填入密码,以后打包过程中会经常用到 +``` + +### 3.查看 key + +```shell +$ gpg --list-keys +pub rsa4096/579C25F5 2021-04-26 # 579C25F5就是key id +uid [ultimate] ${输入用户名} <${邮箱地址}> +sub rsa4096 2021-04-26 + +# 通过key id发送public key到keyserver +$ gpg --keyserver pgpkeys.mit.edu --send-key 579C25F5 +# 其中,pgpkeys.mit.edu为随意挑选的keyserver,keyserver列表为:https://sks-keyservers.net/status/,相互之间是自动同步的,选任意一个都可以。 +$ gpg --keyserver hkp://pgpkeys.mit.edu --recv-keys 579C25F5 # 验证是否同步到公网,网络不好可能需多试几次 +``` + +**注:如果有多个 public key,设置默认 key。**修改`~/.gnupg/gpg.conf` + +```sh +# If you have more than 1 secret key in your keyring, you may want to +# uncomment the following option and set your preferred keyid. +default-key 28681CB1 +``` + +**如果有多个 public key, 也可以删除无用的 key:** + +```shell +$ gpg --delete-secret-keys 29BBC3CB # 先删除私钥,指明key id +gpg (GnuPG) 2.2.27; Copyright (C) 2021 g10 Code GmbH +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +sec rsa4096/EE8DAE7D29BBC3CB 2021-04-27 mikexue + +Delete this key from the keyring? (y/N) y +This is a secret key! - really delete? (y/N) y +``` + +```shell +$ gpg --delete-keys 29BBC3CB # 删除公钥,指明key id +gpg (GnuPG) 2.2.27; Copyright (C) 2021 g10 Code GmbH +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + + +pub rsa4096/EE8DAE7D29BBC3CB 2021-04-27 mikexue + +Delete this key from the keyring? (y/N) y +``` + +由于公钥服务器没有检查机制,任何人都可以用你的名义上传公钥,所以没有办法保证服务器上的公钥的可靠性。 通常,你可以在网站上公布一个公钥指纹,让其他人核对下载到的公钥是否为真。 + +```shell +# fingerprint参数生成公钥指纹: +$gpg --fingerprint mikexue +pub rsa4096 2021-04-26 [SCA] + F84A 0041 D70B 37AF 9C7B F0B3 39F4 29D7 579C 25F5 +uid [ultimate] mikexue +sub rsa4096 2021-04-26 [E] +``` + +登录 [https://id.apache.org](https://id.apache.org/), 将上面的 fingerprint (即 F84A 0041 D70B 37AF 9C7B F0B3 39F4 29D7 579C 25F5) 粘贴到自己的用户信息中 OpenPGP Public Key Primary Fingerprint + + + +## 发布Apache Maven仓库 + +> 注:EventMesh使用Gradle构建,需修改gradle相关配置 + +### 1.导出私钥文件 + +```shell +$ gpg --export-secret-keys -o secring.gpg #私钥文件妥善保管,后面配置需要 +``` + +### 2.准备分支 + +从主干分支拉取新分支作为发布分支,如现在要发布$`{release_version}`版本,则从develop分支拉出新分支`${release_version}-release`,此后`${release_version}` Release Candidates涉及的修改及打标签等都在`${release_version}-release`分支进行,最终发布完成后合入主干分支。 + +### 3.更新版本说明 + +更新官网项目的如下文件,并提交至master分支: + +https://github.com/apache/incubator-eventmesh-site/tree/master/events/release-notes + +### 4.配置根项目下gradle.properties文件 + +```shell +group=org.apache.eventmesh +version=1.2.0-release +#40位公钥的最后8位 +signing.keyId=579C25F5 +#生成密钥时填的passphrase +signing.password= +#导出的私钥文件secring.gpg路径 +signing.secretKeyRingFile=../secring.gpg +#apache 账号 +apacheUserName= +#apache 密码 +apachePassWord= +``` + +### 5.检查子模块下gradle.properties文件 + +```shell +group=org.apache.eventmesh +version=${release_version} +``` + +### 6.检查并配置根项目下build.gradle文件 + +```shell +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + artifact packageSources + artifact packageJavadoc + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } + } + pom { + name = 'EventMesh' + description = 'Apache EventMesh' + url = 'https://github.com/apache/incubator-eventmesh' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'Apache EventMesh(incubating)' + name = 'Apache EventMesh(incubating) of ASF' + url = 'https://eventmesh.apache.org/' + } + } + scm { + connection = 'scm:git:git@github.com:apache/incubator-eventmesh.git' + developerConnection = 'scm:git:git@github.com:apache/incubator-eventmesh.git' + url = 'https://github.com/apache/incubator-eventmesh' + } + } + } + } + repositories { + maven { + def releasesRepoUrl = 'https://repository.apache.org/service/local/staging/deploy/maven2/' + def snapshotsRepoUrl = 'https://repository.apache.org/content/repositories/snapshots/' + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + credentials { + username apacheUserName + password apachePassWord + } + + } + } +} + +signing { + sign publishing.publications.mavenJava +} +``` + +### 7.上传发布包 + +执行如下命令,需要对jar、源码包、doc和pom等文件签名加密 + +```shell +$ gradle signMavenJavaPublication publish +``` + +上述命令执行成功后,待发布版本会自动上传到Apache的临时筹备仓库(staging repository)。所有被deploy到远程[maven仓库](http://repository.apache.org/)的Artifacts都会处于staging状态,访问https://repository.apache.org/#stagingRepositories, 使用Apache的LDAP账户登录后,就会看到上传的版本,`Repository`列的内容即为${STAGING.REPOSITORY}。 点击`Close`来告诉Nexus这个构建已经完成,只有这样该版本才是可用的。 如果电子签名等出现问题,`Close`会失败,可以通过`Activity`查看失败信息。 + + + +## 发布Apache SVN仓库 + +### 1.准备svn本机环境(Apache使用svn托管项目的发布内容) + +### 2.checkout到本地目录 + +```shell +$ svn checkout https://dist.apache.org/repos/dist/dev/incubator/eventmesh/ +# 假定本地目录为 ~/apache/eventmesh +``` + +### 3.添加gpg公钥 + +添加public key到[KEYS](https://dist.apache.org/repos/dist/dev/incubator/eventmesh/KEYS)文件并提交到SVN仓库(第一次做发布的人需要做这个操作,具体操作参考KEYS文件里的说明)。KEYS主要是让参与投票的人在本地导入,用来校验sign的正确性 + +Windows + +```sh +$ gpg --list-sigs | out-file -append KEYS -encoding utf8 +$ gpg --armor --export | out-file -append KEYS -encoding utf8 +``` + +> Mac OS/Linux + +```sh +$ (gpg --list-sigs && gpg --armor --export ) >> KEYS +``` + +### 4.添加待发布内容到SVN目录 + +```shell +$ cd ~/apache/eventmesh # eventmesh svn根目录 +$ mkdir ${release_version}-${rc_version} +``` + +#### 4.1 创建tag + +在`${release_version}-release`分支上创建tag,需带有rc版本,为预发布版本 + +```shell +$ git tag -a v{$release_version}-{$rc_version} -m "Tagging the ${release_version} first Release Candidate (Candidates start at zero)" +$ git push origin --tags +``` + +#### 4.2 打包源码 + +检查项目源码命名,将源码命名为`apache-eventmesh-${release_version}-incubating-src`,将源码打包为tar.gz格式 + +```shell +$ tar -czvf apache-eventmesh-${release_version}-incubating-source.tar.gz apache-eventmesh-${release_version}-incubating-src +``` + +#### 4.3 打包二进制 + +> 编译上一步打包的源码 + +检查编译后的文件命名,将二进制文件命名为`apache-eventmesh-${release_version}-incubating` + +> 注:需将源码根目录下的`NOTICE`文件,`DISCLAIMER-WIP`文件以及`tools/third-party-licenses`目录下的`LICENSE`文件拷贝到二进制的包中 + +```shell +$ gradle clean jar dist && gradle installPlugin && gradle tar -x test +$ tar -czvf apache-eventmesh-${release_version}-incubating-bin.tar.gz apache-eventmesh-${release_version}-incubating +``` + +压缩source包、bin包,并将相关的压缩包拷贝到svn本地仓库下`/apache/eventmesh/${release_version}-${rc_version}` + +### 5.生成签名/sha512文件 + +> 针对源码包与二进制包生成签名/sha512文件 + +```shell +$ for i in *.tar.gz; do echo $i; gpg --print-md SHA512 $i > $i.sha512 ; done #计算sha512 +$ for i in *.tar.gz; do echo $i; gpg --armor --output $i.asc --detach-sig $i ; done #计算签名 +``` + +### 6.提交到Apache svn + +```shell +$ cd ~/apache/eventmesh # eventmesh svn根目录 +$ svn status +$ svn commit -m 'prepare for ${release_version}-${rc_version}' +``` + + + +## 验证Release Candidates + +详细检查列表请参考官方的[check list](https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist) + +从以下地址下载要发布的Release Candidates到本地环境: + +```shell +https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version}/ +``` + +然后开始验证环节,验证包含但不限于以下内容和形式 + +### 1.检查签名和hash等信息 + +> 由于操作系统不同,检查的命令或有差异,具体可参考[官方检查步骤](https://www.apache.org/info/verification.html) + +#### 1.1检查sha512哈希 + +> Mac OS/Linux + +```shell +$ shasum -a apache-eventmesh-${release_version}-incubating-source.tar.gz +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-source.tar.gz.sha512文件内容作对比 +$ shasum -a apache-eventmesh-${release_version}-incubating-bin.tar.gz +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-bin.tar.gz.sha512文件内容作对比 +``` + +> Windows + +```shell +$ certUtil -hashfile apache-eventmesh-${release_version}-incubating-source.tar.gz SHA512 +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-source.tar.gz.sha512文件内容作对比 +$ certUtil -hashfile apache-eventmesh-${release_version}-incubating-bin.tar.gz SHA512 +#并将输出内容与 apache-eventmesh-${release_version}-${rc_version}-incubating-bin.tar.gz.sha512文件内容作对比 +``` + +#### 1.2检查gpg签名 + +首先导入发布人公钥。从svn仓库导入KEYS到本地环境。(发布版本的人不需要再导入,帮助做验证的人需要导入,用户名填发版人的即可) + +```shell +$ curl https://dist.apache.org/repos/dist/dev/incubator/eventmesh/KEYS >> KEYS +$ gpg --import KEYS +$ gpg --edit-key "${发布人的gpg用户名}" + > trust + +Please decide how far you trust this user to correctly verify other users' keys +(by looking at passports, checking fingerprints from different sources, etc.) + + 1 = I don't know or won't say + 2 = I do NOT trust + 3 = I trust marginally + 4 = I trust fully + 5 = I trust ultimately + m = back to the main menu + +Your decision? 5 + + > save +``` + +然后使用如下命令检查签名 + +```shell +$ gpg --verify apache-eventmesh-${release_version}-incubating-source.tar.gz.asc apache-eventmesh-${release_version}-incubating-source-tar.gz +$ gpg --verify apache-eventmesh-${release_version}-incubating-bin.tar.gz.asc apache-eventmesh-${release_version}-incubating-bin.tar.gz +``` + +### 2.检查源码包的文件内容 + +解压缩`apache-eventmesh-${release_version}-incubating-source-tar.gz`,进行如下检查: + +- 检查源码包是否包含由于包含不必要文件,致使tar包过于庞大 +- 文件夹包含单词`incubating` +- 存在`LICENSE`和`NOTICE`文件 +- 存在`DISCLAIMER`文件 +- `NOTICE`文件中的年份正确 +- 只存在文本文件,不存在二进制文件 +- 所有文件的开头都有ASF许可证 +- 能够正确编译,单元测试可以通过 (./gradle build) (目前支持JAVA 8/gradle 7.0/idea 2021.1.1及以上) +- 检查是否有多余文件或文件夹,例如空文件夹等 + +### 3.检查二进制包的文件内容 + +- 文件夹包含单词`incubating` +- 存在`LICENSE`和`NOTICE`文件 +- 存在`DISCLAIMER`文件 +- `NOTICE`文件中的年份正确 +- 所有文本文件开头都有ASF许可证 +- 检查第三方依赖许可证: + - 第三方依赖的许可证兼容 + - 所有第三方依赖的许可证都在`LICENSE`文件中声名 + - 依赖许可证的完整版全部在`license`目录 + - 如果依赖的是Apache许可证并且存在`NOTICE`文件,那么这些`NOTICE`文件也需要加入到版本的`NOTICE`文件中 + +你可以参考此文章:[ASF第三方许可证策](https://apache.org/legal/resolved.html) + +## 发起投票 + +> EventMesh 仍在孵化阶段,需要进行两次投票 + +- EventMesh社区投票,发送邮件至:`dev@eventmesh.apache.org` +- incubator社区投票,发送邮件至:`general@incubator.apache.org` EventMesh毕业后,只需要在EventMesh社区投票 + +### 1.EventMesh社区投票阶段 + +1. EventMesh社区投票,发起投票邮件到`dev@eventmesh.apache.org`。PMC需要先按照文档检查版本的正确性,然后再进行投票。 经过至少72小时并统计到3个`+1 PMC member`票后,即可进入下一阶段的投票。 +2. 宣布投票结果,发起投票结果邮件到`dev@eventmesh.apache.org`。 + +### 2.EventMesh社区投票模板 + +标题: + +``` +[VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +正文: + +``` +Hello EventMesh Community, + + This is a call for vote to release Apache EventMesh (incubating) version ${release_version}-${rc_version}. + + Release notes: + https://github.com/apache/incubator-eventmesh/releases/tag/v${release_version}-${rc_version} + + The release candidates: + https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version}/ + + Maven artifacts are available in a staging repository at: + https://repository.apache.org/content/repositories/orgapacheeventmesh-{staging-id} + + Git tag for the release: + https://github.com/apache/incubator-eventmesh/tree/v${release_version}-${rc_version} + + Keys to verify the Release Candidate: + https://downloads.apache.org/incubator/eventmesh/KEYS + + Hash for the release tag: + #hashCode of this release tag + + GPG user ID: + ${YOUR.GPG.USER.ID} + + The vote will be open for at least 72 hours or until necessary number of votes are reached. + + Please vote accordingly: + + [ ] +1 approve + + [ ] +0 no opinion + + [ ] -1 disapprove with the reason + + Checklist for reference: + + [ ] Download links are valid. + + [ ] Checksums and PGP signatures are valid. + + [ ] Source code distributions have correct names matching the current release. + + [ ] LICENSE and NOTICE files are correct for each EventMesh repo. + + [ ] All files have license headers if necessary. + + [ ] No compiled archives bundled in source archive. + + More detail checklist please refer: + https://cwiki.apache.org/confluence/display/INCUBATOR/Incubator+Release+Checklist + +Thanks, +Your EventMesh Release Manager +``` + +### 3.宣布投票结果模板 + +标题: + +``` +[RESULT][VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +正文: + +``` +Hello Apache EventMesh PPMC and Community, + + The vote closes now as 72hr have passed. The vote PASSES with + + xx (+1 non-binding) votes from the PPMC, + xx (+1 binding) votes from the IPMC, + xx (+1 non-binding) votes from the rest of the developer community, + and no further 0 or -1 votes. + + The vote thread: {vote_mail_address} + + I will now bring the vote to general@incubator.apache.org to get approval by the IPMC. + If this vote passes also, the release is accepted and will be published. + +Thank you for your support. +Your EventMesh Release Manager +``` + +### 4.Incubator社区投票阶段 + +1. Incubator社区投票,发起投票邮件到`general@incubator.apache.org`,需3个 `+1 IPMC Member`投票,方可进入下一阶段。 +2. 宣布投票结果,发起投票结果邮件到`general@incubator.apache.org` 并抄送至`dev@eventmesh.apache.org`。 + +### 5.Incubator社区投票模板 + +标题: + +``` +[VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +内容: + +``` +Hello Incubator Community, + + This is a call for a vote to release Apache EventMesh(Incubating) version ${release_version} ${rc_version} + + The Apache EventMesh community has voted on and approved a proposal to release + Apache EventMesh(Incubating) version ${release_version} ${rc_version} + + We now kindly request the Incubator PMC members review and vote on this + incubator release. + + EventMesh community vote thread: + • [投票链接] + + Vote result thread: + • [投票结果链接] + + The release candidate: + •https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version}/ + + Git tag for the release: + • https://github.com/apache/incubator-eventmesh/tree/${release_version}-${rc_version} + Release notes: + • https://github.com/apache/incubator-eventmesh/releases/tag/${release_version}-${rc_version} + + The artifacts signed with PGP key [填写你个人的KEY], corresponding to [填写你个人的邮箱], that can be found in keys file: + • https://downloads.apache.org/incubator/eventmesh/KEYS + + The vote will be open for at least 72 hours or until necessary number of votes are reached. + + Please vote accordingly: + + [ ] +1 approve + [ ] +0 no opinion + [ ] -1 disapprove with the reason + +Thanks, +On behalf of Apache EventMesh(Incubating) community +``` + +### 6.宣布投票结果模板 + +标题: + +``` +[RESULT][VOTE] Release Apache EventMesh (incubating) ${release_version} ${rc_version} +``` + +内容: + +``` +Hi all, + + Thanks for reviewing and voting for Apache EventMesh(Incubating) version ${release_version} ${rc_version} release, I am happy to announce the release voting has passed with [投票结果数] binding votes, no +0 or -1 votes. + + Binding votes are from IPMC + - xxx + - xxx + - xxx + + Non-binding votes: + +1 xxx + +0 xxx + -1 xxx + + The voting thread is: + • [投票结果链接] + + Many thanks for all our mentors helping us with the release procedure, and all IPMC helped us to review and vote for Apache EventMesh(Incubating) release. I will be working on publishing the artifacts soon. + +Thanks, +On behalf of Apache EventMesh(Incubating) community +``` + +## 正式发布 + +### 1.合并分支 + +合并`${release_version}-release`分支的改动到`master`分支,合并完成后删除`release`分支 + +```shell +$ git checkout master +$ git merge origin/${release_version}-release +$ git pull +$ git push origin master +$ git push --delete origin ${release_version}-release +$ git branch -d ${release_version}-release +``` + +### 2.迁移源码与二进制包 + +将源码和二进制包从svn的`dev`目录移动到`release`目录 + +```shell +$ svn mv https://dist.apache.org/repos/dist/dev/incubator/eventmesh/${release_version}-${rc_version} https://dist.apache.org/repos/dist/release/incubator/eventmesh/ -m "transfer packages for ${release_version}-${rc_version}" #移动源码包与二进制包 +$ svn delete https://dist.apache.org/repos/dist/release/incubator/eventmesh/KEYS -m "delete KEYS" #清除原有release目录下的KEYS +$ svn cp https://dist.apache.org/repos/dist/dev/incubator/eventmesh/KEYS https://dist.apache.org/repos/dist/release/incubator/eventmesh/ -m "transfer KEYS for ${release_version}-${rc_version}" #拷贝dev目录KEYS到release目录 +``` + +### 3.确认dev和release下的包是否正确 + +- 确认[dev](https://dist.apache.org/repos/dist/dev/incubator/eventmesh/)下的`${release_version}-${rc_version}`已被删除 +- 删除[release](https://dist.apache.org/repos/dist/release/incubator/eventmesh/)目录下上一个版本的发布包,这些包会被自动保存在[这里](https://archive.apache.org/dist/incubator/eventmesh/) + +```shell +$ svn delete https://dist.apache.org/repos/dist/release/incubator/eventmesh/${last_release_version} -m "Delete ${last_release_version}" +``` + +### 4.在Apache Staging仓库发布版本 + +- 登录http://repository.apache.org , 使用Apache账号登录 +- 点击左侧的Staging repositories, +- 搜索EventMesh关键字,选择你最近上传的仓库,投票邮件中指定的仓库 +- 点击上方的`Release`按钮,这个过程会进行一系列检查 + +> 等仓库同步到其他数据源,一般需要24小时 + +### 5.GitHub版本发布 + +1.Tag the commit (on which the vote happened) with the release version without `-${RELEASE_CANDIDATE}`. 例如:after a successful vote on `v1.2-rc5`, the hash will be tagged again with `v1.2` only. + +2.在 [GitHub Releases](https://github.com/apache/incubator-eventmesh/releases) 页面的 `${release_version}` 版本上点击 `Edit` + +编辑版本号及版本说明,并点击 `Publish release` + +### 6.更新下载页面 + +等待并确认新的发布版本同步至 Apache 镜像后,更新如下页面: + +https://eventmesh.apache.org/download/ + +https://eventmesh.apache.org/zh/download/ + +GPG签名文件和哈希校验文件的下载连接应该使用这个前缀:`https://downloads.apache.org/incubator/eventmesh/` + +> 注意:项目下载链接应该使用 https://www.apache.org/dyn/closer.lua 而不是 closer.cgi 或者 mirrors.cgi + +### 7.邮件通知版本发布完成 + +> 请确保Apache Staging仓库已发布成功,一般是在该步骤的24小时后发布邮件 + +发邮件到 `dev@eventmesh.apache.org` 、 `announce@apache.org`和`general@incubator.apache.org` + +标题: + +``` +[ANNOUNCE] Apache EventMesh (incubating) ${release_version} available +``` + +正文: + +``` +Hi all, + +Apache EventMesh (incubating) Team is glad to announce the new release of Apache EventMesh (incubating) ${release_version}. + +Apache EventMesh (incubating) is a dynamic cloud-native eventing infrastructure used to decouple the application and backend middleware layer, which supports a wide range of use cases that encompass complex multi-cloud, widely distributed topologies using diverse technology stacks. + +Download Links: https://eventmesh.apache.org/projects/eventmesh/download/ + +Release Notes: https://eventmesh.apache.org/events/release-notes/v${release_version}/ + +Website: https://eventmesh.apache.org/ + +EventMesh Resources: +- Issue: https://github.com/apache/incubator-eventmesh/issues +- Mailing list: dev@eventmesh.apache.org + + + +Apache EventMesh (incubating) Team +``` + diff --git a/docs/zh/contribute/02-write-unit-test.md b/docs/zh/contribute/02-write-unit-test.md new file mode 100644 index 0000000000..0c48e46bc6 --- /dev/null +++ b/docs/zh/contribute/02-write-unit-test.md @@ -0,0 +1,77 @@ +# Unit Test Requirement + +- Each unit test case should use assertions instead of `System.out` output or `if` statement +- Each unit test case shouldn't call other cases or depend on the order of execution. +- Each unit test case should be repeatable and not depend on the external environment because the test might be executed in the continuous integration. +- The scope of each unit test should be small enough to help locate the problem at the method level. + +## Location and Naming Rules + +- The unit test should be placed in `src/test/java`. +- The unit test configuration file should be placed in `src/test/resources`. For example: + - Class to be tested: `src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBody.java` + - Unit test: `src/test/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBodyTest.java` + - Unit test configuration: `src/test/resources/configuration.properties` +- The package name of the unit test class should be identical to the class to be tested. +- The name of the unit test class should be `{class or interface to be tested}Test`. For example: + - Class to be tested: `EventMeshUtil` + - Unit test class: `EventMeshUtilTest` +- The name of each test case should be `test{method name}`. For example: + - Method to be tested: `addProp(String key, String val)` + - Unit test case: `testAddProp` + +## Assertion Usage + +### Common Assertion + +| Methods | Instructions | +| :-------------- | :-------------- | +| `assertEquals` | Determines whether two objects or primitive types are equal | +| `assertNotEquals` | Determines whether two objects or primitive types are not equal | +| `assertTrue` | Determines whether the given Boolean value is `true` | +| `assertFalse` | Determines whether the given Boolean value is `false` | +| `assertNull` | Determines whether the given object reference is `null` | +| `assertNotNull` | Determines whether the given object reference is not `null` | +| `assertAll` | When multiple decision logic are processed together if only one error is reported, the whole test will fail | + +### Example + +#### `assertEquals()` + +```java +configuration.init(); +Assert.assertEquals("value1", configuration.eventMeshEnv); +``` + +#### `assertTrue()` + +```java +BaseResponseHeader header = BaseResponseHeader.buildHeader("200"); +Assert.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); +``` + +#### `assertFalse()` + +```java +Class nacosRegistryServiceClass = NacosRegistryService.class; +Field initStatus = nacosRegistryServiceClass.getDeclaredField("INIT_STATUS"); +initStatus.setAccessible(true); +Object initStatusField = initStatus.get(nacosRegistryService); +Assert.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); +``` + +#### `assertNull()` + +```java +DefaultFullHttpResponse response = httpCommand.httpResponse(); +Assert.assertNull(response); +``` + +#### `assertNotNull()` + +```java +Codec.Decoder cd = new Codec.Decoder(); +ArrayList result = new ArrayList<>(); +cd.decode(null, buf, result); +Assert.assertNotNull(result.get(0)); +``` diff --git a/docs/zh/contribute/03-new-contributor-guidelines.md b/docs/zh/contribute/03-new-contributor-guidelines.md new file mode 100644 index 0000000000..8c63375c35 --- /dev/null +++ b/docs/zh/contribute/03-new-contributor-guidelines.md @@ -0,0 +1,145 @@ + +# How to Contribution + +If you are a new contributor who wants to contribute to the eventmesh community, please read this document, which describes how to contribute to the community, and if you find any questions in the document, feel free to leave comments or suggestions. + +## Preparation + +### Development environment + +- You should have the JDK installed in your development environment. + +### Code Style + +Import [EventMesh CheckStyle](https://github.com/apache/incubator-eventmesh/blob/master/style/checkStyle.xml) file to your IDEA. + +For IDEA, you can import check style file by: +```shell + Editor -> Code Style -> Java -> Scheme -> Import Scheme -> CheckStyle Configuration +``` + +If you can't see CheckStyle Configuration section under Import Scheme, you can install CheckStyle-IDEA plugin first, and you will see it. + +You can also use `./gradlew check` to check the code style. +(Note: this command will check all file in project, when you submit a pr, the ci will only check the file has been changed in this pr). + +### Workflow + +Here are the workflow for contributors: + +1. Fork to your own + +2. Clone fork to local repository +```git +git clone git@github.com:yourgithub/incubator-eventmesh.git +``` + +3. Create a new branch and work on it +```git +git checkout -b fix_patch_xx +``` + +4. Keep your branch in sync +```git +git remote add upstream git@github.com:apache/incubator-eventmesh.git +git fetch upstream develop:upstream_develop +git rebase upstream_develop +``` + +5. Commit your changes (make sure your commit message concise) + +6. Push your commits to your forked repository + +7. Create a pull request + +## Explanation + +The original warehouse: https://github.com/apache/incubator-eventmesh The apache warehouse of eventmesh is called the original warehouse in the text. + +The Fork library: From https://github.com/apache/eventmesh fork to your own personal repository to become a fork library. + +So fork the original EventMesh repository into your own repository. + +## Development branch + +**The current development branch of eventmesh is Master. Please submit PR to this branch.** + +- We recommend that you create a new branch in your repository for development and submit the branch to the master branch of eventmesh. + +## Contribution Categories + +### Bug feedback or bug fixes + +- Whether it's a bug feedback or a fix, an issue needs to be created first to describe the bug in detail, so that the community can easily find and view the problem and code through the issue record. bug feedback issues usually need to contain a complete description of the bug information and reproducible scenarios. + +### Implementation of functions, refactoring + +- If you plan to implement a new feature (or refactoring), be sure to communicate with the eventmesh core development team via an Issue or other means, and describe the new feature (or refactoring), mechanism and scenario in detail during the communication process. + +### Documentation Improvement + +- You can find the eventmesh documentation at [evenmesh-docs](https://github.com/apache/incubator-eventmesh/tree/master/docs), and the documentation is supplemented or improved in a way that is also essential for eventmesh. + +## Contribution method + +There are two ways for new contributors to contribute to the eventmesh community: + +- If you find a bug in the eventmesh code that you want to fix, or if you provide a new feature for the eventmesh, submit an issue in the eventmesh and submit a pr to the eventmesh. + +- Other contributors in the eventmesh community have raised issues, the [`issue for first-time contributors`](https://github.com/apache/incubator-eventmesh/issues/888) sorted out by the community here are relatively simple PR, which can help you familiarize yourself with the process of making contributions to the eventmesh community. + +## Submit issue guidelines + +- If you don't know how to raise an issue on eventmesh, please read [about the issue](https://docs.github.com/cn/issues/tracking-your-work-with-issues/quickstart). + +- In the eventmesh community, there are issue templates that can be used for reference, if the type matches please use the template, if the issue template does not meet your requirements, you can open an empty issue template, for the issue please bring its matching feature labels. + +- For the name of the issue, please briefly describe your question or purpose in one sentence, and write in English for better global communication. + +## pull request (pr) submission guidelines + +- If you don't know how to initiate a pr for eventmesh, please see [about pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). + +- Whether it's a bug fix, or a new feature development (if this pr is a new feature development, then documentation updates about the new feature should be included in this pr), please submit a PR to the current development branch master. + +- The pr submission should follow the template provided by eventmesh as well as the need to write the submission information, a brief description of what the pr you are submitting does is sufficient, please see the [template for details](https://github.com/apache/incubator-eventmesh/blob/master/.github/PULL_REQUEST_TEMPLATE.md). + +- The pr you submit needs to be associated with the issue you are fixing, or the issue you are raising,so your PR title should start with [ISSUE #xx]. + +- If your change is about a typo or small optimize, you needn't create an Issue, just submit a PR and title with [MINOR]. + +**Note:** + + - A single pull request should not be too large. If heavy changes are required, it's better to separate the changes to a few individual PRs. + + - After creating a PR, one or more committers will help to review the pull request, after approve, this PR will be merged in to eventmesh repository, and the related Issue will be closed. + +## review + +### PR review + +All code should be well reviewed by one or more committers. Some principles: + +- Readability: Important code should be well-documented. Comply with our [code style](https://github.com/apache/incubator-eventmesh/blob/master/style/checkStyle.xml). + +- Elegance: New functions, classes or components should be well-designed. + +- Testability: Important code should be well-tested (high unit test coverage). + +### License review + +EventMesh follows [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) policy. All source files should +have the Apache License header added to the file header. EventMesh uses the [apache/skywalking-eyes](https://github.com/apache/skywalking-eyes) to check +the source file header. + +### PR merge + +After a PR is approved by at least one committer, it can be merged. Before the merge, the committer can make changes to the commits message, requiring the commits +message to be clear without duplication, and use Squash and Merge to make sure one PR should only contain one commits. +For large multi-person PR, use Merge to merge, and fix the commits by rebase before merging. + +## Community + +### Contact us + +Mail: dev@eventmesh.apache.org \ No newline at end of file diff --git a/docs/zh/contribute/_category_.json b/docs/zh/contribute/_category_.json new file mode 100644 index 0000000000..56d36f918e --- /dev/null +++ b/docs/zh/contribute/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 5, + "label": "Contribute", + "collapsed": false +} diff --git a/docs/zh/desing-document/02-runtime-protocol.md b/docs/zh/desing-document/02-runtime-protocol.md new file mode 100644 index 0000000000..d5f155602f --- /dev/null +++ b/docs/zh/desing-document/02-runtime-protocol.md @@ -0,0 +1,420 @@ +# TCP协议文档 + +#### 1. 协议格式 + +![dataFlow](../../images/design-document/tcp-protocol.png) + +**消息组成详解:** + +``` +魔术字:9位,当前值为“EventMesh” + +通信协议版本号:4位,当前值为“0000” + +消息总长度值(length):4位,int类型 + +消息头长度值(headerLength):4位,int类型 + +消息头(header):长度 = headerLength + +消息体(body):长度 = length - headerLength - 4 - 4 +``` + +#### 2. 业务逻辑层 + ++ 消息组成 + +消息头(header)+ 消息体(body) + +```java +public class Package { + + private Header header; + private Object body; +} + + +public class Header { + + private Command cmd; + private int code; + private String msg; + private String seq; +} +``` + ++ 详解 + +消息头(header):类型为Header,Header中有Command字段,用于区分不同的消息类型 + +消息体(body):对于不同的消息类型,body的类型不同 + +| 消息命令字 | body类型 | +| ------------------------------------------------------------ | ------------ | +| HEARTBEAT_REQUEST, HEARTBEAT_RESPONSE, HELLO_RESPONSE, CLIENT_GOODBYE_REQUEST, CLIENT_GOODBYE_RESPONSE, SERVER_GOODBYE_REQUEST, SERVER_GOODBYE_RESPONSE, LISTEN_REQUEST, LISTEN_RESPONSE, UNSUBSCRIBE_REQUEST, SUBSCRIBE_RESPONSE, UNSUBSCRIBE_RESPONSE, ASYNC_MESSAGE_TO_SERVER_ACK, BROADCAST_MESSAGE_TO_SERVER_ACK | 无 | +| HELLO_REQUEST | UserAgent | +| SUBSCRIBE_REQUEST | Subscription | +| REQUEST_TO_SERVER, REQUEST_TO_CLIENT, RESPONSE_TO_SERVER, RESPONSE_TO_CLIENT, ASYNC_MESSAGE_TO_SERVER, ASYNC_MESSAGE_TO_CLIENT, BROADCAST_MESSAGE_TO_SERVER, BROADCAST_MESSAGE_TO_CLIENT, ASYNC_MESSAGE_TO_CLIENT_ACK, BROADCAST_MESSAGE_TO_CLIENT_ACK, RESPONSE_TO_CLIENT_ACK, REQUEST_TO_CLIENT_ACK | OpenMessage | +| REDIRECT_TO_CLIENT | RedirectInfo | + +#### 3. Client 与 Eventmesh-Runtime(Server)交互场景详解 + +```java +public enum Command { + + //心跳 + HEARTBEAT_REQUEST(0), //client发给server的心跳包 + HEARTBEAT_RESPONSE(1), //server回复client的心跳包 + + //握手 + HELLO_REQUEST(2), //client发给server的握手请求 + HELLO_RESPONSE(3), //server回复client的握手请求 + + //断连 + CLIENT_GOODBYE_REQUEST(4), //client主动断连时通知server + CLIENT_GOODBYE_RESPONSE(5), //server回复client的主动断连通知 + SERVER_GOODBYE_REQUEST(6), //server主动断连时通知client + SERVER_GOODBYE_RESPONSE(7), //client回复server的主动断连通知 + + //订阅管理 + SUBSCRIBE_REQUEST(8), //client发给server的订阅请求 + SUBSCRIBE_RESPONSE(9), //server回复client的订阅请求 + UNSUBSCRIBE_REQUEST(10), //client发给server的取消订阅请求 + UNSUBSCRIBE_RESPONSE(11), //server回复client的取消订阅请求 + + //监听 + LISTEN_REQUEST(12), //client发给server的启动监听请求 + LISTEN_RESPONSE(13), //server回复client的监听请求 + + //RR + REQUEST_TO_SERVER(14), //client将RR请求发送给server + REQUEST_TO_CLIENT(15), //server将RR请求推送给client + REQUEST_TO_CLIENT_ACK(16), //client收到RR请求后ACK给server + RESPONSE_TO_SERVER(17), //client将RR回包发送给server + RESPONSE_TO_CLIENT(18), //server将RR回包推送给client + RESPONSE_TO_CLIENT_ACK(19), //client收到回包后ACK给server + + //异步事件 + ASYNC_MESSAGE_TO_SERVER(20), //client将异步事件发送给server + ASYNC_MESSAGE_TO_SERVER_ACK(21), //server收到异步事件后ACK给client + ASYNC_MESSAGE_TO_CLIENT(22), //server将异步事件推送给client + ASYNC_MESSAGE_TO_CLIENT_ACK(23), //client收到异步事件后ACK给server + + //广播 + BROADCAST_MESSAGE_TO_SERVER(24), //client将广播消息发送给server + BROADCAST_MESSAGE_TO_SERVER_ACK(25), //server收到广播消息后ACK给client + BROADCAST_MESSAGE_TO_CLIENT(26), //server将广播消息推送给client + BROADCAST_MESSAGE_TO_CLIENT_ACK(27), //client收到广播消息后ACK给server + + //重定向指令 + REDIRECT_TO_CLIENT(30), //server将重定向指令推动给client +} +``` + +#### 4. Client发起交互 + +| 场景 | Client向Server发送消息命令字 | Server回复Client消息的命令字 | 说明 | +| -------------- | ---------------------------- | ------------------------------- | ---- | +| 握手 | HELLO_REQUEST | HELLO_RESPONSE | | +| 心跳 | HEARTBEAT_REQUEST | HEARTBEAT_RESPONSE | | +| 订阅 | SUBSCRIBE_REQUEST | SUBSCRIBE_RESPONSE | | +| 取消订阅 | UNSUBSCRIBE_REQUEST | UNSUBSCRIBE_RESPONSE | | +| 开始监听消息 | LISTEN_REQUEST | LISTEN_RESPONSE | | +| 发送RR请求 | REQUEST_TO_SERVER | RESPONSE_TO_CLIENT | | +| 发送RR回包 | RESPONSE_TO_SERVER | 无 | | +| 发送异步事件 | ASYNC_MESSAGE_TO_SERVER | ASYNC_MESSAGE_TO_SERVER_ACK | | +| 发送广播事件 | BROADCAST_MESSAGE_TO_SERVER | BROADCAST_MESSAGE_TO_SERVER_ACK | | +| 客户端主动断连 | CLIENT_GOODBYE_REQUEST | CLIENT_GOODBYE_RESPONSE | | + +#### 5. Server发起交互 + +| 场景 | Server向Client发送消息命令字 | Client回复Server消息命令字 | 说明 | +| ------------------ | ---------------------------- | ------------------------------- | ---- | +| 客户端接收RR请求 | REQUEST_TO_CLIENT | REQUEST_TO_CLIENT_ACK | | +| 客户端接收RR回包 | RESPONSE_TO_CLIENT | RESPONSE_TO_CLIENT_ACK | | +| 客户端接收异步事件 | ASYNC_MESSAGE_TO_CLIENT | ASYNC_MESSAGE_TO_CLIENT_ACK | | +| 客户端接收广播事件 | BROADCAST_MESSAGE_TO_CLIENT | BROADCAST_MESSAGE_TO_CLIENT_ACK | | +| 服务端主动断连 | SERVER_GOODBYE_REQUEST | 无 | | +| 服务端进行重定向 | REDIRECT_TO_CLIENT | 无 | | +| | | | | + +#### 6. 消息类型 + ++ 发送RR消息 + +![rr-msg](../../images/design-document/sync-message.png) + ++ 发送异步单播消息 + +![async-msg](../../images/design-document/async-message.png) + ++ 发送广播消息 + +![broadcast-msg](../../images/design-document/broadcast-message.png) + +## HTTP协议文档 + +Java类`LiteMessage`的`content`字段表示一个特殊的协议,因此,如果您要使用eventmesh-sdk-java的http-client,则只需设计协议的`content`即可。`LiteMessage`组成如下: + +```java +public class LiteMessage { + + private String bizSeqNo; + + private String uniqueId; + + private String topic; + + private String content; + + private Map prop; + + private long createTime = System.currentTimeMillis(); +} +``` + +#### 1. 消息发送方式与组成 + +**消息发送方式**:POST方式 + +**消息组成**:请求头(RequestHeader) + 请求体(RequestBody) + ++ 心跳消息 + +**RequestHeader** + +| Key | 说明 | +| -------- | ---------------- | +| Env | client所属环境 | +| Region | client所属区域 | +| Idc | client所属IDC | +| Dcn | client所在DCN | +| Sys | client所属子系统 | +| Pid | client进程号 | +| Ip | client Ip | +| Username | client 用户名 | +| Passwd | client 密码 | +| Version | 协议版本 | +| Language | 语言描述 | +| Code | 请求码 | + +**RequestBody** + +| Key | 说明 | +| ----------------- | ------------------------------ | +| clientType | 客户端类型 | +| heartbeatEntities | 心跳实体,包含topic、url等信息 | + ++ 订阅消息: + +**RequestHeader** + +与心跳消息一致 + +**RequestBody** + +| Key | 说明 | +| ----- | ----------------- | +| topic | 客户端订阅的topic | +| url | topic对应的url | + ++ 取消订阅消息: + +**RequestHeader** + +与心跳消息一致 + +**RequestBody** + +与订阅消息一致 + ++ 发送异步事件: + +**RequestHeader** + +与心跳消息一致 + +**RequestBody** + +| Key | 说明 | +| -------- | ----------------------- | +| topic | 客户端请求的topic | +| content | 客户端发送的topic的内容 | +| ttl | 客户端请求超时时间 | +| bizSeqNo | 客户端请求业务流水号 | +| uniqueId | 客户端请求消息唯一标识 | + +#### 2. Client发起交互 + +| 场景 | Client向Server发送消息请求码 | Server回复Client消息的响应码 | 说明 | +| ------------ | ---------------------------- | --------------------------------------- | ---- | +| 心跳 | HEARTBEAT(203) | SUCCESS(0)/EVENTMESH_HEARTBEAT_ERROR(19) | | +| 订阅 | SUBSCRIBE(206) | SUCCESS(0)/EVENTMESH_SUBSCRIBE_ERROR(17) | | +| 取消订阅 | UNSUBSCRIBE(207) | SUCCESS(0)/EVENTMESH_UNSUBSCRIBE_ERROR(18) | | +| 发送异步事件 | MSG_SEND_ASYNC(104) | SUCCESS(0)/EVENTMESH_SEND_ASYNC_MSG_ERR(14) | | + +#### 3. Server发起交互 + +| 场景 | Server向Client发送消息请求码 | Client回复Server消息响应码 | 说明 | +| ------------------ | ---------------------------- | -------------------------- | ---------------------- | +| 客户端接收异步事件 | HTTP_PUSH_CLIENT_ASYNC(105) | retCode | retCode值为0时代表成功 | + +## gRPC 协议文档 + +#### 1. protobuf + +在 `eventmesh-protocol-gprc` 模块有 Eventmesh gRPC 客户端的 protobuf 文件. the protobuf 文件路径是 `/src/main/proto/eventmesh-client.proto`. + +用gradle build 生成 gRPC 代码在 `/build/generated/source/proto/main`. 生成代码用于 `eventmesh-sdk-java` 模块. + +#### 2. gRPC 数据模型 + ++ 消息 + +以下消息数据模型用于 `publish()`, `requestReply()` 和 `broadcast()` APIs. + +``` +message RequestHeader { + string env = 1; + string region = 2; + string idc = 3; + string ip = 4; + string pid = 5; + string sys = 6; + string username = 7; + string password = 8; + string language = 9; + string protocolType = 10; + string protocolVersion = 11; + string protocolDesc = 12; +} + +message SimpleMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + string content = 4; + string ttl = 5; + string uniqueId = 6; + string seqNum = 7; + string tag = 8; + map properties = 9; +} + +message BatchMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + + message MessageItem { + string content = 1; + string ttl = 2; + string uniqueId = 3; + string seqNum = 4; + string tag = 5; + map properties = 6; + } + + repeated MessageItem messageItem = 4; +} + +message Response { + string respCode = 1; + string respMsg = 2; + string respTime = 3; +} +``` + ++ 订阅 + +以下订阅数据模型用于 `subscribe()` 和 `unsubscribe()` APIs. + +``` +message Subscription { + RequestHeader header = 1; + string consumerGroup = 2; + + message SubscriptionItem { + enum SubscriptionMode { + CLUSTERING = 0; + BROADCASTING = 1; + } + + enum SubscriptionType { + ASYNC = 0; + SYNC = 1; + } + + string topic = 1; + SubscriptionMode mode = 2; + SubscriptionType type = 3; + } + + repeated SubscriptionItem subscriptionItems = 3; + string url = 4; +} +``` + ++ 心跳 + +以下心跳数据模型用于 `heartbeat()` API. + +``` +message Heartbeat { + enum ClientType { + PUB = 0; + SUB = 1; + } + + RequestHeader header = 1; + ClientType clientType = 2; + string producerGroup = 3; + string consumerGroup = 4; + + message HeartbeatItem { + string topic = 1; + string url = 2; + } + + repeated HeartbeatItem heartbeatItems = 5; +} +``` + +#### 3. gRPC 服务接口 + ++ 事件生产端服务 APIs + +``` +service PublisherService { + # 异步事件生产 + rpc publish(SimpleMessage) returns (Response); + + # 同步事件生产 + rpc requestReply(SimpleMessage) returns (Response); + + # 批量事件生产 + rpc batchPublish(BatchMessage) returns (Response); +} +``` + ++ 事件消费端服务 APIs + +``` +service ConsumerService { + # 所消费事件通过 HTTP Webhook推送事件 + rpc subscribe(Subscription) returns (Response); + + # 所消费事件通过 TCP stream推送事件 + rpc subscribeStream(Subscription) returns (stream SimpleMessage); + + rpc unsubscribe(Subscription) returns (Response); +} +``` + ++ 客户端心跳服务 API + +``` +service HeartbeatService { + rpc heartbeat(Heartbeat) returns (Response); +} +``` diff --git a/docs/zh/desing-document/06-cloudevents.md b/docs/zh/desing-document/06-cloudevents.md new file mode 100644 index 0000000000..2d53e6079e --- /dev/null +++ b/docs/zh/desing-document/06-cloudevents.md @@ -0,0 +1,102 @@ +# CloudEvents 集成 + +## 介绍 + +[CloudEvents](https://github.com/cloudevents/spec) 是一种描述事件数据的格式规范,它提供了跨服务、平台与系统的互操作性。 + +截止至 2021 年 5 月,EventMesh 包含了以下主要组件:`eventmesh-runtime`, `eventmesh-sdk-java` 和 `eventmesh-connector-rocketmq`。 + +对于使用 EventMesh 的用户,`eventmesh-runtime` 可以被部署为微服务来在生产者和消费者间传输用户的事件。 +用户的应用程序可以通过 `eventmesh-sdk-java` 来与 `eventmesh-runtime` 进行交互,即发布或订阅指定主题的事件。 + +EventMesh 的用户非常渴望能得到对 CloudEvents 的支持。有许多理由使得用户倾向于使用集成了 CloudEvents 支持的 SDK: + +- CloudEvents 是一种更为广泛接受和支持的描述事件的方式。目前,`eventmesh-sdk-java` 使用的是 `LiteMessage` 结构 + 来描述事件,其标准化程度较低。 +- CloudEvents 的 Java SDK 有更广泛的分发方式。比如,目前 EventMesh 的用户需要使用 SDK 的 tar 包,或对每个 EventMesh 的 + 发布版本从源码编译。有了 CloudEvents 的支持,用户可以更方便地通过 CloudEvents 的公开分发(比如,配置 Maven)来添加 + EventMesh SDK 依赖项。 +- CloudEvents 的 SDK 支持多种语言。尽管目前 EventMesh 只提供了 Java SDK,但在未来,如果要为更多语言提供支持,将 Java SDK + 与 CloudEvents 绑定的经验将使工作变得容易。 + +## 需求 + +### 功能需求 + +| 需求 ID | 需求描述 | 备注 | +| ------ | ------- | --- | +| F-1 | EventMesh 用户应能使用公共 SDK 依赖项来发布或订阅 CloudEvents 格式的事件 | 功能性 | +| F-2 | EventMesh 用户应能在提供了 CloudEvents 支持的 SDK 中继续使用现有的 EventMesh 客户端功能(如负载均衡) | 功能等价 | +| F-3 | EventMesh 的开发者应不需要付出特别多努力/痛苦来在 `eventmesh-sdk-java` 和提供了 CloudEvents 支持的 SDK 之间同步 | 可维护性 | +| F-4 | EventMesh 支持可插拔的协议,以便开发者整合其他协议(例如:CloudEvents / EventMesh MessageOpenMessage / MQTT...) | 功能性 | +| F-5 | EventMesh 支持统一的 API 以供从/向事件库发布或订阅事件 | 功能性 | + +### 性能需求 + +| 需求 ID | 需求描述 | 备注 | +| ------ | ------- | --- | +| P-1 | 提供了 CloudEvents 支持的 SDK 应具有与目前的 SDK 相近的客户端延迟 | | + +## 设计细节 + +与 CloudEvents 的 Java SDK 绑定(这与 Kafka 已经完成的工作类似,请在附录中的参考资料了解更多细节)是达成上述需求的一种简单方法。 + +### 可插拔协议 + +![可插拔协议](../../images/design-document/cloudevents-pluggable-protocols.png) + +### EventMesh 集成 CloudEvents 进度表 + +#### TCP + +##### SDK 端发布 + +- 在 `package` 首部中添加 CloudEvents 标识符 +- 使用 `CloudEventBuilder` 构造 CloudEvent,并将其放入 `package` 体中 + +##### SDK 端订阅 + +- 在 `ReceiveMsgHook` 接口下添加 `convert` 函数,其用于将 `package` 体转换为具有 `package` 首部标识符的特定协议 +- 不同协议应实现 `ReceiveMsgHook` 接口 + +##### 服务端发布 + +- 设计包含 `decodeMessage` 接口的协议转换 API,其可以把包体转换为 CloudEvent +- 更新 `MessageTransferTask` 下的 `Session.upstreamMsg()`,将入参 `Message` 改为 `CloudEvent`,这使用了 + 上一步的 `decodeMessage` API 来进行对 CloudEvent 的转换 +- 更新 `SessionSender.send()`,将入参 `Message` 改为 `CloudEvent` +- 更新 `MeshMQProducer` API,支持在运行时发送 `CloudEvents` +- 在 `connector-plugin` 中实现支持向 EventStore 中发送 `CloudEvents` + +##### 服务端订阅 + +- 支持将连接器插件中的 `RocketMessage` 改为 `CloudEvent +- 重写 `AsyncMessageListener.consume()` 函数,将入参 `Message` 改为 `CloudEvent` +- 更新 `MeshMQPushConsumer.updateOffset()`,将入参 `Message` 改为 `CloudEvent` +- 更新 `DownStreamMsgContext`,将入参 `Message` 改为 `CloudEvent`,更新 `DownStreamMsgContext.ackMsg` + +#### HTTP + +##### SDK 端发布 + +- 支持 `LiteProducer.publish(cloudEvent)` +- 在 http 请求头中添加 CloudEvents 标识符 + +##### SDK 端订阅 + +##### 服务端发布 + +- 支持根据 `HttpCommand` 首部中的协议类型,通过可插拔的协议插件构造 `HttpCommand.body` +- 支持在消息处理器中发布 CloudEvent + +##### 服务端订阅 + +- 更新 `EventMeshConsumer.subscribe()` +- 更新 `HandleMsgContext`, 将入参 `Message` 改为 `CloudEvent` +- 更新 `AsyncHttpPushRequest.tryHTTPRequest()` + +## 附录 + +### 参考资料 + +- diff --git a/docs/zh/desing-document/08-spi.md b/docs/zh/desing-document/08-spi.md new file mode 100644 index 0000000000..5fb301f408 --- /dev/null +++ b/docs/zh/desing-document/08-spi.md @@ -0,0 +1,111 @@ +# EventMesh SPI + +## 介绍 + +为了提高扩展性,EventMesh通过引入SPI(Service Provider Interface)机制,能够在运行时自动寻找扩展接口的具体实现类,动态加载。 +在EventMesh中,一切扩展点都利用SPI采用插件的实现方式,用户可以通过实现扩展接口,开发自定义的插件,在运行时通过简单的配置,声明式的选择所需要运行的插件。 + +## eventmesh-spi模块 + +SPI相关的代码位于eventmesh-spi模块下,其中主要包括EventMeshExtensionFactory, EventMeshSPI, ExtensionClassLoader这三个类。 + +### EventMeshSPI + +EventMeshSPI是SPI注解,所有需要采用SPI实现扩展的接口都需要使用@EventMeshSPI注解标记。 + +```java +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface EventMeshSPI { + + /** + * If true, the spi instance is singleton + */ + boolean isSingleton() default false; + +} +``` + +这么做的原因是可以通过注解的方式声明接口为SPI扩展接口,提高代码的可读性。同时,@EventMeshSPI注解中包含一个isSingleton属性, +用来声明该扩展接口是否采用单例的实现方式,如果为true,那么该接口的实现类将会使用单例的实现方式,在一个JVM进程中全局唯一。 + +### EventMeshExtensionFactory + +EventMeshExtensionFactory是SPI实现类的获取工厂,包含一个静态方法`getExtension(Class extensionType, String extensionName)`, +接收扩展接口字节码对象和扩展实例名称,用于获取扩展接口的具体实现类。 + +```java +public enum EventMeshExtensionFactory { + ; + /** + * @param extensionType extension plugin class type + * @param extensionName extension instance name + * @param the type of the plugin + * @return plugin instance + */ + public static T getExtension(Class extensionType, String extensionName) { + } +} +``` + +所有需要获取扩展实现的地方都应该通过EventMeshExtensionFactory获取。 + +### ExtensionClassLoader + +ExtensionClassLoader是扩展接口实现类的加载接口,包含两个实现子类MetaInfExtensionClassLoader和JarExtensionClassLoader。 + +```java +/** + * Load extension class + *
    + *
  • {@link MetaInfExtensionClassLoader}
  • + *
  • {@link JarExtensionClassLoader}
  • + *
+ */ +public interface ExtensionClassLoader { + + /** + * load + * + * @param extensionType extension type class + * @param extension type + * @return extension instance name to extension instance class + */ + Map> loadExtensionClass(Class extensionType); +} +``` + +MetaInfExtensionClassLoader用于从classPath直接加载实现类,JarExtensionClassLoader用于从配置目录下通过加载Jar包的方式加载实现类,未来可能还会提供通过从Maven仓库下加载实现类。 + +## SPI使用示例 + +下面以eventmesh-connector-plugin为例,介绍SPI具体的使用过程。 + +首先定义一个eventmesh-connector-api模块,并且定义扩展接口MeshMQProducer。在MeshMQProducer接口上使用@EventMeshSPI注解进行声明,表明该接口是一个SPI扩展接口 + +```java +@EventMeshSPI(isSingleton = false) +public interface MeshMQProducer extends Producer { +... +} +``` + +eventmesh-connector-rocketmq模块中包含采用rocketmq的具体实现方式RocketMQProducerImpl。 + +```java +public class RocketMQProducerImpl implements MeshMQProducer { +... +} +``` + +同时,还需要在eventmesh-connector-rocketmq模块中resource/META-INF/eventmesh目录下创建文件名为SPI接口全限定名的文件 +org.apache.eventmesh.api.producer.Producer + +文件内容为扩展实例名和对应的实例全类名 + +```properties +rocketmq=org.apache.eventmesh.connector.rocketmq.producer.RocketMQProducerImpl +``` + +至此,一个SPI扩展模块就完成了。在使用的时候只需要通过EventMeshExtensionFactory.getExtension(MeshMQProducer.class, “rocketmq”)就可以获取RocketMQProducerImpl实现类。 diff --git a/docs/zh/desing-document/_category_.json b/docs/zh/desing-document/_category_.json new file mode 100644 index 0000000000..95b7eed067 --- /dev/null +++ b/docs/zh/desing-document/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Documentation", + "collapsed": false +} diff --git a/docs/zh/desing-document/eventmesh-unit-test-rule.md b/docs/zh/desing-document/eventmesh-unit-test-rule.md new file mode 100644 index 0000000000..a346c835c8 --- /dev/null +++ b/docs/zh/desing-document/eventmesh-unit-test-rule.md @@ -0,0 +1,124 @@ +# 单元测试准则 + +## 目录以及命名规则 + ++ 单元测试代码必须放在工程目录下:src/test/java + 测试的配置文件也必须放在: src/test/resources + 例: + 业务类: `src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBody.java` + 对应被测试业务类: `src/test/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBodyTest.java` + 测试配置文件: `src/test/resources/configuration.properties` + ++ 测试类所在的包名与被测试类所在的包名一致(如上所示) + ++ 测试类的命名规范: + 被测试(类、接口)名 + Test + 例: + 业务类名: `EventMeshUtil` + 对应被测试业务类名: `EventMeshUtilTest` + ++ 测试类用例命名规范: + test + 方法名, 使用test作为方法名的前缀 + 例: + 业务方法名: + ``` + public EventMeshMessage addProp(String key, String val) { + if (prop == null) { + prop = new HashMap<>(); + } + prop.put(key, val); + return this; + } + ``` + 对应被测试业务方法名: + ``` + public void testAddProp() { + EventMeshMessage message = createLiteMessage(); + message.addProp("key3", "value3"); + Assert.assertEquals(3L, message.getProp().size()); + Assert.assertEquals("value1", message.getProp("key1")); + } + ``` + +## 编码规范 + ++ 单元测试类中必须使用assert断言来进行验证, 不允许使用System.out, if判断验证来进行验证(可以使用log打印关键日志输出) ++ 增量代码要确保单元测试通过 ++ 单元测试要保证测试粒度足够小, 以助于精确定位问题, 一般都是方法级别 + 注:测试粒度小才能尽快定位到错误位置 ++ 保持单元测试之间的独立性, 为了保证单元测试稳定可靠且便于维护, 单元测试用例之间绝不能互相调用,也不能依赖执行的先后次序 ++ 单元测试必须可以重复执行的, 不受外界环境影响 + 注:单元测试通常放在持续集成中, 如果单个单元测试依赖外部环境, 那么很容易导致集成机制不可用 + +## 断言的使用 + +**所有的测试用例的结果验证都必须使用断言模式** + +### 常规断言 + +| 方法 | 说明 | 备注 | +| :-------------- | :---------------| ------------- | +| assertEquals | 判断两个对象或者两个原始类型是否相等 | | +| assertNotEquals | 判断两个对象或者两个原始类型是否不相等 | | +| assertTrue | 判断给定的布尔值是否为真 | | +| assertFalse | 判断给定的布尔值是否为假 | | +| assertNull | 判断给定的对象应用是否为空 | | +| assertNotNull | 判断给定的对象应用是否不为空 | | +| assertAll | 多个逻辑一起处理, 只要有一个报错, 整个测试就会失败 | | + +### 断言使用实例 + ++ assertEquals() +``` + configuration.init(); + Assert.assertEquals("value1", configuration.eventMeshEnv); +``` + ++ assertTrue() +``` + BaseResponseHeader header = BaseResponseHeader.buildHeader("200"); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); +``` + ++ assertFalse() +``` + Class nacosRegistryServiceClass = NacosRegistryService.class; + Field initStatus = nacosRegistryServiceClass.getDeclaredField("INIT_STATUS"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(nacosRegistryService); + Assert.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); +``` + ++ assertNull() +``` + DefaultFullHttpResponse response = httpCommand.httpResponse(); + Assert.assertNull(response); +``` + ++ assertNotNull() +``` + Codec.Decoder cd = new Codec.Decoder(); + ArrayList result = new ArrayList<>(); + cd.decode(null, buf, result); + Assert.assertNotNull(result.get(0)); +``` + ++ 集合结果集中的每个对象都需要断言(以map为例) +``` + Map headerParam = new HashMap<>(); + headerParam.put(ProtocolKey.REQUEST_CODE, 200); + headerParam.put(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA); + headerParam.put(ProtocolKey.VERSION, "1.0"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, "default cluster"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, "127.0.0.1"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, "DEV"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, "IDC"); + header = PushMessageRequestHeader.buildHeader(headerParam); + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is(200)); + Assert.assertThat(header.toMap().get(ProtocolKey.LANGUAGE), is(Constants.LANGUAGE_JAVA)); + Assert.assertThat(header.toMap().get(ProtocolKey.VERSION), is(ProtocolVersion.V1)); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER), is("default cluster")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP), is("127.0.0.1")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV), is("DEV")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC), is("IDC")); +``` diff --git a/docs/zh/desing-document/https.md b/docs/zh/desing-document/https.md new file mode 100644 index 0000000000..a100ba3977 --- /dev/null +++ b/docs/zh/desing-document/https.md @@ -0,0 +1,32 @@ +# HTTPS + +1.在eventmesh-runtime 中配置 + +``` +eventMesh.properties(添加如下配置) +eventMesh.server.useTls.enabled=true //默认值 false + + +config env varible +-Dssl.server.protocol=TLSv1.1 //默认值 TLSv1.1 +-Dssl.server.cer=sChat2.jks //把文件放到启动脚本start.sh 指定的conPath目录下 +-Dssl.server.pass=sNetty +``` + +2.在eventmesh-sdk-java 中配置 + +``` +//创建producer +LiteClientConfig eventMeshHttpClientConfig = new eventMeshHttpClientConfig(); +... + +//设置开启TLS +eventMeshHttpClientConfig.setUseTls(true); +LiteProducer producer = new LiteProducer(eventMeshHttpClientConfig); + + +//配置环境变量 +-Dssl.client.protocol=TLSv1.1 //默认值 TLSv1.1 +-Dssl.client.cer=sChat2.jks //把文件放到应用指定的conPath目录下 +-Dssl.client.pass=sNetty +``` diff --git a/docs/zh/desing-document/webhook.md b/docs/zh/desing-document/webhook.md new file mode 100644 index 0000000000..617a602b05 --- /dev/null +++ b/docs/zh/desing-document/webhook.md @@ -0,0 +1,268 @@ + + +## webhook使用流程 +#### 第一步:在eventmesh配置webhook相关信息并且启动 + +##### 配置说明 +``` +# 是否启动webhook admin服务 +eventMesh.webHook.admin.start=true + +# webhook事件配置存储模式。目前只支持file与nacos +eventMesh.webHook.operationMode=file +# 文件存储模式的文件存放路径,如果写上#{eventMeshHome},在eventMesh根目录 +eventMesh.webHook.fileMode.filePath= #{eventMeshHome}/webhook + +# nacos存储模式,配置命名规则是eventMesh.webHook.nacosMode.{nacos 原生配置key} 具体的配置请看 [nacos github api](https://github.com/alibaba/nacos/blob/develop/api/src/main/java/com/alibaba/nacos/api/SystemPropertyKeyConst.java) +## nacos的地址 +eventMesh.webHook.nacosMode.serverAddr=127.0.0.1:8848 + +# webhook eventcloud 发送模式。与eventMesh.connector.plugin.type 配置一样 +eventMesh.webHook.producer.connector=standalone +``` + +#### 第二步:添加webhook配置信息 +配置信息说明 +```java + /** + * 厂商调用的path。厂商事件调用地址、 [http or https ]://[域名 or IP 【厂商可以被调用】]:[端口]/webhook/[callbackPath] + * 比如:http://127.0.0.1:10504/webhook/test/event 需要把全完url填入厂商调用输入中 + * callbackPath 是唯一 + * manufacturer callback path + */ + private String callbackPath; + + /** + * 厂商的名字 + * manufacturer name ,like github + */ + private String manufacturerName; + + /** + * 厂商的事件名 + * webhook event name ,like rep-push + */ + private String manufacturerEventName; + + /** + * + * http header content type + */ + private String contentType = "application/json"; + + /** + * 说明 + * description of this WebHookConfig + */ + private String description; + + /** + * 有一些厂商使用验签方式, + * secret key ,for authentication + */ + private String secret; + + /** + * 有一些厂商使用验签方式,使用账户密码方式 + * userName ,for HTTP authentication + */ + private String userName; + + /** + * 有一些厂商使用验签方式,使用账户密码方式 + * password ,for HTTP authentication + */ + private String password; + + + + /** + * 事件发送到那个topic + * roll out event name ,like topic to mq + */ + private String cloudEventName; + + /** + * roll out data format -> CloudEvent serialization mode + * If HTTP protocol is used, the request header contentType needs to be marked + */ + private String dataContentType = "application/json";; + + /** + * source of event + */ + private String cloudEventSource; + + /** + * cloudEvent事件对象唯一标识符识别方式,uuid或者manufacturerEventId(厂商id) + * id of cloudEvent ,like uuid/manufacturerEventId + */ + private String cloudEventIdGenerateMode; + +``` + +##### 添加接口 +路径: /webhook/insertWebHookConfig +方法: POST +contentType: application/json + +输入参数: +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 厂商名 | string | 是 | null | +| manufacturerEventName | 厂商事件名 | string | 是 | null | +| contentType | http connettype | string | 否 | application/json | +| description | 配置说明 | string | 否 | null | +| secret | 验签密钥 | string | 否 | null | +| userName | 用户名 | string | 否 | null | +| password | 用户密码 | string | 否 | null | +| cloudEventName | 事件名() | string | 是 | null | +| cloudEventSource | 事件来源可以填写 | string | 是 | null | +| cloudEventIdGenerateMode | cloudEvent事件对象唯一标识符识别方式,uuid或者manufacturerEventId(厂商id) | string | 否 | manufacturerEventId | + +列子: +```json + +{ + "callbackPath":"/webhook/github/eventmesh/all", + "manufacturerName":"github", + "manufacturerEventName":"all", + "secret":"eventmesh", + "cloudEventName":"github-eventmesh", + "cloudEventSource":"github" +} + +``` +输出参数:1 成功,0失败 + +##### 删除接口 +路径: /webhook/deleteWebHookConfig +方法: POST +contentType: application/json + +输入参数: +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | + + +列子: + +```json + +{ + "callbackPath":"/webhook/github/eventmesh/all" +} + +``` + + +输出参数:1 成功,0失败 + +##### 通过callbackPath查询WebHookConfig +路径: /webhook/queryWebHookConfigById +方法: POST +contentType: application/json + +输入参数: +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | + + +列子: + +```json + +{ + "callbackPath":"/webhook/github/eventmesh/all" +} + +``` + + +输出参数: +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 厂商名 | string | 是 | null | +| manufacturerEventName | 厂商事件名 | string | 是 | null | +| contentType | http connettype | string | 否 | application/json | +| description | 配置说明 | string | 否 | null | +| secret | 验签密钥 | string | 否 | null | +| userName | 用户名 | string | 否 | null | +| password | 用户密码 | string | 否 | null | +| cloudEventName | 事件名() | string | 是 | null | +| cloudEventSource | 事件来源可以填写 | string | 是 | null | +| cloudEventIdGenerateMode | cloudEvent事件对象唯一标识符识别方式,uuid或者manufacturerEventId(厂商id) | string | 否 | manufacturerEventId | + + +##### 通过manufacturer查询WebHookConfig列表 +路径: /webhook/queryWebHookConfigByManufacturer +方法: POST +contentType: application/json + +输入参数: +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| manufacturerName | 厂商名 | string | 是 | null | + + +列子: + +```json + +{ + "manufacturerName":"github" +} + +``` + + +输出参数: +| 字段 | 说明 | 类型 | 必须 | 默认值 | +| -- | -- | -- | -- | -- | +| callbackPath | 调用地址,唯一地址 | string | 是 | null | +| manufacturerName | 厂商名 | string | 是 | null | +| manufacturerEventName | 厂商事件名 | string | 是 | null | +| contentType | http connettype | string | 否 | application/json | +| description | 配置说明 | string | 否 | null | +| secret | 验签密钥 | string | 否 | null | +| userName | 用户名 | string | 否 | null | +| password | 用户密码 | string | 否 | null | +| cloudEventName | 事件名() | string | 是 | null | +| cloudEventSource | 事件来源可以填写 | string | 是 | null | +| cloudEventIdGenerateMode | cloudEvent事件对象唯一标识符识别方式,uuid或者manufacturerEventId(厂商id) | string | 否 | manufacturerEventId | + + +#### 第三步:查看配置是否成功 +1. file存储模式。请到eventMesh.webHook.fileMode.filePath 目录下查看。文件名为callbackPath转移后的 +2. nacos存储模式。请到eventMesh.webHook.nacosMode.serverAddr 配置的nacos服务去看 + +#### 第四步:配置cloudevent的消费者 + + +#### 第五步:在厂商配置webhook相关信息 +> 厂商操作请看【厂商webhook操作说明】 + + +## 厂商webhook操作说明 +### github 注册 +#### 第一步:进入对应的项目 +#### 第二步:点击setting +![](../images/features/webhook/webhook-github-setting.png) +#### 第三步:点击Webhooks +![](../images/features/webhook/webhook-github-webhooks.png) +#### 第四步:点击 Add webhook +![](../images/features/webhook/webhook-github-add.png) +#### 第五步: 填写webhook信息 +![](../images/features/webhook/webhook-github-info.png) + +Payload URL: 服务地址以及pahts。[http or https ]://[域名 or IP 【厂商可以被调用】]:[端口]/webhook/[callbackPath] +Content type:http header content type +secret: 验签字符串 + + + + diff --git a/docs/zh/instruction/00-eclipse.md b/docs/zh/instruction/00-eclipse.md new file mode 100644 index 0000000000..27ded49524 --- /dev/null +++ b/docs/zh/instruction/00-eclipse.md @@ -0,0 +1,33 @@ +# eventMesh 导入Eclipse 快速入门说明 + +### 依赖 + +``` +64位JDK 1.8+; +Gradle至少为7.0, 推荐 7.0.* +eclipse 已安装gradle插件或者eclipse自带gradle插件 +``` + +### 下载源码 +git init + +git clone https://github.com/apache/incubator-eventmesh.git + +### 项目编译eclipse环境 + +打开命令行终端,运行gradlew cleanEclipse eclipse + +### 配置修改 +修改工程名称和settings.gradle 配置文件参数rootProject.name 参数一致 + +### 修改eclipse.init配置文件,配置lombok以1.18.8版本为例 +-javaagent:lombok-1.18.8.jar +-XBootclasspath/a:lombok-1.18.8.jar + +### 202106版本eclipse,eclipse.init增加配置参数 +--illegal-access=permit + + +### 导入gradle +打开eclipse,导入gradle项目到IDE里 + diff --git a/docs/zh/instruction/01-store-with-docker.md b/docs/zh/instruction/01-store-with-docker.md new file mode 100644 index 0000000000..6b4dbb775b --- /dev/null +++ b/docs/zh/instruction/01-store-with-docker.md @@ -0,0 +1,40 @@ +# eventmesh-store 快速入门说明 + +## 依赖 + +``` +建议使用64位操作系统,建议使用Linux/Unix; +64位JDK 1.8+; +Gradle至少为7.0, 推荐7.0.* +4g+可用磁盘用于eventmesh-store服务器 +eventmesh在非standalone模式下,依赖RocketMQ作为存储层;若采用standalone模式,则可跳过该步,直接进行runtime的部署 +``` + +## 部署 +在命令行输入如下命令直接从 docker hub 上获取 RocketMQ 镜像: + +```shell +#获取 namesrv 镜像 +sudo docker pull rocketmqinc/rocketmq-namesrv:4.5.0-alpine +#获取 broker 镜像 +sudo docker pull rocketmqinc/rocketmq-broker:4.5.0-alpine +``` + +在命令行输入以下命令运行namerv容器和broker容器 + +```shell +#运行 namerv 容器 +sudo docker run -d -p 9876:9876 -v `pwd` /data/namesrv/logs:/root/logs -v `pwd`/data/namesrv/store:/root/store --name rmqnamesrv rocketmqinc/rocketmq-namesrv:4.5.0-alpine sh mqnamesrv + +#运行 broker 容器 +sudo docker run -d -p 10911:10911 -p 10909:10909 -v `pwd`/data/broker/logs:/root/logs -v `pwd`/data/broker/store:/root/store --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" rocketmqinc/rocketmq-broker:4.5.0-alpine sh mqbroker -c ../conf/broker.conf +``` + +请注意 **rocketmq-broker ip** 是 **pod ip**, 如果你想修改这个ip, 可以通过挂载容器中 **broker.conf** 文件的方式并修改文件中的 **brokerIP1** 配置项为自定义值 + + +至此eventmesh-store的部署已完成,请转至下一步完成eventmesh-runtime的部署 + + +## 参考 +关于RocketMQ的其他更多资料,请参考 diff --git a/docs/zh/instruction/01-store.md b/docs/zh/instruction/01-store.md new file mode 100644 index 0000000000..d8b5599f04 --- /dev/null +++ b/docs/zh/instruction/01-store.md @@ -0,0 +1,51 @@ +# eventmesh-store 快速入门说明 + +## 依赖 + +``` +建议使用64位操作系统,建议使用Linux/Unix; +64位JDK 1.8+; +Gradle至少为7.0, 推荐7.0.* +4g+可用磁盘用于eventmesh-store服务器 +eventmesh在非standalone模式下,依赖RocketMQ作为存储层;若采用standalone模式,则可跳过该步,直接进行runtime的部署 +``` + + +## 下载 + +从[RocketMQ官方网站](https://rocketmq.apache.org/dowloading/releases/) 下载Binary代码(推荐使用4.9.*版本),这里以4.9.2为例 + +``` +unzip rocketmq-all-4.9.2-bin-release.zip +cd rocketmq-4.9.2/ +``` + + +## 部署 + +- #### 启动Name Server + +``` +nohup sh bin/mqnamesrv & +tail -f ~/logs/rocketmqlogs/namesrv.log +``` + +如果在看到The Name Server boot success...,则说明Name Server启动成功 + +- #### 启动Broker + +``` +nohup sh bin/mqbroker -n localhost:9876 & +tail -f ~/logs/rocketmqlogs/broker.log +``` + +如果在看到The broker boot success...,则说明Broker启动成功 + +至此eventmesh-store的部署已完成,请转至下一步完成eventmesh-runtime的部署 + + +## 参考 +关于RocketMQ的其他更多资料,请参考 + + + diff --git a/docs/zh/instruction/02-runtime-with-docker.md b/docs/zh/instruction/02-runtime-with-docker.md new file mode 100644 index 0000000000..640bd59376 --- /dev/null +++ b/docs/zh/instruction/02-runtime-with-docker.md @@ -0,0 +1,149 @@ +# 使用 Docker 快速入门 EventMesh(暂时只支持到1.4.0版本) + +本篇快速入门将详细介绍使用 docker 部署 EventMesh,以 RocketMQ 作为对接的中间件。 + +可选语言: [英文版本](../../en/instructions/eventmesh-runtime-quickstart-with-docker.md),[中文版本](02-runtime-with-docker.md)。 + +## 前提 + +1. 建议使用64位的 linux 系统; +2. 请预先安装 Docker Engine。 Docker 的安装过程可以参考 [docker 官方文档](https://docs.docker.com/engine/install/); +3. 建议掌握基础的 docker 概念和命令行,例如注册中心、挂载等等。不过这不是必须的,因为本次操作所需的命令都已为您列出; +4. 若您选择非standalone模式,请确保 [RocketMQ 已成功启动](https://rocketmq.apache.org/docs/quick-start/) 并且可以使用 ip 地址访问到;若您选择standalone模式,则无需启动 RocketMQ 。 + +## 获取 EventMesh 镜像 + +首先,你可以打开一个命令行,并且使用下面的 ```pull``` 命令从 [Docker Hub](https://registry.hub.docker.com/r/eventmesh/eventmesh/tags) 中下载[最新发布的 EventMesh](https://eventmesh.apache.org/events/release-notes/v1.3.0/) 。 + +```shell +sudo docker pull eventmesh/eventmesh:v1.4.0 +``` + +您可以使用以下命令列出并查看本地已有的镜像。 + +```shell +sudo docker images +``` + +如果终端显示如下所示的镜像信息,则说明 EventMesh 镜像已经成功下载到本地。 + +```shell +REPOSITORY TAG IMAGE ID CREATED SIZE +eventmesh/eventmesh v1.4.0 6e2964599c78 3 months ago 936.73 MB +``` + +## 创建配置文件 + +在根据 EventMesh 镜像运行对应容器之前,你需要创建两个配置文件,分别是:```eventMesh.properties``` 和 ```rocketmq-client.properties```。 + +首先,你需要使用下面的命令创建这两个文件。 + +```shell +sudo mkdir -p /data/eventmesh/rocketmq/conf +cd /data/eventmesh/rocketmq/conf +sudo touch eventmesh.properties +sudo touch rocketmq-client.properties +``` + +### 配置 eventMesh.properties + +这个配置文件中包含 EventMesh 运行时环境和集成进来的其他插件所需的参数。 + +使用下面的 ```vim``` 命令编辑 ```eventmesh.properties```。 + +```shell +sudo vim eventmesh.properties +``` + +你可以直接将 GitHub 仓库中的对应配置文件中的内容复制过来,链接为: 。 + +请检查配置文件里的默认端口是否已被占用,如果被占用请修改成未被占用的端口: + +| 属性 | 默认值 | 备注 | +|----------------------------|-------|----------------------------| +| eventMesh.server.http.port | 10105 | EventMesh http server port | +| eventMesh.server.tcp.port | 10000 | EventMesh tcp server port | +| eventMesh.server.grpc.port | 10205 | EventMesh grpc server port | + +### 配置 rocketmq-client.properties + +这个配置文件中包含 RocketMQ nameserver 的信息。 + +使用下面的 ```vim``` 命令编辑 ```rocketmq-client.properties```。 + +```shell +sudo vim rocketmq-client.properties +``` + +你可以直接将 GitHub 仓库中的对应配置文件中的内容复制过来,链接为: 。请注意,如果您正在运行的 namesetver 地址不是配置文件中的默认值,请将其修改为实际正在运行的nameserver地址。 + +请检查配置文件里的默认namesrvAddr是否已被占用,如果被占用请修改成未被占用的地址: + +| 属性 | 默认值 | 备注 | +|---------------------------------------|-------------------------------|----------------------------------| +| eventMesh.server.rocketmq.namesrvAddr | 127.0.0.1:9876;127.0.0.1:9876 | RocketMQ namesrv default address | + +## 运行 EventMesh + +现在你就可以开始根据下载好的 EventMesh 镜像运行容器了。 + +使用到的命令是 ```docker run```,有以下两点内容需要格外注意。 + +1. 绑定容器端口和宿主机端口:使用 ```docker run``` 的 ```-p``` 选项。 +2. 将宿主机中的两份配置文件挂在到容器中:使用 ```docker run``` 的 ```-v``` 选项。 + +综合一下,对应的启动命令为: + +```shell +sudo docker run -d \ + -p 10000:10000 -p 10105:10105 \ + -v /data/eventmesh/rocketmq/conf/eventMesh.properties:/data/app/eventmesh/conf/eventMesh.properties \ + -v /data/eventmesh/rocketmq/conf/rocketmq-client.properties:/data/app/eventmesh/conf/rocketmq-client.properties \ + eventmesh/eventmesh:v1.4.0 +``` + +如果运行命令之后看到新输出一行字符串,那么运行 EventMesh 镜像的容器就启动成功了。 + +接下来,你可以使用下面的命令查看容器的状态。 + +```shell +sudo docker ps +``` + +如果成功的话,你会看到终端打印出了如下所示容器的信息,其中就有运行 EventMesh 镜像的容器。 + +```shell +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +d1e1a335d4a9 eventmesh/eventmesh:v1.4.0 "/bin/sh -c 'sh star…" About a minute ago Up About a minute 0.0.0.0:10000->10000/tcp, :::10000->10000/tcp, 0.0.0.0:10105->10105/tcp, :::10105->10105/tcp focused_bartik +``` + +从这个信息中可以看出,```container id``` 是 ```d1e1a335d4a9```,```name``` 是 ```focused_bartik```,它们都可以用来唯一标识这个容器。**注意**:在你的电脑中,它们的值可能跟这里的不同。 + +## 管理 EventMesh 容器 + +在成功的运行了 EventMesh 容器后,你可以通过进入容器、查看日志、删除容器等方式管理容器。 + +**进入容器** 命令示例: + +```shell +sudo docker exec -it [your container id or name] /bin/bash +``` + +在容器中 **查看日志** 命令示例: + +```shell +cd ../logs +tail -f eventmesh.out +``` + +**删除容器** 命令示例: + +```shell +sudo docker rm -f [your container id or name] +``` + +## 探索更多 + +现在 EventMesh 已经通过容器运行了,你可以参考 [```eventmesh-examples``` 模块](https://github.com/apache/incubator-eventmesh/tree/master/eventmesh-examples) 编写并测试自己的代码了。 + +希望你享受这个过程并获得更多收获! diff --git a/docs/zh/instruction/02-runtime.md b/docs/zh/instruction/02-runtime.md new file mode 100644 index 0000000000..845f1ccf63 --- /dev/null +++ b/docs/zh/instruction/02-runtime.md @@ -0,0 +1,114 @@ +# Eventmesh-runtime 快速入门说明 + + +## 1 本地构建运行 + +### 1.1 依赖 + +``` +建议使用64位操作系统,建议使用Linux / Unix; +64位JDK 1.8+; +Gradle至少为7.0, 推荐 7.0.* +``` + +### 1.2 下载源码 + +在 [EventMesh download](https://eventmesh.apache.org/download) 页面选择1.5.0版本的 Source Code 进行下载并解压, 您将获得**apache-eventmesh-1.5.0-incubating-src** + + +### 1.3 本地启动 + +**1.3.1 项目结构说明:** + +- eventmesh-common : eventmesh公共类与方法模块 +- eventmesh-connector-api : eventmesh connector插件接口定义模块 +- eventmesh-connector-plugin : eventmesh connector插件模块 +- eventmesh-runtime : eventmesh运行时模块 +- eventmesh-sdk-java : eventmesh java客户端sdk +- eventmesh-starter : eventmesh本地启动运行项目入口 +- eventmesh-spi : eventmesh SPI加载模块 + +> 注:插件模块遵循 eventmesh 定义的SPI规范, 自定义的SPI接口需要使用注解 @EventMeshSPI 标识. +> 插件实例需要在对应模块中的 /main/resources/META-INF/eventmesh 下配置相关接口与实现类的映射文件,文件名为SPI接口全类名. +> 文件内容为插件实例名到插件实例的映射, 具体可以参考 eventmesh-connector-rocketmq 插件模块 + +**1.3.2 插件说明** + +***1.3.2.1 安装插件*** + +有两种方式安装插件 + +- classpath加载:本地开发可以通过在 eventmesh-starter 模块 build.gradle 中进行声明,例如声明使用 rocketmq 插件 + +```gradle + implementation project(":eventmesh-connector-plugin:eventmesh-connector-rocketmq") +``` + +- 文件加载:通过将插件安装到插件目录,EventMesh 在运行时会根据条件自动加载插件目录下的插件,可以通过执行以下命令安装插件 + +```shell +./gradlew clean jar dist && ./gradlew installPlugin +``` + +***1.3.2.2 使用插件*** + +EventMesh 会默认加载 dist/plugin 目录下的插件,可以通过`-DeventMeshPluginDir=your_plugin_directory`来改变插件目录。运行时需要使用的插件实例可以在 +`confPath`目录下面的`eventmesh.properties`中进行配置。例如通过以下设置声明在运行时使用rocketmq插件。 + +```properties +#connector plugin +eventMesh.connector.plugin.type=rocketmq +``` + +**1.3.3 配置VM启动参数** + +```properties +-Dlog4j.configurationFile=eventmesh-runtime/conf/log4j2.xml +-Deventmesh.log.home=eventmesh-runtime/logs +-Deventmesh.home=eventmesh-runtime +-DconfPath=eventmesh-runtime/conf +``` + +> 注:如果操作系统为Windows, 可能需要将文件分隔符换成\ + +**1.3.4 启动运行** + +``` +运行org.apache.eventmesh.starter.StartUp的主要方法 +``` + +## 2 远程部署 + +### 2.1 依赖 + +``` +建议使用64位操作系统,建议使用Linux / Unix; +64位JDK 1.8+; +Gradle至少为7.0, 推荐 7.0.* +``` + +### 2.2 下载 + +在 [EventMesh download](https://eventmesh.apache.org/download) 页面选择1.5.0版本的 Binary Distribution 进行下载, 您将获得**apache-eventmesh-1.5.0-incubating-bin.tar.gz** + + +### 2.3 部署 + +- 部署eventmesh-runtime + +```$ xslt +# 解压 apache-eventmesh-1.5.0-incubating-bin.tar.gz +tar -zxvf apache-eventmesh-1.5.0-incubating-bin.tar.gz +cd apache-eventmesh-1.5.0-incubating + +# 配置 eventMesh.properties +vim conf/eventMesh.properties + +# 启动EventMesh +cd bin +sh start.sh +``` + +如果看到"EventMeshTCPServer[port=10000] started....",则说明设置成功。 + + diff --git a/docs/zh/instruction/03-demo.md b/docs/zh/instruction/03-demo.md new file mode 100644 index 0000000000..5a18196660 --- /dev/null +++ b/docs/zh/instruction/03-demo.md @@ -0,0 +1,178 @@ +# 运行 eventmesh-sdk-java demo + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java) + +> EventMesh-sdk-java作为客户端,与eventmesh-runtime通信,用于完成消息的发送和接收。 +> +> EventMesh-sdk-java支持异步消息和广播消息。异步消息表示生产者只发送消息,不关心回复消息。广播消息表示生产者发送一次消息,所有订阅广播主题的消费者都将收到消息 +> +> EventMesh-sdk-java支持HTTP,TCP 和 GRPC 协议。 + +TCP, HTTP 和 GRPC 示例都在**eventmesh-examples**模块下 + +### 1. TCP DEMO + +

异步消息

+ +- 创建主题TEST-TOPIC-TCP-ASYNC,可以通过 rocketmq-console 或者 rocketmq tools 命令 + +- 启动消费者,订阅上一步骤已经创建的Topic + +``` +运行 org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribe 的main方法 +``` + +- 启动发送端,发送消息 + +``` +运行 org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublish 的main方法 +``` + +

广播消息

+ +- 创建主题TEST-TOPIC-TCP-BROADCAST,可以通过 rocketmq-console 或者 rocketmq tools 命令 + +- 启动消费端,订阅上一步骤已经创建的Topic + +``` +运行 org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribeBroadcast 的main方法 +``` + +- 启动发送端,发送广播消息 + +``` +运行 org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublishBroadcast 的main方法 +``` + +更多关于TCP部分的内容,请参考 [EventMesh TCP](docs/zh/sdk-java/03-tcp.md) + +### 2. HTTP演示 + +> 对于HTTP,eventmesh-sdk-java对对于异步事件实现了发送与订阅 +> +>在演示中,Java类`LiteMessage`的`content`字段表示一个特殊的协议,因此,如果您要使用eventmesh-sdk-java的http-client,则只需设计协议的内容并在同一时间提供消费者的应用程序。 + +

异步事件

+ +> 生产者将事件发送给下游即可,无需等待响应 + +- 创建主题TEST-TOPIC-HTTP-ASYNC,可以通过rocketmq-console或者rocketmq tools 命令 + +- 启动消费端,订阅Topic + + 异步事件消费端为spring boot demo,运行demo即可启动服务并完成Topic订阅 + +``` +运行 org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication 的main方法 +``` + +- 启动发送端,发送消息 + +``` +运行 org.apache.eventmesh.http.demo.pub.eventmeshmessage.AsyncPublishInstance 的main方法 +``` +更多关于HTTP部分的内容,请参考 [EventMesh HTTP](docs/zh/sdk-java/02-http.md) + +### 3. GRPC 演示 + +> eventmesh-sdk-java 实现了 gRPC 协议. 它能异步和同步发送事件到 eventmesh-runtime. +> 它可以通过webhook和事件流方式订阅消费事件, 同时也支持 CNCF CloudEvents 协议. + +

异步事件发送 和 webhook订阅

+ +> Async生产者 异步发送事件到 eventmesh-runtime, 不需要等待事件储存到 `event-store` +> 在webhook 消费者, 事件推送到消费者的http endpoint url。这个URL在消费者的 `Subscription` 模型定于. 这方法跟前面的Http eventmsh client类似。 + +- 在rocketmq 创建主题 TEST-TOPIC-GRPC-ASYNC +- 启动 publisher 发送事件 + +``` +运行 org.apache.eventmesh.grpc.pub.eventmeshmessage.AsyncPublishInstance 的main方法 +``` + +- 启动 webhook 消费者 + +``` +运行 org.apache.eventmesh.grpc.sub.app.SpringBootDemoApplication 的main方法 +``` + +

同步事件发送和事件流订阅

+ +> 同步生产者 发送事件到 eventmesh-runtime, 同时等待事件储存到 `event-store` +> 在事件流消费者,事件以流的形式推送到 `ReceiveMsgHook` 客户端。 这方法类似 eventmesh client. + +- 在rocketmq 创建主题 TEST-TOPIC-GRPC-RR +- 启动 Request-Reply publisher 发送事件 + +``` +运行 org.apache.eventmesh.grpc.pub.eventmeshmessage.RequestReplyInstance 的main方法 +``` + +- 启动 stream subscriber + +``` +运行 org.apache.eventmesh.grpc.sub.EventmeshAsyncSubscribe 的main方法 +``` + +

批量事件发布

+ +> 批量发布多个事件到 eventmesh-runtime. 这是异步操作 + +- 在rocketmq 创建主题 TEST-TOPIC-GRPC-ASYNC +- 启动 publisher 来批量发布事件 + +``` +运行 org.apache.eventmesh.grpc.pub.eventmeshmessage.BatchPublishInstance 的main方法 +``` + +更多关于 gRPC 部分的内容,请参考 [EventMesh gRPC](docs/zh/sdk-java/04-grpc.md) + +### 3.4 测试 + +请参考[EventMesh Store](docs/zh/instruction/01-store.md) 和 [EventMesh Runtime](docs/zh/instruction/02-runtime.md) 完成运行环境的部署 + +完成 store 和 runtime 的部署后,就可以在 eventmesh-examples 模块下运行我们的 demo 来体验 eventmesh 了: + + TCP Sub + + ```shell + cd bin + sh tcp_eventmeshmessage_sub.sh + ``` + + TCP Pub + + ```shell + cd bin + sh tcp_pub_eventmeshmessage.sh + ``` + + TCP Sub Broadcast + + ```shell + cd bin + sh tcp_sub_eventmeshmessage_broadcast.sh + ``` + + TCP Pub Broadcast + + ```shell + cd bin + sh tcp_pub_eventmeshmessage_broadcast.sh + ``` + + HTTP Sub + + ```shell + cd bin + sh http_sub.sh + ``` + + HTTP Pub + + ```shell + cd bin + sh http_pub_eventmeshmessage.sh + ``` + + 之后, 你可以在 `/logs` 目录下面看到不同模式的运行日志 diff --git a/docs/zh/instruction/_category_.json b/docs/zh/instruction/_category_.json new file mode 100644 index 0000000000..06fd721fbd --- /dev/null +++ b/docs/zh/instruction/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Instructions", + "collapsed": false +} diff --git a/docs/zh/introduction.md b/docs/zh/introduction.md new file mode 100644 index 0000000000..43c821dd61 --- /dev/null +++ b/docs/zh/introduction.md @@ -0,0 +1,49 @@ +# Apache EventMesh (Incubating) + +[![CI status](https://github.com/apache/incubator-eventmesh/actions/workflows/ci.yml/badge.svg)](https://github.com/apache/incubator-eventmesh/actions/workflows/ci.yml) +[![CodeCov](https://codecov.io/gh/apache/incubator-eventmesh/branch/develop/graph/badge.svg)](https://codecov.io/gh/apache/incubator-eventmesh) +[![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/apache/incubator-eventmesh/context:java) +[![Total alerts](https://img.shields.io/lgtm/alerts/g/apache/incubator-eventmesh.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/apache/incubator-eventmesh/alerts/) +[![GitHub release](https://img.shields.io/badge/release-download-orange.svg)](https://github.com/apache/incubator-eventmesh/releases) +[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) + +## 什么是Event Mesh? + +EventMesh是一个动态的云原生事件驱动架构基础设施,用于分离应用程序和后端中间件层,它支持广泛的用例,包括复杂的混合云、使用了不同技术栈的分布式架构。 + +![architecture1](../images/eventmesh-define.png) + +**EventMesh架构:** + +![architecture1](../images/eventmesh-runtime.png) + +**EventMesh云原生结构:** + +![architecture2](../images/eventmesh-panels.png) + +Event Mesh允许将来自一个应用程序的事件动态路由到任何其他应用程序. Event Mesh的一般功能: + +* 事件驱动; +* 事件治理; +* 动态路由; +* 云原生 + +部件: + +* eventmesh-runtime:一种中间件,用于在事件生产者和消费者之间传输事件,支持云原生应用程序和微服务 +* eventmesh-sdk-java:当前支持HTTP、HHTTP、TCP和 [gRPC](https://grpc.io) 协议 + + +## 快速开始 + +1. 构建并部署 event-store(RocketMQ), 请参见[说明](instruction/01-store.md) +2. 构建并部署 eventmesh-runtime,请参见[说明](instruction/02-runtime.md) +3. 运行 eventmesh-sdk-java 演示,请参见[说明](instruction/03-demo.md) + +## 贡献 + +永远欢迎参与共建, 请参阅[贡献](../../03-new-contributor-guidelines.md)了解详细指南 + +您可以从发现和解决问题开始~ +[GitHub Issues](https://github.com/apache/incubator-eventmesh/issues) + diff --git a/docs/zh/metrics-tracing/01-prometheus.md b/docs/zh/metrics-tracing/01-prometheus.md new file mode 100644 index 0000000000..067cd00abf --- /dev/null +++ b/docs/zh/metrics-tracing/01-prometheus.md @@ -0,0 +1,46 @@ +# 通过 Prometheus 观察 Metrics + +## 下载 Prometheus + +官网:https://prometheus.io/ + +本地下载Prometheus:https://prometheus.io/download/ + +选择自己电脑对应的版本下载并解压缩 + +![Prometheus-download](../../images/Prometheus-download.png) + +### 2、在prometheus.yml中添加配置 + +如果你是Prometheus的新手,可以直接复制eventmesh-runtime/conf/prometheus.yml替换 + +例如:这是win-64的下载后的样子: + +![prometheus-yml](../../images/prometheus-yml.png) + +替换红框中的文件 + +如果你十分了解Prometheus,可以自行配置,eventmesh默认的导出的端口为19090。 + +ps:如果需要更换端口的话,请修改eventmesh-runtime/conf/eventmesh.properties中的 + +```properties +#prometheusPort +eventMesh.metrics.prometheus.port=19090 +``` + +## 运行 Prometheus 和 EventMesh + +双击Prometheus.exe运行 + +运行eventmesh-starter(参考[eventmesh-runtime-quickstart](eventmesh-runtime-quickstart.md)) + +运行eventmesh-example(参考[eventmesh-sdk-java-quickstart](eventmesh-sdk-java-quickstart.md)) + +打开浏览器访问:http://localhost:9090/ + +### 输入想观察的 Metrics + +输入’**eventmesh_**‘ 就会出现相关的指标的提示 + +![promethus-search](../../images/promethus-search.png) diff --git a/docs/zh/metrics-tracing/02-zipkin.md b/docs/zh/metrics-tracing/02-zipkin.md new file mode 100644 index 0000000000..913ee056cc --- /dev/null +++ b/docs/zh/metrics-tracing/02-zipkin.md @@ -0,0 +1,49 @@ +# 通过 Zipkin 观察 Trace + +### 1、下载和运行Zipkin + +请参考https://zipkin.io/pages/quickstart.html + + + +### 2、运行eventmesh + +运行eventmesh-starter(参考[eventmesh-runtime-quickstart](eventmesh-runtime-quickstart.md)) + +运行eventmesh-example(参考[eventmesh-sdk-java-quickstart](eventmesh-sdk-java-quickstart.md)) + + + +### 3、相关的设置 + +eventmesh-runtime/conf/eventmesh.properties中: + +默认的exporter是log,需要手动改成Zipkin + +```properties +#trace exporter +eventmesh.trace.exporter.type=Zipkin +``` +下面是关于Zipkin的各种配置 +```properties +#set the maximum batch size to use +eventmesh.trace.exporter.max.export.size=512 +#set the queue size. This must be >= the export batch size +eventmesh.trace.exporter.max.queue.size=2048 +#set the max amount of time an export can run before getting(TimeUnit=SECONDS) +eventmesh.trace.exporter.export.timeout=30 +#set time between two different exports(TimeUnit=SECONDS) +eventmesh.trace.exporter.export.interval=5 + +#zipkin +eventmesh.trace.export.zipkin.ip=localhost +eventmesh.trace.export.zipkin.port=9411 +``` + +以上都是相关的配置,如果你十分熟悉Zipkin的话可以自行修改。 + + + +### 4、观察 + +浏览器打开: **localhost:9411** diff --git a/docs/zh/metrics-tracing/_category_.json b/docs/zh/metrics-tracing/_category_.json new file mode 100644 index 0000000000..72c4414d12 --- /dev/null +++ b/docs/zh/metrics-tracing/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 4, + "label": "Metrics and Tracing", + "collapsed": false +} diff --git a/docs/zh/roadmap.md b/docs/zh/roadmap.md new file mode 100644 index 0000000000..d48a08d8ab --- /dev/null +++ b/docs/zh/roadmap.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 1 +--- + +# EventMesh产品路线图 + +下表列出了EventMesh的新特性和bug修复情况,详情请参考 [release notes](https://eventmesh.apache.org/events/release-notes/v1.4.0). + +## List of Features and Milestones + +| Status | Description | Reference | +| --- | --- | --- | +| **Implemented** | gRPC Integration | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/417) | +| **In Progress** | Event Governance for Choreography | [GitHub Issue](https://github.com/apache/incubator-eventmesh/blob/master/docs/en/features/eventmesh-workflow-design.md) | +| Planned | Knative Eventing Infrastructure | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/790), [GSoC '22](https://issues.apache.org/jira/browse/COMDEV-463) | +| Planned | Dashboard | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/700), [GSoC '22](https://issues.apache.org/jira/browse/COMDEV-465) | +| Planned | Event Streaming | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/676) | +| Planned | Federated Connector | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/577) | +| Planned | Transaction Event | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/697) | +| Planned | Event Query Language (EQL)| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/778) | +| Planned | Metadata consistency persistent| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/817) | +| Planned | Go SDK | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/762) | +| Planned | Rust SDK | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/815) | +| Planned | WebAssembly Runtime| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/576) | +| Planned | Filter Chain | [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/664) | +| Planned | Kafka-based EventStore| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/199) | +| Planned | Redis-based EventStore| [GitHub Issue](https://github.com/apache/incubator-eventmesh/issues/389) | diff --git a/docs/zh/sdk-java/01-intro.md b/docs/zh/sdk-java/01-intro.md new file mode 100644 index 0000000000..cb4b87640c --- /dev/null +++ b/docs/zh/sdk-java/01-intro.md @@ -0,0 +1,29 @@ +# 安装 + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java/badge.svg?style=for-the-badge)](https://maven-badges.herokuapp.com/maven-central/org.apache.eventmesh/eventmesh-sdk-java) + +EventMesh Java SDK 是在一个 Java 应用中集成 Eventmesh 所需的 Java 组件集合。SDK 支持使用 TCP、HTTP 和 gRPC 协议来发送和接收同步消息、异步消息和广播消息。SDK 实现了 EventMesh 消息、CloudEvents 和 OpenMessaging 形式。您可以在 [`eventmesh-example`](https://github.com/apache/incubator-eventmesh/tree/master/eventmesh-examples) 模块中查看示例项目。 + +## Gradle + +使用 Gradle 安装 EventMesh Java SDK,您需要在模块的 `build.gradle` 文件的依赖块中将 `org.apache.eventmesh:eventmesh-sdk-java` 声明为 `implementation`。 + +```groovy +dependencies { + implementation 'org.apache.eventmesh:eventmesh-sdk-java:1.4.0' +} +``` + +## Maven + +使用 Maven 安装 EventMesh Java SDK,您需要在项目 `pom.xml` 文件的依赖块中声明 `org.apache.eventmesh:eventmesh-sdk-java`。 + +```xml + + + org.apache.eventmesh + eventmesh-sdk-java + 1.4.0 + + +``` \ No newline at end of file diff --git a/docs/zh/sdk-java/02-http.md b/docs/zh/sdk-java/02-http.md new file mode 100644 index 0000000000..45a6698da7 --- /dev/null +++ b/docs/zh/sdk-java/02-http.md @@ -0,0 +1,114 @@ +# HTTP 协议 + +EventMesh Java SDK 实现了 HTTP 异步消息的生产者和消费者。二者都需要一个 `EventMeshHttpClientConfig` 类实例来指定 EventMesh HTTP 客户端的配置信息。其中的 `liteEventMeshAddr`、`userName` 和 `password` 字段需要和 EventMesh runtime `eventmesh.properties` 文件中的相匹配。 + +```java +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +public class HTTP { + public static void main(String[] args) throws Exception { + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr("localhost:10105") + .producerGroup("TEST_PRODUCER_GROUP") + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())) + .userName("eventmesh") + .password("password") + .build(); + /* ... */ + } +} +``` + +## HTTP 消费者 + +类 `EventMeshHttpConsumer` 实现了 `heartbeat`、`subscribe` 和 `unsubscribe` 方法。`subscribe` 方法接收一个 `SubscriptionItem` 对象的列表,其中定义了要订阅的话题和回调的 URL 地址。 + +```java +import org.apache.eventmesh.client.http.consumer.EventMeshHttpConsumer; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import com.google.common.collect.Lists; + +public class HTTP { + final String url = "http://localhost:8080/callback"; + final List topicList = Lists.newArrayList( + new SubscriptionItem("eventmesh-async-topic", SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC) + ); + + public static void main(String[] args) throws Exception { + /* ... */ + eventMeshHttpConsumer = new EventMeshHttpConsumer(eventMeshClientConfig); + eventMeshHttpConsumer.heartBeat(topicList, url); + eventMeshHttpConsumer.subscribe(topicList, url); + /* ... */ + eventMeshHttpConsumer.unsubscribe(topicList, url); + } +} +``` + +EventMesh runtime 将发送一个包含 [CloudEvents 格式](https://github.com/cloudevents/spec) 信息的 POST 请求到这个回调的 URL 地址。类 [SubController.java](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/controller/SubController.java) 实现了 Spring Boot controller,它将接收并解析回调信息。 + +## HTTP 生产者 + +类 `EventMeshHttpProducer` 实现了 `publish` 方法。`publish` 方法接收将被发布的消息和一个可选的 timeout 值。消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` +- `io.openmessaging.api.Message` + +```java +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.utils.JsonUtils; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class HTTP { + public static void main(String[] args) throws Exception { + /* ... */ + EventMeshHttpProducer eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject("eventmesh-async-topic") + .withSource(URI.create("/")) + .withDataContentType("application/cloudevents+json") + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + eventMeshHttpProducer.publish(event); + } +} +``` + +## 使用Curl 命令 + +也可以不通过Event Mesh SDK来体验事件的收发功能 + +### 事件发送 + +```shell +curl -H "Content-Type:application/json" -X POST -d '{"name": "admin", "pass":"12345678"}' http://127.0.0.1:10105/eventmesh/publish/TEST-TOPIC-HTTP-ASYNC +``` + +启动eventmesh运行时服务后,可以使用curl命令将事件用HTTP post方法发布到指定的主题,并且Body必须是JSON格式。发布事件的url类似于(http://127.0.0.1:10105/eventmesh/publish/TEST-TOPIC-HTTP-ASYNC),您将获得成功发布的结果。 + +### 事件订阅 + +```shell +curl -H "Content-Type:application/json" -X POST -d '{"url": "http://127.0.0.1:8088/sub/test", "consumerGroup":"TEST-GROUP", "topic":[{"mode":"CLUSTERING","topic":"TEST-TOPIC-HTTP-ASYNC","type":"ASYNC"}]}' http://127.0.0.1:10105/eventmesh/subscribe/local +``` + +启动eventmesh运行时服务器后,可以使用curl命令用HTTP post方法订阅指定的主题列表,并且Body必须是JSON格式。订阅url类似于(http://127.0.0.1:10105/eventmesh/subscribe/local),您将获得订阅成功的结果。你应该注意Body中的`url`字段,这意味着你需要在指定的url上启动HTTP服务实现监听,你可以在`eventmesh-examples`模块中看到这个例子。 \ No newline at end of file diff --git a/docs/zh/sdk-java/03-tcp.md b/docs/zh/sdk-java/03-tcp.md new file mode 100644 index 0000000000..54f5eca556 --- /dev/null +++ b/docs/zh/sdk-java/03-tcp.md @@ -0,0 +1,118 @@ +# TCP 协议 + +EventMesh Java SDK 实现了同步、异步和广播 TCP 消息的生产者和消费者。 二者都需要一个 `EventMeshHttpClientConfig` 类实例来指定 EventMesh TCP 客户端的配置信息。其中的 `host` 和 `port` 字段需要和 EventMesh runtime `eventmesh.properties` 文件中的相匹配。 + +```java +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import io.cloudevents.CloudEvent; + +public class AsyncSubscribe implements ReceiveMsgHook { + public static void main(String[] args) throws InterruptedException { + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + /* ... */ + } +} +``` + +## TCP 消费者 + +消费者应该实现 `ReceiveMsgHook` 类,其被定义在 [ReceiveMsgHook.java](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/ReceiveMsgHook.java)。 + +```java +public interface ReceiveMsgHook { + Optional handle(ProtocolMessage msg); +} +``` + +类 `EventMeshTCPClient` 实现了 `subscribe` 方法。该方法接收话题、`SubscriptionMode` 和 `SubscriptionType`。`handle` 方法将会在消费者从订阅的话题中收到消息时被调用。如果 `SubscriptionType` 是 `SYNC`,`handle` 的返回值将被发送回生产者。 + +```java +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import io.cloudevents.CloudEvent; + +public class TCPConsumer implements ReceiveMsgHook { + public static TCPConsumer handler = new TCPConsumer(); + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + client = EventMeshTCPClientFactory.createEventMeshTCPClient( + eventMeshTcpClientConfig, + CloudEvent.class + ); + client.init(); + + client.subscribe( + "eventmesh-sync-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.SYNC + ); + + client.registerSubBusiHandler(handler); + client.listen(); + } + + @Override + public Optional handle(CloudEvent message) { + log.info("Messaged received: {}", message); + return Optional.of(message); + } +} +``` + +## TCP 生产者 + +### 异步生产者 + +类 `EventMeshTCPClient` 实现了 `public` 方法。该方法接收将被发布的消息和一个可选的 timeout 值,并返回来自消费者的响应消息。 + +```java +/* ... */ +client = EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); +client.init(); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); +client.publish(event, 1000); +``` + +### 同步生产者 + +类 `EventMeshTCPClient` 实现了 `rr` 方法。该方法接收将被发布的消息和一个可选的 timeout 值,并返回来自消费者的响应消息。 + +```java +/* ... */ +client = EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); +client.init(); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + +Package response = client.rr(event, 1000); +CloudEvent replyEvent = EventFormatProvider + .getInstance() + .resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(response.getBody().toString().getBytes(StandardCharsets.UTF_8)); +``` \ No newline at end of file diff --git a/docs/zh/sdk-java/04-grpc.md b/docs/zh/sdk-java/04-grpc.md new file mode 100644 index 0000000000..b078187071 --- /dev/null +++ b/docs/zh/sdk-java/04-grpc.md @@ -0,0 +1,174 @@ +# gRPC 协议 + +EventMesh Java SDK 实现了 gRPC 同步、异步和广播消息的生产者和消费者。二者都需要一个 `EventMeshHttpClientConfig` 类实例来指定 EventMesh gRPC 客户端的配置信息。其中的 `liteEventMeshAddr`、`userName` 和 `password` 字段需要和 EventMesh runtime `eventmesh.properties` 文件中的相匹配。 + +```java +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import io.cloudevents.CloudEvent; + +public class CloudEventsAsyncSubscribe implements ReceiveMsgHook { + public static void main(String[] args) throws InterruptedException { + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr("localhost") + .serverPort(10205) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + /* ... */ + } +} +``` + +## gRPC 消费者 + +### 流消费者 + +EventMesh runtime 会将来自生产者的信息作为一系列事件流向流消费者发送。消费者应实现 `ReceiveHook` 类,其被定义在 [ReceiveMsgHook.java](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/ReceiveMsgHook.java)。 + +```java +public interface ReceiveMsgHook { + Optional handle(T msg) throws Throwable; + String getProtocolType(); +} +``` + +类 `EventMeshGrpcConsumer` 实现了 `registerListener`、`subscribe` 和 `unsubscribe` 方法。`subscribe` 方法接收一个 `SubscriptionItem` 对象的列表,其中定义了要订阅的话题。`registerListener` 接收一个实现了 `ReceiveMsgHook` 的实例。`handle` 方法将会在消费者收到订阅的主题消息时被调用。如果 `SubscriptionType` 是 `SYNC`,`handle` 的返回值将被发送回生产者。 + +```java +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import io.cloudevents.CloudEvent; + +public class CloudEventsAsyncSubscribe implements ReceiveMsgHook { + public static CloudEventsAsyncSubscribe handler = new CloudEventsAsyncSubscribe(); + public static void main(String[] args) throws InterruptedException { + /* ... */ + SubscriptionItem subscriptionItem = new SubscriptionItem( + "eventmesh-async-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.ASYNC + ); + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + eventMeshGrpcConsumer.registerListener(handler); + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + /* ... */ + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(CloudEvent message) { + log.info("Messaged received: {}", message); + return Optional.empty(); + } + + @Override + public String getProtocolType() { + return EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME; + } +} +``` + +### Webhook 消费者 + +类 `EventMeshGrpcConsumer` 的 `subscribe` 方法接收一个 `SubscriptionItem` 对象的列表,其中定义了要订阅的主题和一个可选的 timeout 值。如果提供了回调 URL,EventMesh runtime 将向回调 URL 地址发送一个包含 [CloudEvents 格式](https://github.com/cloudevents/spec) 消息的 POST 请求。[SubController.java](https://github.com/apache/incubator-eventmesh/blob/master/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/controller/SubController.java) 实现了一个接收并解析回调信息的 Spring Boot controller。 + +```java +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; + +@Component +public class SubService implements InitializingBean { + final String url = "http://localhost:8080/callback"; + + public void afterPropertiesSet() throws Exception { + /* ... */ + eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + eventMeshGrpcConsumer.init(); + + SubscriptionItem subscriptionItem = new SubscriptionItem( + "eventmesh-async-topic", + SubscriptionMode.CLUSTERING, + SubscriptionType.ASYNC + ); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem), url); + /* ... */ + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem), url); + } +} +``` + +## gRPC 生产者 + +### 异步生产者 + +类 `EventMeshGrpcProducer` 实现了 `publish` 方法。`publish` 方法接收将被发布的消息和一个可选的 timeout 值。消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +```java +/* ... */ +EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); +eventMeshGrpcProducer.init(); + +Map content = new HashMap<>(); +content.put("content", "testAsyncMessage"); + +CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); +eventMeshGrpcProducer.publish(event); +``` + +### 同步生产者 + +类 `EventMeshGrpcProducer` 实现了 `requestReply` 方法。`requestReply` 方法接收将被发布的消息和一个可选的 timeout 值。方法会返回消费者返回的消息。消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +### 批量生产者 + +类 `EventMeshGrpcProducer` 重写了 `publish` 方法,该方法接收一个将被发布的消息列表和一个可选的 timeout 值。列表中的消息应是下列类的一个实例: + +- `org.apache.eventmesh.common.EventMeshMessage` +- `io.cloudevents.CloudEvent` + +```java +/* ... */ +List cloudEventList = new ArrayList<>(); +for (int i = 0; i < 5; i++) { + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + + cloudEventList.add(event); +} + +eventMeshGrpcProducer.publish(cloudEventList); +/* ... */ +``` \ No newline at end of file diff --git a/docs/zh/sdk-java/_category_.json b/docs/zh/sdk-java/_category_.json new file mode 100644 index 0000000000..9d0a27c562 --- /dev/null +++ b/docs/zh/sdk-java/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "EventMesh SDK for Java", + "collapsed": false +} diff --git a/eventmesh-acl/build.gradle b/eventmesh-acl/build.gradle deleted file mode 100644 index 11bbc47bf2..0000000000 --- a/eventmesh-acl/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - id 'java' -} - -group 'cn.webank.defibus' -version '1.0.0' - -repositories { - mavenCentral() -} - -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' -} diff --git a/eventmesh-admin/README.md b/eventmesh-admin/README.md new file mode 100644 index 0000000000..69db9bb59a --- /dev/null +++ b/eventmesh-admin/README.md @@ -0,0 +1,53 @@ +# EventMesh Administration Module + +EventMesh Administration Module for EventMesh. It manages Admin Service, Configurations such as topics/subscriptions management.It works as a control plane and provide some interface to manage the eventmesh-runtime module and other configurations. + +## Administration Client Manager APIs + +### POST /topicManage +- Create a new topic if does not exist +- Exposed POST endpoint to create a new topic if it does not exist. + * Url - http://localhost:8081/topicManage + * sample request payload + ```json + { + "name": "mytopic1" + } + ``` + + Sample response + + ```json + { + "topic": "mytopic1", + "created_time": "2021-09-03", + } + ``` +### DELETE /topicManage/(string: topic) +- Delete a specific topic. +- Exposed DELETE endpoint to remove a specific topic + * URL - + ```url + http://localhost:8081/topicManage/mytopic1 + ``` + + * Response - + + ```json + { + "topic": "mytopic1", + } + ``` + +### GET /topicManage +- Retrieve a list of topics +- Exposed GET endpoint to retrieve all topics + * URL - + ```url + http://localhost:8081/topicManage + ``` + * Response + + ```json + ["mytopic1", "mytopic2"] + ``` diff --git a/eventmesh-admin/build.gradle b/eventmesh-admin/build.gradle new file mode 100644 index 0000000000..2944f98194 --- /dev/null +++ b/eventmesh-admin/build.gradle @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/build.gradle b/eventmesh-admin/eventmesh-admin-rocketmq/build.gradle new file mode 100644 index 0000000000..1217b33818 --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/build.gradle @@ -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. + */ + + +dependencies { + compileOnly project(":eventmesh-common") + + implementation "org.apache.httpcomponents:httpclient" + implementation "com.fasterxml.jackson.core:jackson-databind" + implementation "com.fasterxml.jackson.core:jackson-core" + implementation "com.fasterxml.jackson.core:jackson-annotations" + + implementation project(":eventmesh-connector-plugin:eventmesh-connector-api") + + testImplementation project(":eventmesh-connector-plugin:eventmesh-connector-api") +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/gradle.properties b/eventmesh-admin/eventmesh-admin-rocketmq/gradle.properties new file mode 100644 index 0000000000..7c28639929 --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/gradle.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +rocketmq_version=4.9.3 \ No newline at end of file diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/Constants.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/Constants.java new file mode 100644 index 0000000000..6547f9e3ee --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/Constants.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq; + +public class Constants { + + public static final String TOPIC_MANAGE_PATH = "/topicManage"; +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/HttpMethod.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/HttpMethod.java new file mode 100644 index 0000000000..2fb4ddef3e --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/HttpMethod.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq; + +public enum HttpMethod { + + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE + +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/controller/AdminController.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/controller/AdminController.java new file mode 100644 index 0000000000..9b85b4521c --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/controller/AdminController.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.controller; + +import static org.apache.eventmesh.admin.rocketmq.Constants.TOPIC_MANAGE_PATH; + +import org.apache.eventmesh.admin.rocketmq.handler.TopicsHandler; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpServer; + +public class AdminController { + + private static final Logger logger = LoggerFactory.getLogger(AdminController.class); + + public AdminController() { + } + + public void run(HttpServer server) throws IOException { + + server.createContext(TOPIC_MANAGE_PATH, new TopicsHandler()); + + logger.info("EventMesh-Admin Controller server context created successfully"); + } +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/handler/TopicsHandler.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/handler/TopicsHandler.java new file mode 100644 index 0000000000..ed9fbcadeb --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/handler/TopicsHandler.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.handler; + +import static org.apache.eventmesh.admin.rocketmq.Constants.TOPIC_MANAGE_PATH; + +import org.apache.eventmesh.admin.rocketmq.request.TopicCreateRequest; +import org.apache.eventmesh.admin.rocketmq.response.TopicResponse; +import org.apache.eventmesh.admin.rocketmq.util.JsonUtils; +import org.apache.eventmesh.admin.rocketmq.util.NetUtils; +import org.apache.eventmesh.admin.rocketmq.util.RequestMapping; + +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class TopicsHandler implements HttpHandler { + private static final Logger logger = LoggerFactory.getLogger(TopicsHandler.class); + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + + // create a new topic + if (RequestMapping.postMapping(TOPIC_MANAGE_PATH, httpExchange)) { + createTopicHandler(httpExchange); + return; + } + + OutputStream out = httpExchange.getResponseBody(); + httpExchange.sendResponseHeaders(500, 0); + String result = String.format("Please check your request url"); + logger.error(result); + out.write(result.getBytes()); + return; + } + + public void createTopicHandler(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String params = NetUtils.parsePostBody(httpExchange); + TopicCreateRequest topicCreateRequest = + JsonUtils.toObject(params, TopicCreateRequest.class); + String topic = topicCreateRequest.getName(); + + if (StringUtils.isBlank(topic)) { + result = "Create topic failed. Parameter topic not found."; + logger.error(result); + out.write(result.getBytes()); + return; + } + + //TBD: A new rocketmq service will be implemented for creating topics + TopicResponse topicResponse = null; + if (topicResponse != null) { + logger.info("create a new topic: {}", topic); + httpExchange.getResponseHeaders().add("Content-Type", "application/json"); + httpExchange.sendResponseHeaders(200, 0); + result = JsonUtils.toJson(topicResponse); + logger.info(result); + out.write(result.getBytes()); + return; + } else { + httpExchange.sendResponseHeaders(500, 0); + result = String.format("create topic failed! Server side error"); + logger.error(result); + out.write(result.getBytes()); + return; + } + } catch (Exception e) { + httpExchange.getResponseHeaders().add("Content-Type", "application/json"); + httpExchange.sendResponseHeaders(500, 0); + result = String.format("create topic failed! Server side error"); + logger.error(result); + out.write(result.getBytes()); + return; + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + } + +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/request/TopicCreateRequest.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/request/TopicCreateRequest.java new file mode 100644 index 0000000000..7adaa77cd2 --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/request/TopicCreateRequest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.request; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_EMPTY) +@JsonIgnoreProperties(ignoreUnknown = true) +public class TopicCreateRequest { + + private String name; + + @JsonCreator + public TopicCreateRequest(@JsonProperty("name") String topic) { + super(); + this.name = topic; + } + + @JsonProperty("name") + public String getName() { + return this.name; + } + + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/response/TopicResponse.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/response/TopicResponse.java new file mode 100644 index 0000000000..41b6e6a9b2 --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/response/TopicResponse.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.response; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class TopicResponse { + + private String topic; + private String createdTime; + + @JsonCreator + public TopicResponse(@JsonProperty("topic") String topic, + @JsonProperty("created_time") String createdTime) { + super(); + this.topic = topic; + this.createdTime = createdTime; + } + + @JsonProperty("topic") + public String getTopic() { + return this.topic; + } + + @JsonProperty("topic") + public void setTopic(String topic) { + this.topic = topic; + } + + @JsonProperty("created_time") + public String getCreatedTime() { + return createdTime; + } + + @JsonProperty("created_time") + public void setCreatedTime(String createdTime) { + this.createdTime = createdTime; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("TopicResponse {topic=" + this.topic + ","); + sb.append("created_time=" + this.createdTime + "}"); + return sb.toString(); + } + +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/JsonUtils.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/JsonUtils.java new file mode 100644 index 0000000000..6fbd31a2dd --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/JsonUtils.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.util; + +import java.io.IOException; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +public class JsonUtils { + + private static ObjectMapper objectMapper; + + static { + objectMapper = new ObjectMapper(); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + } + + public static byte[] serialize(String topic, Class data) throws JsonProcessingException { + if (data == null) { + return null; + } + return objectMapper.writeValueAsBytes(data); + } + + public static String toJson(Object obj) throws JsonProcessingException { + if (obj == null) { + return null; + } + return objectMapper.writeValueAsString(obj); + } + + public static T toObject(String json, Class clazz) throws JsonProcessingException { + return objectMapper.readValue(json, clazz); + } + + public static T deserialize(Class clazz, byte[] bytes) throws IOException { + if (bytes == null || bytes.length == 0) { + return null; + } + + return objectMapper.readValue(bytes, clazz); + } + + public static T deserialize(Class clazz, String json) throws IOException { + if (json == null || json.length() == 0) { + return null; + } + + return objectMapper.readValue(json, clazz); + } + + public static JsonNode getJsonNode(String json) throws IOException { + if (json == null || json.length() == 0) { + return null; + } + + return objectMapper.readTree(json); + } +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/NetUtils.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/NetUtils.java new file mode 100644 index 0000000000..7a16bf74f8 --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/NetUtils.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.util; + +import org.apache.eventmesh.admin.rocketmq.HttpMethod; + +import org.apache.http.Consts; + +import java.io.IOException; +import java.io.InputStreamReader; + +import com.sun.net.httpserver.HttpExchange; + +public class NetUtils { + + public static String parsePostBody(HttpExchange exchange) + throws IOException { + StringBuilder body = new StringBuilder(); + if (HttpMethod.POST.name().equalsIgnoreCase(exchange.getRequestMethod()) + || HttpMethod.PUT.name().equalsIgnoreCase(exchange.getRequestMethod())) { + try (InputStreamReader reader = + new InputStreamReader(exchange.getRequestBody(), Consts.UTF_8)) { + char[] buffer = new char[256]; + int read; + while ((read = reader.read(buffer)) != -1) { + body.append(buffer, 0, read); + } + } + } + return body.toString(); + } +} + diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/RequestMapping.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/RequestMapping.java new file mode 100644 index 0000000000..6a67e05813 --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/RequestMapping.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.util; + +import org.apache.eventmesh.admin.rocketmq.HttpMethod; + +import com.sun.net.httpserver.HttpExchange; + +public class RequestMapping { + + public static boolean postMapping(String value, HttpExchange httpExchange) { + if (HttpMethod.POST.name().equalsIgnoreCase(httpExchange.getRequestMethod())) { + String requestUri = httpExchange.getRequestURI().getPath(); + UrlMappingPattern matcher = new UrlMappingPattern(value); + return matcher.matches(requestUri); + } + return false; + } + + public static boolean getMapping(String value, HttpExchange httpExchange) { + if (HttpMethod.GET.name().equalsIgnoreCase(httpExchange.getRequestMethod())) { + String requestUri = httpExchange.getRequestURI().getPath(); + UrlMappingPattern matcher = new UrlMappingPattern(value); + return matcher.matches(requestUri); + } + return false; + } + + public static boolean putMapping(String value, HttpExchange httpExchange) { + if (HttpMethod.PUT.name().equalsIgnoreCase(httpExchange.getRequestMethod())) { + String requestUri = httpExchange.getRequestURI().getPath(); + UrlMappingPattern matcher = new UrlMappingPattern(value); + return matcher.matches(requestUri); + } + return false; + } + + public static boolean deleteMapping(String value, HttpExchange httpExchange) { + if (HttpMethod.DELETE.name().equalsIgnoreCase(httpExchange.getRequestMethod())) { + String requestUri = httpExchange.getRequestURI().getPath(); + UrlMappingPattern matcher = new UrlMappingPattern(value); + return matcher.matches(requestUri); + } + return false; + } + +} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/UrlMappingPattern.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/UrlMappingPattern.java new file mode 100644 index 0000000000..09d0eb3d67 --- /dev/null +++ b/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/UrlMappingPattern.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.admin.rocketmq.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class UrlMappingPattern { + + private static final String URL_PARAMETER_REGEX = "\\{(\\w*?)\\}"; + + private static final String URL_PARAMETER_MATCH_REGEX = + "\\([%\\\\w-.\\\\~!\\$&'\\\\(\\\\)\\\\*\\\\+,;=:\\\\[\\\\]@]+?\\)"; + + private static final Pattern URL_PARAMETER_PATTERN = Pattern.compile(URL_PARAMETER_REGEX); + + private static final String URL_FORMAT_REGEX = "(?:\\.\\{format\\})$"; + + private static final String URL_FORMAT_MATCH_REGEX = "(?:\\\\.\\([\\\\w%]+?\\))?"; + + private static final String URL_QUERY_STRING_REGEX = "(?:\\?.*?)?$"; + + private String urlMappingPattern; + + private Pattern compiledUrlMappingPattern; + + private List paramNames = new ArrayList(); + + public UrlMappingPattern(String pattern) { + super(); + setUrlMappingPattern(pattern); + compile(); + } + + public String getMappingPattern() { + return getUrlMappingPattern().replaceFirst(URL_FORMAT_REGEX, ""); + } + + private String getUrlMappingPattern() { + return urlMappingPattern; + } + + public Map extractPathParameterValues(String url) { + Matcher matcher = compiledUrlMappingPattern.matcher(url); + if (matcher.matches()) { + return extractParameters(matcher); + } + return null; + } + + public boolean matches(String url) { + return (extractPathParameterValues(url) != null); + } + + public void compile() { + acquireParamNames(); + String parsedPattern = + getUrlMappingPattern().replaceFirst(URL_FORMAT_REGEX, URL_FORMAT_MATCH_REGEX); + parsedPattern = parsedPattern.replaceAll(URL_PARAMETER_REGEX, URL_PARAMETER_MATCH_REGEX); + this.compiledUrlMappingPattern = Pattern.compile(parsedPattern + URL_QUERY_STRING_REGEX); + } + + private void acquireParamNames() { + Matcher m = URL_PARAMETER_PATTERN.matcher(getUrlMappingPattern()); + while (m.find()) { + paramNames.add(m.group(1)); + } + } + + private Map extractParameters(Matcher matcher) { + Map values = new HashMap(); + for (int i = 0; i < matcher.groupCount(); i++) { + String value = matcher.group(i + 1); + + if (value != null) { + values.put(paramNames.get(i), value); + } + } + return values; + } + + private void setUrlMappingPattern(String pattern) { + this.urlMappingPattern = pattern; + } + + public List getParamNames() { + return Collections.unmodifiableList(paramNames); + } +} diff --git a/eventmesh-admin/gradle.properties b/eventmesh-admin/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-admin/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-common/build.gradle b/eventmesh-common/build.gradle new file mode 100644 index 0000000000..5033b3aabb --- /dev/null +++ b/eventmesh-common/build.gradle @@ -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. + */ + +dependencies { + api "com.google.guava:guava" + api "org.slf4j:slf4j-api" + api "org.assertj:assertj-core" + api "org.apache.commons:commons-collections4" + api "org.apache.commons:commons-text" + api "org.apache.commons:commons-lang3" + + implementation "org.apache.logging.log4j:log4j-api" + implementation "org.apache.logging.log4j:log4j-core" + implementation "org.apache.logging.log4j:log4j-slf4j-impl" + + implementation 'com.github.seancfoley:ipaddress:5.3.3' + + implementation "com.lmax:disruptor" + + api "com.fasterxml.jackson.core:jackson-databind" + api "com.fasterxml.jackson.core:jackson-core" + api "com.fasterxml.jackson.core:jackson-annotations" + + implementation "org.apache.httpcomponents:httpclient" + + implementation "io.netty:netty-all" + + implementation "io.grpc:grpc-protobuf:1.17.1" + implementation "io.grpc:grpc-stub:1.17.1" + implementation "javax.annotation:javax.annotation-api:1.3.2" + + implementation "com.github.stefanbirkner:system-rules" + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + + testImplementation "org.apache.commons:commons-lang3" + + testImplementation "com.google.guava:guava" + + testImplementation "org.slf4j:slf4j-api" + testImplementation "org.apache.logging.log4j:log4j-api" + testImplementation "org.apache.logging.log4j:log4j-core" + testImplementation "org.apache.logging.log4j:log4j-slf4j-impl" + + testImplementation "com.lmax:disruptor" + + testImplementation "com.fasterxml.jackson.core:jackson-databind" + testImplementation "com.fasterxml.jackson.core:jackson-core" + testImplementation "com.fasterxml.jackson.core:jackson-annotations" + + testImplementation "org.apache.httpcomponents:httpclient" + + testImplementation "io.netty:netty-all" + + testImplementation "org.assertj:assertj-core" + + testImplementation "org.mockito:mockito-core" + testImplementation "org.powermock:powermock-module-junit4" + testImplementation "org.powermock:powermock-api-mockito2" +} diff --git a/eventmesh-common/gradle.properties b/eventmesh-common/gradle.properties new file mode 100644 index 0000000000..b1312a0905 --- /dev/null +++ b/eventmesh-common/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java new file mode 100644 index 0000000000..daa36e08f4 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common; + +public class Constants { + + public static final String DEFAULT_CHARSET = "UTF-8"; + + public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; + + public static final String LANGUAGE_JAVA = "JAVA"; + + public static final String HTTP_PROTOCOL_PREFIX = "http://"; + + public static final String HTTPS_PROTOCOL_PREFIX = "https://"; + + public static final String PROTOCOL_TYPE = "protocoltype"; + + public static final String PROTOCOL_VERSION = "protocolversion"; + + public static final String PROTOCOL_DESC = "protocoldesc"; + + public static final int DEFAULT_HTTP_TIME_OUT = 15000; + + public static final String EVENTMESH_MESSAGE_CONST_TTL = "ttl"; + + public static final String DEFAULT_EVENTMESH_MESSAGE_TTL = "4000"; + + public static final Integer DEFAULT_CLIENT_UNACK = 12; + + public static final String CONSTANTS_SERVICE_DESC_ENV = "env"; + + public static final String CONSTANTS_SERVICE_DESC_VERSION = "version"; + + public static final String CONSTANTS_INSTANCE_DESC_ENV = "env"; + + public static final String CONSTANTS_INSTANCE_DESC_IDC = "idc"; + + public static final String CONSTANTS_INSTANCE_DESC_SYSID = "sysId"; + + public static final String CONSTANTS_INSTANCE_DESC_IP = "ip"; + + public static final String CONSTANTS_INSTANCE_DESC_PORT = "port"; + + public static final String KEY_CONSTANTS_INSTANCE_DESC_PID = "pid"; + + public static final String RMB_UNIQ_ID = "rmbuniqid"; + + public static final String IDC_SEPERATER = "-"; + + public static final String PROPERTY_MESSAGE_TIMEOUT = "timeout"; + + public static final String PROPERTY_MESSAGE_SEARCH_KEYS = "searchkeys"; + + public static final String PROPERTY_MESSAGE_QUEUE_ID = "queueid"; + + public static final String PROPERTY_MESSAGE_QUEUE_OFFSET = "queueoffset"; + + public static final String PROPERTY_MESSAGE_DESTINATION = "destination"; + + public static final String PROPERTY_MESSAGE_MESSAGE_ID = "messageid"; + + public static final String PROPERTY_MESSAGE_BORN_HOST = "bornhost"; + + public static final String PROPERTY_MESSAGE_BORN_TIMESTAMP = "borntimestamp"; + + public static final String PROPERTY_MESSAGE_STORE_HOST = "storehost"; + + public static final String PROPERTY_MESSAGE_STORE_TIMESTAMP = "storetimestamp"; + + public static final String MESSAGE_PROP_SEPARATOR = "99"; + + public static final String EVENTMESH_CONF_HOME = System.getProperty("confPath", System.getenv("confPath")); + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/EventMeshMessage.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/EventMeshMessage.java new file mode 100644 index 0000000000..8fecc700fe --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/EventMeshMessage.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common; + +import java.util.HashMap; +import java.util.Map; + +import lombok.Builder; +import lombok.Data; + +/** + * EventMesh message. + */ +@Builder +@Data +public class EventMeshMessage { + + private String bizSeqNo; + + private String uniqueId; + + private String topic; + + private String content; + + private Map prop; + + @Builder.Default + private final long createTime = System.currentTimeMillis(); + + public EventMeshMessage addProp(String key, String val) { + if (prop == null) { + prop = new HashMap<>(); + } + prop.put(key, val); + return this; + } + + public String getProp(String key) { + if (prop == null) { + return null; + } + return prop.get(key); + } + + public EventMeshMessage removePropIfPresent(String key) { + if (prop == null) { + + return this; + } + prop.remove(key); + return this; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/ThreadPoolFactory.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/ThreadPoolFactory.java new file mode 100644 index 0000000000..8b6e4379d2 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/ThreadPoolFactory.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +public class ThreadPoolFactory { + + public static ThreadPoolExecutor createThreadPoolExecutor(int core, int max, final String threadName) { + return createThreadPoolExecutor(core, max, threadName, true); + } + + public static ThreadPoolExecutor createThreadPoolExecutor(int core, int max, final String threadName, + final boolean isDaemon) { + return createThreadPoolExecutor(core, max, new LinkedBlockingQueue<>(1000), threadName, isDaemon); + } + + public static ThreadPoolExecutor createThreadPoolExecutor(int core, int max, BlockingQueue blockingQueue, + final String threadName, final boolean isDaemon) { + return new ThreadPoolExecutor(core, max, 10 * 1000, TimeUnit.MILLISECONDS, blockingQueue, + new ThreadFactoryBuilder().setNameFormat(threadName).setDaemon(isDaemon).build() + ); + } + + public static ThreadPoolExecutor createThreadPoolExecutor(int core, int max, ThreadFactory threadFactory) { + return createThreadPoolExecutor(core, max, new LinkedBlockingQueue<>(1000), threadFactory); + } + + public static ThreadPoolExecutor createThreadPoolExecutor(int core, int max, BlockingQueue blockingQueue, + ThreadFactory threadFactory) { + return new ThreadPoolExecutor(core, max, 10 * 1000, TimeUnit.MILLISECONDS, blockingQueue, threadFactory); + } + + public static ScheduledExecutorService createSingleScheduledExecutor(final String threadName) { + return Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { + private AtomicInteger ai = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r, threadName + ai.incrementAndGet()); + thread.setDaemon(true); + return thread; + } + }); + } + + public static ScheduledExecutorService createScheduledExecutor(int core, final String threadName) { + return createScheduledExecutor(core, threadName, true); + } + + public static ScheduledExecutorService createScheduledExecutor(int core, final String threadName, + final boolean isDaemon) { + return Executors.newScheduledThreadPool(core, new ThreadFactory() { + private AtomicInteger ai = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r, threadName + ai.incrementAndGet()); + thread.setDaemon(isDaemon); + return thread; + } + }); + } + + public static ScheduledExecutorService createScheduledExecutor(int core, ThreadFactory threadFactory) { + return Executors.newScheduledThreadPool(core, threadFactory); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/CommonConfiguration.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/CommonConfiguration.java new file mode 100644 index 0000000000..fe88d58486 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/CommonConfiguration.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config; + +import org.apache.eventmesh.common.utils.IPUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import com.google.common.base.Preconditions; + +import lombok.Getter; + +public class CommonConfiguration { + public String eventMeshEnv = "P"; + public String eventMeshIDC = "FT"; + public String eventMeshCluster = "LS"; + public String eventMeshName = ""; + public String sysID = "5477"; + public String eventMeshConnectorPluginType = "rocketmq"; + public String eventMeshSecurityPluginType = "security"; + public String eventMeshRegistryPluginType = "namesrv"; + public List eventMeshMetricsPluginType; + public String eventMeshTracePluginType; + public String namesrvAddr = ""; + public String eventMeshRegistryPluginUsername = ""; + public String eventMeshRegistryPluginPassword = ""; + public Integer eventMeshRegisterIntervalInMills = 10 * 1000; + public Integer eventMeshFetchRegistryAddrInterval = 10 * 1000; + public String eventMeshServerIp = null; + public boolean eventMeshServerSecurityEnable = false; + public boolean eventMeshServerRegistryEnable = false; + public boolean eventMeshServerTraceEnable = false; + + @Getter + protected ConfigurationWrapper configurationWrapper; + + public String eventMeshWebhookOrigin = "eventmesh." + eventMeshIDC; + + public CommonConfiguration(ConfigurationWrapper configurationWrapper) { + this.configurationWrapper = configurationWrapper; + } + + public void init() { + + if (configurationWrapper != null) { + eventMeshEnv = checkNotEmpty(ConfKeys.KEYS_EVENTMESH_ENV); + + sysID = checkNumeric(ConfKeys.KEYS_EVENTMESH_SYSID); + + eventMeshCluster = checkNotEmpty(ConfKeys.KEYS_EVENTMESH_SERVER_CLUSTER); + + eventMeshName = checkNotEmpty(ConfKeys.KEYS_EVENTMESH_SERVER_NAME); + + eventMeshIDC = checkNotEmpty(ConfKeys.KEYS_EVENTMESH_IDC); + + eventMeshServerIp = get(ConfKeys.KEYS_EVENTMESH_SERVER_HOST_IP, IPUtils::getLocalAddress); + + eventMeshConnectorPluginType = checkNotEmpty(ConfKeys.KEYS_ENENTMESH_CONNECTOR_PLUGIN_TYPE); + + eventMeshServerSecurityEnable = Boolean.parseBoolean(get(ConfKeys.KEYS_EVENTMESH_SECURITY_ENABLED, () -> "false")); + + eventMeshSecurityPluginType = checkNotEmpty(ConfKeys.KEYS_ENENTMESH_SECURITY_PLUGIN_TYPE); + + eventMeshServerRegistryEnable = Boolean.parseBoolean(get(ConfKeys.KEYS_EVENTMESH_REGISTRY_ENABLED, () -> "false")); + + eventMeshRegistryPluginType = checkNotEmpty(ConfKeys.KEYS_ENENTMESH_REGISTRY_PLUGIN_TYPE); + + namesrvAddr = checkNotEmpty(ConfKeys.KEYS_EVENTMESH_REGISTRY_PULGIN_SERVER_ADDR); + + eventMeshRegistryPluginUsername = + Optional.ofNullable(configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_REGISTRY_PULGIN_USERNAME)).orElse(""); + + eventMeshRegistryPluginPassword = + Optional.ofNullable(configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_REGISTRY_PULGIN_PASSWORD)).orElse(""); + + String metricsPluginType = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_METRICS_PLUGIN_TYPE); + if (StringUtils.isNotEmpty(metricsPluginType)) { + eventMeshMetricsPluginType = Arrays.stream(metricsPluginType.split(",")) + .filter(StringUtils::isNotBlank) + .map(String::trim) + .collect(Collectors.toList()); + } + + eventMeshServerTraceEnable = Boolean.parseBoolean(get(ConfKeys.KEYS_EVENTMESH_TRACE_ENABLED, () -> "false")); + if (eventMeshServerTraceEnable) { + eventMeshTracePluginType = checkNotEmpty(ConfKeys.KEYS_EVENTMESH_TRACE_PLUGIN_TYPE); + } + } + } + + private String checkNotEmpty(String key) { + String value = configurationWrapper.getProp(key); + if (value != null) { + value = StringUtils.deleteWhitespace(value); + } + Preconditions.checkState(StringUtils.isNotEmpty(value), key + " is invalidated"); + return value; + } + + private String checkNumeric(String key) { + String value = configurationWrapper.getProp(key); + if (value != null) { + value = StringUtils.deleteWhitespace(value); + } + Preconditions.checkState(StringUtils.isNotEmpty(value) && StringUtils.isNumeric(value), key + " is invalidated"); + return value; + } + + private String get(String key, Supplier defaultValueSupplier) { + String value = configurationWrapper.getProp(key); + if (value != null) { + value = StringUtils.deleteWhitespace(value); + } + return StringUtils.isEmpty(value) ? defaultValueSupplier.get() : value; + } + + static class ConfKeys { + public static final String KEYS_EVENTMESH_ENV = "eventMesh.server.env"; + + public static final String KEYS_EVENTMESH_IDC = "eventMesh.server.idc"; + + public static final String KEYS_EVENTMESH_SYSID = "eventMesh.sysid"; + + public static final String KEYS_EVENTMESH_SERVER_CLUSTER = "eventMesh.server.cluster"; + + public static final String KEYS_EVENTMESH_SERVER_NAME = "eventMesh.server.name"; + + public static final String KEYS_EVENTMESH_SERVER_HOST_IP = "eventMesh.server.hostIp"; + + public static final String KEYS_EVENTMESH_SERVER_REGISTER_INTERVAL = + "eventMesh.server.registry.registerIntervalInMills"; + + public static final String KEYS_EVENTMESH_SERVER_FETCH_REGISTRY_ADDR_INTERVAL = + "eventMesh.server.registry.fetchRegistryAddrIntervalInMills"; + + public static final String KEYS_ENENTMESH_CONNECTOR_PLUGIN_TYPE = "eventMesh.connector.plugin.type"; + + public static final String KEYS_EVENTMESH_SECURITY_ENABLED = "eventMesh.server.security.enabled"; + + public static final String KEYS_ENENTMESH_SECURITY_PLUGIN_TYPE = "eventMesh.security.plugin.type"; + + public static final String KEYS_EVENTMESH_REGISTRY_ENABLED = "eventMesh.registry.plugin.enabled"; + + public static final String KEYS_ENENTMESH_REGISTRY_PLUGIN_TYPE = "eventMesh.registry.plugin.type"; + + public static final String KEYS_EVENTMESH_REGISTRY_PULGIN_SERVER_ADDR = "eventMesh.registry.plugin.server-addr"; + + public static final String KEYS_EVENTMESH_REGISTRY_PULGIN_USERNAME = "eventMesh.registry.plugin.username"; + + public static final String KEYS_EVENTMESH_REGISTRY_PULGIN_PASSWORD = "eventMesh.registry.plugin.password"; + + public static final String KEYS_EVENTMESH_METRICS_PLUGIN_TYPE = "eventMesh.metrics.plugin"; + + public static final String KEYS_EVENTMESH_TRACE_ENABLED = "eventMesh.server.trace.enabled"; + + public static final String KEYS_EVENTMESH_TRACE_PLUGIN_TYPE = "eventMesh.trace.plugin"; + } +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigurationWrapper.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigurationWrapper.java new file mode 100644 index 0000000000..b24426c92b --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigurationWrapper.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config; + +import org.apache.eventmesh.common.file.FileChangeContext; +import org.apache.eventmesh.common.file.FileChangeListener; +import org.apache.eventmesh.common.file.WatchFileManager; + +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Map.Entry; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Preconditions; + +public class ConfigurationWrapper { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final String directoryPath; + + private final String fileName; + + private final Properties properties = new Properties(); + + private final String file; + + private final boolean reload; + + private final FileChangeListener fileChangeListener = new FileChangeListener() { + @Override + public void onChanged(FileChangeContext changeContext) { + load(); + } + + @Override + public boolean support(FileChangeContext changeContext) { + return changeContext.getWatchEvent().context().toString().contains(fileName); + } + }; + + public ConfigurationWrapper(String directoryPath, String fileName, boolean reload) { + this.directoryPath = directoryPath + .replace('/', File.separator.charAt(0)) + .replace('\\', File.separator.charAt(0)); + this.fileName = fileName; + this.file = (directoryPath + File.separator + fileName) + .replace('/', File.separator.charAt(0)) + .replace('\\', File.separator.charAt(0)); + this.reload = reload; + init(); + } + + private void init() { + load(); + if (this.reload) { + WatchFileManager.registerFileChangeListener(directoryPath, fileChangeListener); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + logger.info("Configuration reload task closed"); + WatchFileManager.deregisterFileChangeListener(directoryPath); + })); + } + } + + private void load() { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + logger.info("loading config: {}", file); + properties.load(reader); + } catch (IOException e) { + logger.error("loading properties [{}] error", file, e); + } + } + + public String getProp(String key) { + return StringUtils.isEmpty(key) ? null : properties.getProperty(key, null); + } + + public int getIntProp(String configKey, int defaultValue) { + String configValue = StringUtils.deleteWhitespace(getProp(configKey)); + if (StringUtils.isEmpty(configValue)) { + return defaultValue; + } + Preconditions.checkState(StringUtils.isNumeric(configValue), + String.format("key:%s, value:%s error", configKey, configValue)); + return Integer.parseInt(configValue); + } + + public boolean getBoolProp(String configKey, boolean defaultValue) { + String configValue = StringUtils.deleteWhitespace(getProp(configKey)); + if (StringUtils.isEmpty(configValue)) { + return defaultValue; + } + return Boolean.parseBoolean(configValue); + } + + private String removePrefix(String key, String prefix, boolean removePrefix) { + return removePrefix ? key.replace(prefix, "") : key; + } + + public Properties getPropertiesByConfig(String prefix, boolean removePrefix) { + Properties properties = new Properties(); + prefix = prefix.endsWith(".") ? prefix : prefix + "."; + for (Entry entry : this.properties.entrySet()) { + String key = (String) entry.getKey(); + if (key.startsWith(prefix)) { + properties.put(removePrefix(key, prefix, removePrefix), entry.getValue()); + } + } + return properties; + } + + @SuppressWarnings("unchecked") + public T getPropertiesByConfig(String prefix, Class clazz, boolean removePrefix) { + ObjectMapper objectMapper = new ObjectMapper(); + return (T) objectMapper.convertValue(getPropertiesByConfig(prefix, removePrefix), clazz); + } + +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/exception/EventMeshException.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/exception/EventMeshException.java new file mode 100644 index 0000000000..9dc45c29f9 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/exception/EventMeshException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.exception; + +public class EventMeshException extends Exception { + + public EventMeshException(String message) { + super(message); + } + + public EventMeshException(String message, Throwable cause) { + super(message, cause); + } + + public EventMeshException(Throwable cause) { + super(cause); + } + + public EventMeshException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public EventMeshException(Integer errCode, String errMsg) { + super(String.format("errorCode: %s, errorMessage: %s", errCode, errMsg)); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/exception/JsonException.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/exception/JsonException.java new file mode 100644 index 0000000000..50f4bfa48c --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/exception/JsonException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.exception; + +/** + * Json format exception, see {@link org.apache.eventmesh.common.utils.JsonUtils}. + */ +public class JsonException extends RuntimeException { + + public JsonException(String message) { + super(message); + } + + public JsonException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/FileChangeContext.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/FileChangeContext.java new file mode 100644 index 0000000000..f46d2bc125 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/FileChangeContext.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.file; + +import java.nio.file.WatchEvent; + +public class FileChangeContext { + + private String directoryPath; + + private String fileName; + + private WatchEvent watchEvent; + + public String getDirectoryPath() { + return directoryPath; + } + + public void setDirectoryPath(String directoryPath) { + this.directoryPath = directoryPath; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public WatchEvent getWatchEvent() { + return watchEvent; + } + + public void setWatchEvent(WatchEvent watchEvent) { + this.watchEvent = watchEvent; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/FileChangeListener.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/FileChangeListener.java new file mode 100644 index 0000000000..a11efa9e9c --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/FileChangeListener.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.file; + +/** + * Users can register {@link FileChangeListener} with WatchFileManager via the + * {@link WatchFileManager#registerFileChangeListener(java.lang.String, org.apache.eventmesh.common.file.FileChangeListener)} method. + * The {@link FileChangeListener#onChanged(org.apache.eventmesh.common.file.FileChangeContext)} method fires when a file changes, + * and the {@link FileChangeListener#support(org.apache.eventmesh.common.file.FileChangeContext)} method let the user customize + * which files are supported + */ +public interface FileChangeListener { + /** + * triggered when a file change occurs + * + * @param changeContext file change context {@link FileChangeContext} + */ + void onChanged(FileChangeContext changeContext); + + /** + * true if support + * + * @param changeContext file change context {@link FileChangeContext} + * @return true if support + */ + boolean support(FileChangeContext changeContext); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/WatchFileManager.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/WatchFileManager.java new file mode 100644 index 0000000000..157109f0d1 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/WatchFileManager.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.file; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WatchFileManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(WatchFileManager.class); + + private static final AtomicBoolean CLOSED = new AtomicBoolean(false); + + private static final Map WATCH_FILE_TASK_MAP = new HashMap<>(); + + static { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + LOGGER.warn("[WatchFileManager] WatchFileManager closed"); + shutdown(); + })); + } + + public static void registerFileChangeListener(String directoryPath, + FileChangeListener listener) { + WatchFileTask task = WATCH_FILE_TASK_MAP.get(directoryPath); + if (task == null) { + task = new WatchFileTask(directoryPath); + task.start(); + WATCH_FILE_TASK_MAP.put(directoryPath, task); + } + task.addFileChangeListener(listener); + } + + public static void deregisterFileChangeListener(String directoryPath) { + WatchFileTask task = WATCH_FILE_TASK_MAP.get(directoryPath); + if (task != null) { + task.shutdown(); + WATCH_FILE_TASK_MAP.remove(directoryPath); + } + } + + private static void shutdown() { + if (!CLOSED.compareAndSet(false, true)) { + return; + } + LOGGER.warn("[WatchFileManager] start close"); + for (Map.Entry entry : WATCH_FILE_TASK_MAP.entrySet()) { + LOGGER.warn("[WatchFileManager] start to shutdown : " + entry.getKey()); + try { + entry.getValue().shutdown(); + } catch (Throwable ex) { + LOGGER.error("[WatchFileManager] shutdown has error : ", ex); + } + } + WATCH_FILE_TASK_MAP.clear(); + LOGGER.warn("[WatchFileManager] already closed"); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/WatchFileTask.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/WatchFileTask.java new file mode 100644 index 0000000000..577d75cc68 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/file/WatchFileTask.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.file; + +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WatchFileTask extends Thread { + + private static final Logger LOGGER = LoggerFactory.getLogger(WatchFileTask.class); + + private static final FileSystem FILE_SYSTEM = FileSystems.getDefault(); + + private final WatchService watchService; + + private final List fileChangeListeners = new ArrayList<>(); + + private volatile boolean watch = true; + + private final String directoryPath; + + public WatchFileTask(String directoryPath) { + this.directoryPath = directoryPath; + final Path path = Paths.get(directoryPath); + if (!path.toFile().exists()) { + throw new IllegalArgumentException("file directory not exist: " + directoryPath); + } + if (!path.toFile().isDirectory()) { + throw new IllegalArgumentException("must be a file directory : " + directoryPath); + } + + try { + WatchService service = FILE_SYSTEM.newWatchService(); + path.register(service, StandardWatchEventKinds.OVERFLOW, StandardWatchEventKinds.ENTRY_MODIFY, + StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); + this.watchService = service; + } catch (Throwable ex) { + throw new UnsupportedOperationException("WatchService registry fail", ex); + } + } + + public void addFileChangeListener(FileChangeListener fileChangeListener) { + if (fileChangeListener != null) { + fileChangeListeners.add(fileChangeListener); + } + } + + public void shutdown() { + watch = false; + } + + @Override + public void run() { + while (watch) { + try { + WatchKey watchKey = watchService.take(); + List> events = watchKey.pollEvents(); + watchKey.reset(); + + if (events.isEmpty()) { + continue; + } + + for (WatchEvent event : events) { + WatchEvent.Kind kind = event.kind(); + if (kind.equals(StandardWatchEventKinds.OVERFLOW)) { + LOGGER.warn("[WatchFileTask] file overflow: " + event.context()); + continue; + } + precessWatchEvent(event); + } + } catch (InterruptedException ex) { + boolean interrupted = Thread.interrupted(); + if (interrupted) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("[WatchFileTask] file watch is interrupted"); + } + } + } catch (Throwable ex) { + LOGGER.error("[WatchFileTask] an exception occurred during file listening : ", ex); + } + } + } + + private void precessWatchEvent(WatchEvent event) { + try { + for (FileChangeListener fileChangeListener : fileChangeListeners) { + FileChangeContext context = new FileChangeContext(); + context.setDirectoryPath(directoryPath); + context.setFileName(event.context().toString()); + context.setWatchEvent(event); + if (fileChangeListener.support(context)) { + fileChangeListener.onChanged(context); + } + } + } catch (Throwable ex) { + LOGGER.error("[WatchFileTask] file change event callback error : ", ex); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/LoadBalanceSelector.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/LoadBalanceSelector.java new file mode 100644 index 0000000000..3bee08c6ec --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/LoadBalanceSelector.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +/** + * LoadBalance Interface + * + *

see {@link RandomLoadBalanceSelector} + *

see {@link WeightRoundRobinLoadBalanceSelector} + * + * @param Target type + */ +public interface LoadBalanceSelector { + + /** + * Select one + * + * @return target + */ + T select(); + + /** + * load balance type see {@link LoadBalanceType} + * + * @return load balance type of the selector + */ + LoadBalanceType getType(); + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/LoadBalanceType.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/LoadBalanceType.java new file mode 100644 index 0000000000..6096abdf6b --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/LoadBalanceType.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +public enum LoadBalanceType { + RANDOM(0, "random load balance strategy"), + WEIGHT_ROUND_ROBIN(1, "weight round robin load balance strategy"), + WEIGHT_RANDOM(2, "weight random load balance strategy"); + + private int code; + private String desc; + + LoadBalanceType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/RandomLoadBalanceSelector.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/RandomLoadBalanceSelector.java new file mode 100644 index 0000000000..f04a7683c2 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/RandomLoadBalanceSelector.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.RandomUtils; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This selector use random strategy. + * Each selection will randomly give one from the given list + * + * @param Target type + */ +public class RandomLoadBalanceSelector implements LoadBalanceSelector { + + private final Logger logger = LoggerFactory.getLogger(RandomLoadBalanceSelector.class); + + private final List clusterGroup; + + public RandomLoadBalanceSelector(List clusterGroup) { + this.clusterGroup = clusterGroup; + } + + @Override + public T select() { + if (CollectionUtils.isEmpty(clusterGroup)) { + logger.warn("No servers available"); + return null; + } + return clusterGroup.get(RandomUtils.nextInt(0, clusterGroup.size())); + } + + @Override + public LoadBalanceType getType() { + return LoadBalanceType.RANDOM; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/Weight.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/Weight.java new file mode 100644 index 0000000000..cba255b43d --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/Weight.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +import java.util.concurrent.atomic.AtomicInteger; + +public class Weight { + + private T target; + + private final int weight; + + private final AtomicInteger currentWeight; + + public Weight(T target, int weight) { + this.target = target; + this.weight = weight; + this.currentWeight = new AtomicInteger(0); + } + + public void decreaseTotal(int total) { + currentWeight.addAndGet(-1 * total); + } + + public void increaseCurrentWeight() { + currentWeight.addAndGet(weight); + } + + + public T getTarget() { + return target; + } + + public void setTarget(T target) { + this.target = target; + } + + public int getWeight() { + return weight; + } + + + public AtomicInteger getCurrentWeight() { + return currentWeight; + } + + @Override + public String toString() { + return "Wight{" + + "target=" + target + + ", weight=" + weight + + ", currentWeight=" + currentWeight + + '}'; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/WeightRandomLoadBalanceSelector.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/WeightRandomLoadBalanceSelector.java new file mode 100644 index 0000000000..5b7904e69f --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/WeightRandomLoadBalanceSelector.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +import org.apache.eventmesh.common.exception.EventMeshException; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.RandomUtils; + +import java.util.List; + +/** + * This selector use the weighted random strategy to select from list. + * If all the weights are same, it will randomly select one from list. + * If the weights are different, it will select one by using RandomUtils.nextInt(0, w0 + w1 ... + wn) + * + * @param Target type + */ +public class WeightRandomLoadBalanceSelector implements LoadBalanceSelector { + + private final List> clusterGroup; + + private final int totalWeight; + + private boolean sameWeightGroup = true; + + public WeightRandomLoadBalanceSelector(List> clusterGroup) throws EventMeshException { + if (CollectionUtils.isEmpty(clusterGroup)) { + throw new EventMeshException("clusterGroup can not be empty"); + } + int totalWeight = 0; + int firstWeight = clusterGroup.get(0).getWeight(); + for (Weight weight : clusterGroup) { + totalWeight += weight.getWeight(); + if (sameWeightGroup && firstWeight != weight.getWeight()) { + sameWeightGroup = false; + } + } + this.clusterGroup = clusterGroup; + this.totalWeight = totalWeight; + } + + @Override + public T select() { + if (!sameWeightGroup) { + int targetWeight = RandomUtils.nextInt(0, totalWeight); + for (Weight weight : clusterGroup) { + targetWeight -= weight.getWeight(); + if (targetWeight < 0) { + return weight.getTarget(); + } + } + } + int length = clusterGroup.size(); + return clusterGroup.get(RandomUtils.nextInt(0, length)).getTarget(); + } + + @Override + public LoadBalanceType getType() { + return LoadBalanceType.WEIGHT_RANDOM; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/WeightRoundRobinLoadBalanceSelector.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/WeightRoundRobinLoadBalanceSelector.java new file mode 100644 index 0000000000..29dcc729e9 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/loadbalance/WeightRoundRobinLoadBalanceSelector.java @@ -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 org.apache.eventmesh.common.loadbalance; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This selector use the weighted round robin strategy to select from list. + * If the weight is greater, the probability of being selected is larger. + * + * @param Target type + */ +public class WeightRoundRobinLoadBalanceSelector implements LoadBalanceSelector { + + private final Logger logger = LoggerFactory.getLogger(WeightRoundRobinLoadBalanceSelector.class); + + private final List> clusterGroup; + + private final int totalWeight; + + public WeightRoundRobinLoadBalanceSelector(List> clusterGroup) { + int totalWeight = 0; + for (Weight weight : clusterGroup) { + totalWeight += weight.getWeight(); + } + this.clusterGroup = clusterGroup; + this.totalWeight = totalWeight; + } + + + @Override + @SuppressWarnings("ConstantConditions") + public T select() { + if (CollectionUtils.isEmpty(clusterGroup)) { + logger.warn("No servers available"); + return null; + } + Weight targetWeight = null; + for (Weight weight : clusterGroup) { + weight.increaseCurrentWeight(); + if (targetWeight == null || targetWeight.getCurrentWeight().get() < weight.getCurrentWeight().get()) { + targetWeight = weight; + } + } + targetWeight.decreaseTotal(totalWeight); + return targetWeight.getTarget(); + } + + @Override + public LoadBalanceType getType() { + return LoadBalanceType.WEIGHT_ROUND_ROBIN; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/ProtocolTransportObject.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/ProtocolTransportObject.java new file mode 100644 index 0000000000..ca7c36626a --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/ProtocolTransportObject.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol; + +import org.apache.eventmesh.common.protocol.http.HttpCommand; + +import java.io.Serializable; + +/** + *

    + *
  • Tcp transport object{@link org.apache.eventmesh.common.protocol.tcp.Package}
  • + *
  • Http transport object{@link HttpCommand}
  • + *
+ */ +public interface ProtocolTransportObject extends Serializable { +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionItem.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionItem.java new file mode 100644 index 0000000000..5fb0e5f132 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionItem.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol; + +import java.io.Serializable; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.common.base.Objects; + +public class SubscriptionItem implements Serializable { + + private String topic; + + @JsonDeserialize(converter = SubscriptionModeConverter.class) + private SubscriptionMode mode; + + @JsonDeserialize(converter = SubscriptionTypeConverter.class) + private SubscriptionType type; + + public SubscriptionItem() { + } + + public SubscriptionItem(String topic, SubscriptionMode mode, SubscriptionType type) { + this.topic = topic; + this.mode = mode; + this.type = type; + } + + public SubscriptionType getType() { + return type; + } + + public void setType(SubscriptionType type) { + this.type = type; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public SubscriptionMode getMode() { + return mode; + } + + public void setMode(SubscriptionMode mode) { + this.mode = mode; + } + + @Override + public String toString() { + return "SubscriptionItem{" + + "topic=" + topic + + ", mode=" + mode + + ", type=" + type + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SubscriptionItem that = (SubscriptionItem) o; + return Objects.equal(topic, that.topic) && mode == that.mode && type == that.type; + } + + @Override + public int hashCode() { + return Objects.hashCode(topic, mode, type); + } +} + + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionMode.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionMode.java new file mode 100644 index 0000000000..ad4b751a46 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionMode.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol; + +public enum SubscriptionMode { + + /** + * broadcast + */ + BROADCASTING("BROADCASTING"), + /** + * clustering + */ + CLUSTERING("CLUSTERING"); + + private String mode; + + SubscriptionMode(String mode) { + this.mode = mode; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionModeConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionModeConverter.java new file mode 100644 index 0000000000..2b1980f363 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionModeConverter.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.databind.util.Converter; + +public class SubscriptionModeConverter implements Converter { + @Override + public SubscriptionMode convert(String value) { + return SubscriptionMode.valueOf(value); + } + + @Override + public JavaType getInputType(TypeFactory typeFactory) { + return typeFactory.constructType(String.class); + } + + @Override + public JavaType getOutputType(TypeFactory typeFactory) { + return typeFactory.constructType(SubscriptionMode.class); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionType.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionType.java new file mode 100644 index 0000000000..7efe3089b8 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionType.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol; + +public enum SubscriptionType { + /** + * SYNC + */ + SYNC("SYNC"), + /** + * ASYNC + */ + ASYNC("ASYNC"); + + private String type; + + SubscriptionType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionTypeConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionTypeConverter.java new file mode 100644 index 0000000000..50d28914fe --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/SubscriptionTypeConverter.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.databind.util.Converter; + +public class SubscriptionTypeConverter implements Converter { + @Override + public SubscriptionType convert(String value) { + return SubscriptionType.valueOf(value); + } + + @Override + public JavaType getInputType(TypeFactory typeFactory) { + return typeFactory.constructType(String.class); + } + + @Override + public JavaType getOutputType(TypeFactory typeFactory) { + return typeFactory.constructType(SubscriptionType.class); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/BatchMessageWrapper.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/BatchMessageWrapper.java new file mode 100644 index 0000000000..4be71812b0 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/BatchMessageWrapper.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.grpc.common; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; + +public class BatchMessageWrapper implements ProtocolTransportObject { + + private final BatchMessage batchMessage; + + public BatchMessageWrapper(BatchMessage batchMessage) { + this.batchMessage = batchMessage; + } + + public BatchMessage getMessage() { + return batchMessage; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ProtocolKey.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ProtocolKey.java new file mode 100644 index 0000000000..0294ce1c54 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ProtocolKey.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.grpc.common; + +public class ProtocolKey { + + public static final String ENV = "env"; + public static final String IDC = "idc"; + public static final String SYS = "sys"; + public static final String PID = "pid"; + public static final String IP = "ip"; + public static final String USERNAME = "username"; + public static final String PASSWD = "passwd"; + public static final String LANGUAGE = "language"; + + public static final String PROTOCOL_TYPE = "protocoltype"; + public static final String PROTOCOL_VERSION = "protocolversion"; + public static final String PROTOCOL_DESC = "protocoldesc"; + + public static final String SEQ_NUM = "seqnum"; + public static final String UNIQUE_ID = "uniqueid"; + public static final String TTL = "ttl"; + public static final String PRODUCERGROUP = "producergroup"; + public static final String TAG = "tag"; + + public static final String CONTENT_TYPE = "contenttype"; +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/SimpleMessageWrapper.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/SimpleMessageWrapper.java new file mode 100644 index 0000000000..245f55bb38 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/SimpleMessageWrapper.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.grpc.common; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; + +public class SimpleMessageWrapper implements ProtocolTransportObject { + + private final SimpleMessage simpleMessage; + + public SimpleMessageWrapper(SimpleMessage simpleMessage) { + this.simpleMessage = simpleMessage; + } + + public SimpleMessage getMessage() { + return simpleMessage; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/StatusCode.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/StatusCode.java new file mode 100644 index 0000000000..15831d8c41 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/StatusCode.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.grpc.common; + +public enum StatusCode { + + SUCCESS("0", "success"), + OVERLOAD("1", "eventMesh overload, try later, "), + EVENTMESH_REQUESTCODE_INVALID("2", "requestCode can't be null, or must be number, "), + EVENTMESH_SEND_SYNC_MSG_ERR("3", "eventMesh send rr msg err, "), + EVENTMESH_WAITING_RR_MSG_ERR("4", "eventMesh waiting rr msg err, "), + EVENTMESH_PROTOCOL_HEADER_ERR("6", "eventMesh protocol[header] err, "), + EVENTMESH_PROTOCOL_BODY_ERR("7", "eventMesh protocol[body] err, "), + EVENTMESH_STOP("8", "eventMesh will stop or had stopped, "), + EVENTMESH_REJECT_BY_PROCESSOR_ERROR("9", "eventMesh reject by processor error, "), + EVENTMESH_BATCH_PUBLISH_ERR("10", "eventMesh batch publish messages error, "), + EVENTMESH_SEND_BATCHLOG_MSG_ERR("17", "eventMesh send batchlog msg err, "), + EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR("11", "eventMesh batch msg speed over the limit, "), + EVENTMESH_PACKAGE_MSG_ERR("12", "eventMesh package msg err, "), + EVENTMESH_GROUP_PRODUCER_STOPED_ERR("13", "eventMesh group producer stopped, "), + EVENTMESH_SEND_ASYNC_MSG_ERR("14", "eventMesh send async msg err, "), + EVENTMESH_REPLY_MSG_ERR("15", "eventMesh reply msg err, "), + EVENTMESH_RUNTIME_ERR("16", "eventMesh runtime err, "), + EVENTMESH_SUBSCRIBE_ERR("17", "eventMesh subscribe err"), + EVENTMESH_UNSUBSCRIBE_ERR("18", "eventMesh unsubscribe err"), + EVENTMESH_HEARTBEAT_ERR("19", "eventMesh heartbeat err"), + EVENTMESH_ACL_ERR("20", "eventMesh acl err"), + EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR("21", "eventMesh send message speed over the limit err."), + EVENTMESH_REQUEST_REPLY_MSG_ERR("22", "eventMesh request reply msg err, "); + + private String retCode; + + private String errMsg; + + StatusCode(String retCode, String errMsg) { + this.retCode = retCode; + this.errMsg = errMsg; + } + + public String getRetCode() { + return retCode; + } + + public void setRetCode(String retCode) { + this.retCode = retCode; + } + + public String getErrMsg() { + return errMsg; + } + + public void setErrMsg(String errMsg) { + this.errMsg = errMsg; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessage.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessage.java new file mode 100644 index 0000000000..9b638fc51e --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessage.java @@ -0,0 +1,2574 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +/** + * Protobuf type {@code eventmesh.common.protocol.grpc.BatchMessage} + */ +@SuppressWarnings({"all"}) +public final class BatchMessage extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.BatchMessage) + BatchMessageOrBuilder { +private static final long serialVersionUID = 0L; + // Use BatchMessage.newBuilder() to construct. + private BatchMessage(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BatchMessage() { + producerGroup_ = ""; + topic_ = ""; + messageItem_ = java.util.Collections.emptyList(); + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private BatchMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + RequestHeader.Builder subBuilder = null; + if (header_ != null) { + subBuilder = header_.toBuilder(); + } + header_ = input.readMessage(RequestHeader.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(header_); + header_ = subBuilder.buildPartial(); + } + + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + producerGroup_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + topic_ = s; + break; + } + case 34: { + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + messageItem_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000008; + } + messageItem_.add( + input.readMessage(MessageItem.parser(), extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + messageItem_ = java.util.Collections.unmodifiableList(messageItem_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + BatchMessage.class, Builder.class); + } + + public interface MessageItemOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.BatchMessage.MessageItem) + com.google.protobuf.MessageOrBuilder { + + /** + * string content = 1; + */ + String getContent(); + /** + * string content = 1; + */ + com.google.protobuf.ByteString + getContentBytes(); + + /** + * string ttl = 2; + */ + String getTtl(); + /** + * string ttl = 2; + */ + com.google.protobuf.ByteString + getTtlBytes(); + + /** + * string uniqueId = 3; + */ + String getUniqueId(); + /** + * string uniqueId = 3; + */ + com.google.protobuf.ByteString + getUniqueIdBytes(); + + /** + * string seqNum = 4; + */ + String getSeqNum(); + /** + * string seqNum = 4; + */ + com.google.protobuf.ByteString + getSeqNumBytes(); + + /** + * string tag = 5; + */ + String getTag(); + /** + * string tag = 5; + */ + com.google.protobuf.ByteString + getTagBytes(); + + /** + * map<string, string> properties = 6; + */ + int getPropertiesCount(); + /** + * map<string, string> properties = 6; + */ + boolean containsProperties( + String key); + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + java.util.Map + getProperties(); + /** + * map<string, string> properties = 6; + */ + java.util.Map + getPropertiesMap(); + /** + * map<string, string> properties = 6; + */ + + String getPropertiesOrDefault( + String key, + String defaultValue); + /** + * map<string, string> properties = 6; + */ + + String getPropertiesOrThrow( + String key); + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.BatchMessage.MessageItem} + */ + public static final class MessageItem extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.BatchMessage.MessageItem) + MessageItemOrBuilder { + private static final long serialVersionUID = 0L; + // Use MessageItem.newBuilder() to construct. + private MessageItem(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private MessageItem() { + content_ = ""; + ttl_ = ""; + uniqueId_ = ""; + seqNum_ = ""; + tag_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private MessageItem( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + String s = input.readStringRequireUtf8(); + + content_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + ttl_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + uniqueId_ = s; + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + seqNum_ = s; + break; + } + case 42: { + String s = input.readStringRequireUtf8(); + + tag_ = s; + break; + } + case 50: { + if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + properties_ = com.google.protobuf.MapField.newMapField( + PropertiesDefaultEntryHolder.defaultEntry); + mutable_bitField0_ |= 0x00000020; + } + com.google.protobuf.MapEntry + properties__ = input.readMessage( + PropertiesDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); + properties_.getMutableMap().put( + properties__.getKey(), properties__.getValue()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 6: + return internalGetProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_fieldAccessorTable + .ensureFieldAccessorsInitialized( + MessageItem.class, Builder.class); + } + + private int bitField0_; + public static final int CONTENT_FIELD_NUMBER = 1; + private volatile Object content_; + /** + * string content = 1; + */ + public String getContent() { + Object ref = content_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + content_ = s; + return s; + } + } + /** + * string content = 1; + */ + public com.google.protobuf.ByteString + getContentBytes() { + Object ref = content_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TTL_FIELD_NUMBER = 2; + private volatile Object ttl_; + /** + * string ttl = 2; + */ + public String getTtl() { + Object ref = ttl_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ttl_ = s; + return s; + } + } + /** + * string ttl = 2; + */ + public com.google.protobuf.ByteString + getTtlBytes() { + Object ref = ttl_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ttl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int UNIQUEID_FIELD_NUMBER = 3; + private volatile Object uniqueId_; + /** + * string uniqueId = 3; + */ + public String getUniqueId() { + Object ref = uniqueId_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + uniqueId_ = s; + return s; + } + } + /** + * string uniqueId = 3; + */ + public com.google.protobuf.ByteString + getUniqueIdBytes() { + Object ref = uniqueId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + uniqueId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SEQNUM_FIELD_NUMBER = 4; + private volatile Object seqNum_; + /** + * string seqNum = 4; + */ + public String getSeqNum() { + Object ref = seqNum_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + seqNum_ = s; + return s; + } + } + /** + * string seqNum = 4; + */ + public com.google.protobuf.ByteString + getSeqNumBytes() { + Object ref = seqNum_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + seqNum_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TAG_FIELD_NUMBER = 5; + private volatile Object tag_; + /** + * string tag = 5; + */ + public String getTag() { + Object ref = tag_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + tag_ = s; + return s; + } + } + /** + * string tag = 5; + */ + public com.google.protobuf.ByteString + getTagBytes() { + Object ref = tag_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + tag_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PROPERTIES_FIELD_NUMBER = 6; + private static final class PropertiesDefaultEntryHolder { + static final com.google.protobuf.MapEntry< + String, String> defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_PropertiesEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.STRING, + ""); + } + private com.google.protobuf.MapField< + String, String> properties_; + private com.google.protobuf.MapField + internalGetProperties() { + if (properties_ == null) { + return com.google.protobuf.MapField.emptyMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + return properties_; + } + + public int getPropertiesCount() { + return internalGetProperties().getMap().size(); + } + /** + * map<string, string> properties = 6; + */ + + public boolean containsProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetProperties().getMap().containsKey(key); + } + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + public java.util.Map getProperties() { + return getPropertiesMap(); + } + /** + * map<string, string> properties = 6; + */ + + public java.util.Map getPropertiesMap() { + return internalGetProperties().getMap(); + } + /** + * map<string, string> properties = 6; + */ + + public String getPropertiesOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> properties = 6; + */ + + public String getPropertiesOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getContentBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, content_); + } + if (!getTtlBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, ttl_); + } + if (!getUniqueIdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, uniqueId_); + } + if (!getSeqNumBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, seqNum_); + } + if (!getTagBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, tag_); + } + com.google.protobuf.GeneratedMessageV3 + .serializeStringMapTo( + output, + internalGetProperties(), + PropertiesDefaultEntryHolder.defaultEntry, + 6); + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getContentBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, content_); + } + if (!getTtlBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, ttl_); + } + if (!getUniqueIdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, uniqueId_); + } + if (!getSeqNumBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, seqNum_); + } + if (!getTagBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, tag_); + } + for (java.util.Map.Entry entry + : internalGetProperties().getMap().entrySet()) { + com.google.protobuf.MapEntry + properties__ = PropertiesDefaultEntryHolder.defaultEntry.newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(6, properties__); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof MessageItem)) { + return super.equals(obj); + } + MessageItem other = (MessageItem) obj; + + boolean result = true; + result = result && getContent() + .equals(other.getContent()); + result = result && getTtl() + .equals(other.getTtl()); + result = result && getUniqueId() + .equals(other.getUniqueId()); + result = result && getSeqNum() + .equals(other.getSeqNum()); + result = result && getTag() + .equals(other.getTag()); + result = result && internalGetProperties().equals( + other.internalGetProperties()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + CONTENT_FIELD_NUMBER; + hash = (53 * hash) + getContent().hashCode(); + hash = (37 * hash) + TTL_FIELD_NUMBER; + hash = (53 * hash) + getTtl().hashCode(); + hash = (37 * hash) + UNIQUEID_FIELD_NUMBER; + hash = (53 * hash) + getUniqueId().hashCode(); + hash = (37 * hash) + SEQNUM_FIELD_NUMBER; + hash = (53 * hash) + getSeqNum().hashCode(); + hash = (37 * hash) + TAG_FIELD_NUMBER; + hash = (53 * hash) + getTag().hashCode(); + if (!internalGetProperties().getMap().isEmpty()) { + hash = (37 * hash) + PROPERTIES_FIELD_NUMBER; + hash = (53 * hash) + internalGetProperties().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static MessageItem parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static MessageItem parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static MessageItem parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static MessageItem parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static MessageItem parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static MessageItem parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static MessageItem parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static MessageItem parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static MessageItem parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static MessageItem parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static MessageItem parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static MessageItem parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(MessageItem prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.BatchMessage.MessageItem} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.BatchMessage.MessageItem) + MessageItemOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 6: + return internalGetProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMutableMapField( + int number) { + switch (number) { + case 6: + return internalGetMutableProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_fieldAccessorTable + .ensureFieldAccessorsInitialized( + MessageItem.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage.MessageItem.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + content_ = ""; + + ttl_ = ""; + + uniqueId_ = ""; + + seqNum_ = ""; + + tag_ = ""; + + internalGetMutableProperties().clear(); + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_descriptor; + } + + public MessageItem getDefaultInstanceForType() { + return MessageItem.getDefaultInstance(); + } + + public MessageItem build() { + MessageItem result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public MessageItem buildPartial() { + MessageItem result = new MessageItem(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + result.content_ = content_; + result.ttl_ = ttl_; + result.uniqueId_ = uniqueId_; + result.seqNum_ = seqNum_; + result.tag_ = tag_; + result.properties_ = internalGetProperties(); + result.properties_.makeImmutable(); + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof MessageItem) { + return mergeFrom((MessageItem)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(MessageItem other) { + if (other == MessageItem.getDefaultInstance()) return this; + if (!other.getContent().isEmpty()) { + content_ = other.content_; + onChanged(); + } + if (!other.getTtl().isEmpty()) { + ttl_ = other.ttl_; + onChanged(); + } + if (!other.getUniqueId().isEmpty()) { + uniqueId_ = other.uniqueId_; + onChanged(); + } + if (!other.getSeqNum().isEmpty()) { + seqNum_ = other.seqNum_; + onChanged(); + } + if (!other.getTag().isEmpty()) { + tag_ = other.tag_; + onChanged(); + } + internalGetMutableProperties().mergeFrom( + other.internalGetProperties()); + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + MessageItem parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (MessageItem) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private Object content_ = ""; + /** + * string content = 1; + */ + public String getContent() { + Object ref = content_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + content_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string content = 1; + */ + public com.google.protobuf.ByteString + getContentBytes() { + Object ref = content_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string content = 1; + */ + public Builder setContent( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + content_ = value; + onChanged(); + return this; + } + /** + * string content = 1; + */ + public Builder clearContent() { + + content_ = getDefaultInstance().getContent(); + onChanged(); + return this; + } + /** + * string content = 1; + */ + public Builder setContentBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + content_ = value; + onChanged(); + return this; + } + + private Object ttl_ = ""; + /** + * string ttl = 2; + */ + public String getTtl() { + Object ref = ttl_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ttl_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string ttl = 2; + */ + public com.google.protobuf.ByteString + getTtlBytes() { + Object ref = ttl_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ttl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string ttl = 2; + */ + public Builder setTtl( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + ttl_ = value; + onChanged(); + return this; + } + /** + * string ttl = 2; + */ + public Builder clearTtl() { + + ttl_ = getDefaultInstance().getTtl(); + onChanged(); + return this; + } + /** + * string ttl = 2; + */ + public Builder setTtlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + ttl_ = value; + onChanged(); + return this; + } + + private Object uniqueId_ = ""; + /** + * string uniqueId = 3; + */ + public String getUniqueId() { + Object ref = uniqueId_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + uniqueId_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string uniqueId = 3; + */ + public com.google.protobuf.ByteString + getUniqueIdBytes() { + Object ref = uniqueId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + uniqueId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string uniqueId = 3; + */ + public Builder setUniqueId( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + uniqueId_ = value; + onChanged(); + return this; + } + /** + * string uniqueId = 3; + */ + public Builder clearUniqueId() { + + uniqueId_ = getDefaultInstance().getUniqueId(); + onChanged(); + return this; + } + /** + * string uniqueId = 3; + */ + public Builder setUniqueIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + uniqueId_ = value; + onChanged(); + return this; + } + + private Object seqNum_ = ""; + /** + * string seqNum = 4; + */ + public String getSeqNum() { + Object ref = seqNum_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + seqNum_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string seqNum = 4; + */ + public com.google.protobuf.ByteString + getSeqNumBytes() { + Object ref = seqNum_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + seqNum_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string seqNum = 4; + */ + public Builder setSeqNum( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + seqNum_ = value; + onChanged(); + return this; + } + /** + * string seqNum = 4; + */ + public Builder clearSeqNum() { + + seqNum_ = getDefaultInstance().getSeqNum(); + onChanged(); + return this; + } + /** + * string seqNum = 4; + */ + public Builder setSeqNumBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + seqNum_ = value; + onChanged(); + return this; + } + + private Object tag_ = ""; + /** + * string tag = 5; + */ + public String getTag() { + Object ref = tag_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + tag_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string tag = 5; + */ + public com.google.protobuf.ByteString + getTagBytes() { + Object ref = tag_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + tag_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string tag = 5; + */ + public Builder setTag( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + tag_ = value; + onChanged(); + return this; + } + /** + * string tag = 5; + */ + public Builder clearTag() { + + tag_ = getDefaultInstance().getTag(); + onChanged(); + return this; + } + /** + * string tag = 5; + */ + public Builder setTagBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + tag_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.MapField< + String, String> properties_; + private com.google.protobuf.MapField + internalGetProperties() { + if (properties_ == null) { + return com.google.protobuf.MapField.emptyMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + return properties_; + } + private com.google.protobuf.MapField + internalGetMutableProperties() { + onChanged();; + if (properties_ == null) { + properties_ = com.google.protobuf.MapField.newMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + if (!properties_.isMutable()) { + properties_ = properties_.copy(); + } + return properties_; + } + + public int getPropertiesCount() { + return internalGetProperties().getMap().size(); + } + /** + * map<string, string> properties = 6; + */ + + public boolean containsProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetProperties().getMap().containsKey(key); + } + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + public java.util.Map getProperties() { + return getPropertiesMap(); + } + /** + * map<string, string> properties = 6; + */ + + public java.util.Map getPropertiesMap() { + return internalGetProperties().getMap(); + } + /** + * map<string, string> properties = 6; + */ + + public String getPropertiesOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> properties = 6; + */ + + public String getPropertiesOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + public Builder clearProperties() { + internalGetMutableProperties().getMutableMap() + .clear(); + return this; + } + /** + * map<string, string> properties = 6; + */ + + public Builder removeProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + internalGetMutableProperties().getMutableMap() + .remove(key); + return this; + } + /** + * Use alternate mutation accessors instead. + */ + @Deprecated + public java.util.Map + getMutableProperties() { + return internalGetMutableProperties().getMutableMap(); + } + /** + * map<string, string> properties = 6; + */ + public Builder putProperties( + String key, + String value) { + if (key == null) { throw new NullPointerException(); } + if (value == null) { throw new NullPointerException(); } + internalGetMutableProperties().getMutableMap() + .put(key, value); + return this; + } + /** + * map<string, string> properties = 6; + */ + + public Builder putAllProperties( + java.util.Map values) { + internalGetMutableProperties().getMutableMap() + .putAll(values); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.BatchMessage.MessageItem) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.BatchMessage.MessageItem) + private static final MessageItem DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new MessageItem(); + } + + public static MessageItem getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public MessageItem parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new MessageItem(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public MessageItem getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private int bitField0_; + public static final int HEADER_FIELD_NUMBER = 1; + private RequestHeader header_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + return getHeader(); + } + + public static final int PRODUCERGROUP_FIELD_NUMBER = 2; + private volatile Object producerGroup_; + /** + * string producerGroup = 2; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } + } + /** + * string producerGroup = 2; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TOPIC_FIELD_NUMBER = 3; + private volatile Object topic_; + /** + * string topic = 3; + */ + public String getTopic() { + Object ref = topic_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } + } + /** + * string topic = 3; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int MESSAGEITEM_FIELD_NUMBER = 4; + private java.util.List messageItem_; + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public java.util.List getMessageItemList() { + return messageItem_; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public java.util.List + getMessageItemOrBuilderList() { + return messageItem_; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public int getMessageItemCount() { + return messageItem_.size(); + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public MessageItem getMessageItem(int index) { + return messageItem_.get(index); + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public MessageItemOrBuilder getMessageItemOrBuilder( + int index) { + return messageItem_.get(index); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (header_ != null) { + output.writeMessage(1, getHeader()); + } + if (!getProducerGroupBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, producerGroup_); + } + if (!getTopicBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, topic_); + } + for (int i = 0; i < messageItem_.size(); i++) { + output.writeMessage(4, messageItem_.get(i)); + } + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (header_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getHeader()); + } + if (!getProducerGroupBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, producerGroup_); + } + if (!getTopicBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, topic_); + } + for (int i = 0; i < messageItem_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, messageItem_.get(i)); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof BatchMessage)) { + return super.equals(obj); + } + BatchMessage other = (BatchMessage) obj; + + boolean result = true; + result = result && (hasHeader() == other.hasHeader()); + if (hasHeader()) { + result = result && getHeader() + .equals(other.getHeader()); + } + result = result && getProducerGroup() + .equals(other.getProducerGroup()); + result = result && getTopic() + .equals(other.getTopic()); + result = result && getMessageItemList() + .equals(other.getMessageItemList()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasHeader()) { + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + } + hash = (37 * hash) + PRODUCERGROUP_FIELD_NUMBER; + hash = (53 * hash) + getProducerGroup().hashCode(); + hash = (37 * hash) + TOPIC_FIELD_NUMBER; + hash = (53 * hash) + getTopic().hashCode(); + if (getMessageItemCount() > 0) { + hash = (37 * hash) + MESSAGEITEM_FIELD_NUMBER; + hash = (53 * hash) + getMessageItemList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static BatchMessage parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static BatchMessage parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static BatchMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static BatchMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static BatchMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static BatchMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static BatchMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static BatchMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static BatchMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static BatchMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static BatchMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static BatchMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(BatchMessage prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.BatchMessage} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.BatchMessage) + BatchMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + BatchMessage.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getMessageItemFieldBuilder(); + } + } + public Builder clear() { + super.clear(); + if (headerBuilder_ == null) { + header_ = null; + } else { + header_ = null; + headerBuilder_ = null; + } + producerGroup_ = ""; + + topic_ = ""; + + if (messageItemBuilder_ == null) { + messageItem_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + } else { + messageItemBuilder_.clear(); + } + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_BatchMessage_descriptor; + } + + public BatchMessage getDefaultInstanceForType() { + return BatchMessage.getDefaultInstance(); + } + + public BatchMessage build() { + BatchMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public BatchMessage buildPartial() { + BatchMessage result = new BatchMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (headerBuilder_ == null) { + result.header_ = header_; + } else { + result.header_ = headerBuilder_.build(); + } + result.producerGroup_ = producerGroup_; + result.topic_ = topic_; + if (messageItemBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008)) { + messageItem_ = java.util.Collections.unmodifiableList(messageItem_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.messageItem_ = messageItem_; + } else { + result.messageItem_ = messageItemBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof BatchMessage) { + return mergeFrom((BatchMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(BatchMessage other) { + if (other == BatchMessage.getDefaultInstance()) return this; + if (other.hasHeader()) { + mergeHeader(other.getHeader()); + } + if (!other.getProducerGroup().isEmpty()) { + producerGroup_ = other.producerGroup_; + onChanged(); + } + if (!other.getTopic().isEmpty()) { + topic_ = other.topic_; + onChanged(); + } + if (messageItemBuilder_ == null) { + if (!other.messageItem_.isEmpty()) { + if (messageItem_.isEmpty()) { + messageItem_ = other.messageItem_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensureMessageItemIsMutable(); + messageItem_.addAll(other.messageItem_); + } + onChanged(); + } + } else { + if (!other.messageItem_.isEmpty()) { + if (messageItemBuilder_.isEmpty()) { + messageItemBuilder_.dispose(); + messageItemBuilder_ = null; + messageItem_ = other.messageItem_; + bitField0_ = (bitField0_ & ~0x00000008); + messageItemBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getMessageItemFieldBuilder() : null; + } else { + messageItemBuilder_.addAllMessages(other.messageItem_); + } + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + BatchMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (BatchMessage) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private RequestHeader header_ = null; + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> headerBuilder_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return headerBuilder_ != null || header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + if (headerBuilder_ == null) { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } else { + return headerBuilder_.getMessage(); + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + header_ = value; + onChanged(); + } else { + headerBuilder_.setMessage(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader( + RequestHeader.Builder builderForValue) { + if (headerBuilder_ == null) { + header_ = builderForValue.build(); + onChanged(); + } else { + headerBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder mergeHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (header_ != null) { + header_ = + RequestHeader.newBuilder(header_).mergeFrom(value).buildPartial(); + } else { + header_ = value; + } + onChanged(); + } else { + headerBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder clearHeader() { + if (headerBuilder_ == null) { + header_ = null; + onChanged(); + } else { + header_ = null; + headerBuilder_ = null; + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader.Builder getHeaderBuilder() { + + onChanged(); + return getHeaderFieldBuilder().getBuilder(); + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + if (headerBuilder_ != null) { + return headerBuilder_.getMessageOrBuilder(); + } else { + return header_ == null ? + RequestHeader.getDefaultInstance() : header_; + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> + getHeaderFieldBuilder() { + if (headerBuilder_ == null) { + headerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder>( + getHeader(), + getParentForChildren(), + isClean()); + header_ = null; + } + return headerBuilder_; + } + + private Object producerGroup_ = ""; + /** + * string producerGroup = 2; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string producerGroup = 2; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string producerGroup = 2; + */ + public Builder setProducerGroup( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + producerGroup_ = value; + onChanged(); + return this; + } + /** + * string producerGroup = 2; + */ + public Builder clearProducerGroup() { + + producerGroup_ = getDefaultInstance().getProducerGroup(); + onChanged(); + return this; + } + /** + * string producerGroup = 2; + */ + public Builder setProducerGroupBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + producerGroup_ = value; + onChanged(); + return this; + } + + private Object topic_ = ""; + /** + * string topic = 3; + */ + public String getTopic() { + Object ref = topic_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string topic = 3; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string topic = 3; + */ + public Builder setTopic( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + topic_ = value; + onChanged(); + return this; + } + /** + * string topic = 3; + */ + public Builder clearTopic() { + + topic_ = getDefaultInstance().getTopic(); + onChanged(); + return this; + } + /** + * string topic = 3; + */ + public Builder setTopicBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + topic_ = value; + onChanged(); + return this; + } + + private java.util.List messageItem_ = + java.util.Collections.emptyList(); + private void ensureMessageItemIsMutable() { + if (!((bitField0_ & 0x00000008) == 0x00000008)) { + messageItem_ = new java.util.ArrayList(messageItem_); + bitField0_ |= 0x00000008; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + MessageItem, MessageItem.Builder, MessageItemOrBuilder> messageItemBuilder_; + + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public java.util.List getMessageItemList() { + if (messageItemBuilder_ == null) { + return java.util.Collections.unmodifiableList(messageItem_); + } else { + return messageItemBuilder_.getMessageList(); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public int getMessageItemCount() { + if (messageItemBuilder_ == null) { + return messageItem_.size(); + } else { + return messageItemBuilder_.getCount(); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public MessageItem getMessageItem(int index) { + if (messageItemBuilder_ == null) { + return messageItem_.get(index); + } else { + return messageItemBuilder_.getMessage(index); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder setMessageItem( + int index, MessageItem value) { + if (messageItemBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMessageItemIsMutable(); + messageItem_.set(index, value); + onChanged(); + } else { + messageItemBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder setMessageItem( + int index, MessageItem.Builder builderForValue) { + if (messageItemBuilder_ == null) { + ensureMessageItemIsMutable(); + messageItem_.set(index, builderForValue.build()); + onChanged(); + } else { + messageItemBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder addMessageItem(MessageItem value) { + if (messageItemBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMessageItemIsMutable(); + messageItem_.add(value); + onChanged(); + } else { + messageItemBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder addMessageItem( + int index, MessageItem value) { + if (messageItemBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMessageItemIsMutable(); + messageItem_.add(index, value); + onChanged(); + } else { + messageItemBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder addMessageItem( + MessageItem.Builder builderForValue) { + if (messageItemBuilder_ == null) { + ensureMessageItemIsMutable(); + messageItem_.add(builderForValue.build()); + onChanged(); + } else { + messageItemBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder addMessageItem( + int index, MessageItem.Builder builderForValue) { + if (messageItemBuilder_ == null) { + ensureMessageItemIsMutable(); + messageItem_.add(index, builderForValue.build()); + onChanged(); + } else { + messageItemBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder addAllMessageItem( + Iterable values) { + if (messageItemBuilder_ == null) { + ensureMessageItemIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, messageItem_); + onChanged(); + } else { + messageItemBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder clearMessageItem() { + if (messageItemBuilder_ == null) { + messageItem_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + } else { + messageItemBuilder_.clear(); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public Builder removeMessageItem(int index) { + if (messageItemBuilder_ == null) { + ensureMessageItemIsMutable(); + messageItem_.remove(index); + onChanged(); + } else { + messageItemBuilder_.remove(index); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public MessageItem.Builder getMessageItemBuilder( + int index) { + return getMessageItemFieldBuilder().getBuilder(index); + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public MessageItemOrBuilder getMessageItemOrBuilder( + int index) { + if (messageItemBuilder_ == null) { + return messageItem_.get(index); } else { + return messageItemBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public java.util.List + getMessageItemOrBuilderList() { + if (messageItemBuilder_ != null) { + return messageItemBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(messageItem_); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public MessageItem.Builder addMessageItemBuilder() { + return getMessageItemFieldBuilder().addBuilder( + MessageItem.getDefaultInstance()); + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public MessageItem.Builder addMessageItemBuilder( + int index) { + return getMessageItemFieldBuilder().addBuilder( + index, MessageItem.getDefaultInstance()); + } + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + public java.util.List + getMessageItemBuilderList() { + return getMessageItemFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + MessageItem, MessageItem.Builder, MessageItemOrBuilder> + getMessageItemFieldBuilder() { + if (messageItemBuilder_ == null) { + messageItemBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + MessageItem, MessageItem.Builder, MessageItemOrBuilder>( + messageItem_, + ((bitField0_ & 0x00000008) == 0x00000008), + getParentForChildren(), + isClean()); + messageItem_ = null; + } + return messageItemBuilder_; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.BatchMessage) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.BatchMessage) + private static final BatchMessage DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new BatchMessage(); + } + + public static BatchMessage getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public BatchMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new BatchMessage(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public BatchMessage getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessageOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessageOrBuilder.java new file mode 100644 index 0000000000..7f46dd24e9 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessageOrBuilder.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +@SuppressWarnings({"all"}) +public interface BatchMessageOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.BatchMessage) + com.google.protobuf.MessageOrBuilder { + + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + boolean hasHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeader getHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeaderOrBuilder getHeaderOrBuilder(); + + /** + * string producerGroup = 2; + */ + String getProducerGroup(); + /** + * string producerGroup = 2; + */ + com.google.protobuf.ByteString + getProducerGroupBytes(); + + /** + * string topic = 3; + */ + String getTopic(); + /** + * string topic = 3; + */ + com.google.protobuf.ByteString + getTopicBytes(); + + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + java.util.List + getMessageItemList(); + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + BatchMessage.MessageItem getMessageItem(int index); + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + int getMessageItemCount(); + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + java.util.List + getMessageItemOrBuilderList(); + /** + * repeated .eventmesh.common.protocol.grpc.BatchMessage.MessageItem messageItem = 4; + */ + BatchMessage.MessageItemOrBuilder getMessageItemOrBuilder( + int index); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ConsumerServiceGrpc.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ConsumerServiceGrpc.java new file mode 100644 index 0000000000..fbf4608c90 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ConsumerServiceGrpc.java @@ -0,0 +1,445 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.grpc.protos; + +import static io.grpc.MethodDescriptor.generateFullMethodName; +import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; +import static io.grpc.stub.ClientCalls.asyncUnaryCall; +import static io.grpc.stub.ClientCalls.blockingUnaryCall; +import static io.grpc.stub.ClientCalls.futureUnaryCall; +import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +/** + */ +@SuppressWarnings({"all"}) +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.17.1)", + comments = "Source: eventmesh-client.proto") +public final class ConsumerServiceGrpc { + + private ConsumerServiceGrpc() {} + + public static final String SERVICE_NAME = "eventmesh.common.protocol.grpc.ConsumerService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getSubscribeMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "subscribe", + requestType = Subscription.class, + responseType = Response.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSubscribeMethod() { + io.grpc.MethodDescriptor getSubscribeMethod; + if ((getSubscribeMethod = ConsumerServiceGrpc.getSubscribeMethod) == null) { + synchronized (ConsumerServiceGrpc.class) { + if ((getSubscribeMethod = ConsumerServiceGrpc.getSubscribeMethod) == null) { + ConsumerServiceGrpc.getSubscribeMethod = getSubscribeMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "eventmesh.common.protocol.grpc.ConsumerService", "subscribe")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Subscription.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Response.getDefaultInstance())) + .setSchemaDescriptor(new ConsumerServiceMethodDescriptorSupplier("subscribe")) + .build(); + } + } + } + return getSubscribeMethod; + } + + private static volatile io.grpc.MethodDescriptor getSubscribeStreamMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "subscribeStream", + requestType = Subscription.class, + responseType = SimpleMessage.class, + methodType = io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) + public static io.grpc.MethodDescriptor getSubscribeStreamMethod() { + io.grpc.MethodDescriptor getSubscribeStreamMethod; + if ((getSubscribeStreamMethod = ConsumerServiceGrpc.getSubscribeStreamMethod) == null) { + synchronized (ConsumerServiceGrpc.class) { + if ((getSubscribeStreamMethod = ConsumerServiceGrpc.getSubscribeStreamMethod) == null) { + ConsumerServiceGrpc.getSubscribeStreamMethod = getSubscribeStreamMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) + .setFullMethodName(generateFullMethodName( + "eventmesh.common.protocol.grpc.ConsumerService", "subscribeStream")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Subscription.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + SimpleMessage.getDefaultInstance())) + .setSchemaDescriptor(new ConsumerServiceMethodDescriptorSupplier("subscribeStream")) + .build(); + } + } + } + return getSubscribeStreamMethod; + } + + private static volatile io.grpc.MethodDescriptor getUnsubscribeMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "unsubscribe", + requestType = Subscription.class, + responseType = Response.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getUnsubscribeMethod() { + io.grpc.MethodDescriptor getUnsubscribeMethod; + if ((getUnsubscribeMethod = ConsumerServiceGrpc.getUnsubscribeMethod) == null) { + synchronized (ConsumerServiceGrpc.class) { + if ((getUnsubscribeMethod = ConsumerServiceGrpc.getUnsubscribeMethod) == null) { + ConsumerServiceGrpc.getUnsubscribeMethod = getUnsubscribeMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "eventmesh.common.protocol.grpc.ConsumerService", "unsubscribe")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Subscription.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Response.getDefaultInstance())) + .setSchemaDescriptor(new ConsumerServiceMethodDescriptorSupplier("unsubscribe")) + .build(); + } + } + } + return getUnsubscribeMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static ConsumerServiceStub newStub(io.grpc.Channel channel) { + return new ConsumerServiceStub(channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static ConsumerServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new ConsumerServiceBlockingStub(channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static ConsumerServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + return new ConsumerServiceFutureStub(channel); + } + + /** + */ + public static abstract class ConsumerServiceImplBase implements io.grpc.BindableService { + + /** + *
+     * The subscribed event will be delivered by invoking the webhook url in the Subscription
+     * 
+ */ + public void subscribe(Subscription request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getSubscribeMethod(), responseObserver); + } + + /** + *
+     *  The subscribed event will be delivered through stream of Message
+     * 
+ */ + public io.grpc.stub.StreamObserver subscribeStream( + io.grpc.stub.StreamObserver responseObserver) { + return asyncUnimplementedStreamingCall(getSubscribeStreamMethod(), responseObserver); + } + + /** + */ + public void unsubscribe(Subscription request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getUnsubscribeMethod(), responseObserver); + } + + @Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getSubscribeMethod(), + asyncUnaryCall( + new MethodHandlers< + Subscription, + Response>( + this, METHODID_SUBSCRIBE))) + .addMethod( + getSubscribeStreamMethod(), + asyncBidiStreamingCall( + new MethodHandlers< + Subscription, + SimpleMessage>( + this, METHODID_SUBSCRIBE_STREAM))) + .addMethod( + getUnsubscribeMethod(), + asyncUnaryCall( + new MethodHandlers< + Subscription, + Response>( + this, METHODID_UNSUBSCRIBE))) + .build(); + } + } + + /** + */ + public static final class ConsumerServiceStub extends io.grpc.stub.AbstractStub { + private ConsumerServiceStub(io.grpc.Channel channel) { + super(channel); + } + + private ConsumerServiceStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected ConsumerServiceStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new ConsumerServiceStub(channel, callOptions); + } + + /** + *
+     * The subscribed event will be delivered by invoking the webhook url in the Subscription
+     * 
+ */ + public void subscribe(Subscription request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getSubscribeMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     *  The subscribed event will be delivered through stream of Message
+     * 
+ */ + public io.grpc.stub.StreamObserver subscribeStream( + io.grpc.stub.StreamObserver responseObserver) { + return asyncBidiStreamingCall( + getChannel().newCall(getSubscribeStreamMethod(), getCallOptions()), responseObserver); + } + + /** + */ + public void unsubscribe(Subscription request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getUnsubscribeMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class ConsumerServiceBlockingStub extends io.grpc.stub.AbstractStub { + private ConsumerServiceBlockingStub(io.grpc.Channel channel) { + super(channel); + } + + private ConsumerServiceBlockingStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected ConsumerServiceBlockingStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new ConsumerServiceBlockingStub(channel, callOptions); + } + + /** + *
+     * The subscribed event will be delivered by invoking the webhook url in the Subscription
+     * 
+ */ + public Response subscribe(Subscription request) { + return blockingUnaryCall( + getChannel(), getSubscribeMethod(), getCallOptions(), request); + } + + /** + */ + public Response unsubscribe(Subscription request) { + return blockingUnaryCall( + getChannel(), getUnsubscribeMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class ConsumerServiceFutureStub extends io.grpc.stub.AbstractStub { + private ConsumerServiceFutureStub(io.grpc.Channel channel) { + super(channel); + } + + private ConsumerServiceFutureStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected ConsumerServiceFutureStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new ConsumerServiceFutureStub(channel, callOptions); + } + + /** + *
+     * The subscribed event will be delivered by invoking the webhook url in the Subscription
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture subscribe( + Subscription request) { + return futureUnaryCall( + getChannel().newCall(getSubscribeMethod(), getCallOptions()), request); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture unsubscribe( + Subscription request) { + return futureUnaryCall( + getChannel().newCall(getUnsubscribeMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_SUBSCRIBE = 0; + private static final int METHODID_UNSUBSCRIBE = 1; + private static final int METHODID_SUBSCRIBE_STREAM = 2; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final ConsumerServiceImplBase serviceImpl; + private final int methodId; + + MethodHandlers(ConsumerServiceImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @Override + @SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_SUBSCRIBE: + serviceImpl.subscribe((Subscription) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_UNSUBSCRIBE: + serviceImpl.unsubscribe((Subscription) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @Override + @SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_SUBSCRIBE_STREAM: + return (io.grpc.stub.StreamObserver) serviceImpl.subscribeStream( + (io.grpc.stub.StreamObserver) responseObserver); + default: + throw new AssertionError(); + } + } + } + + private static abstract class ConsumerServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { + ConsumerServiceBaseDescriptorSupplier() {} + + @Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return EventmeshGrpc.getDescriptor(); + } + + @Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("ConsumerService"); + } + } + + private static final class ConsumerServiceFileDescriptorSupplier + extends ConsumerServiceBaseDescriptorSupplier { + ConsumerServiceFileDescriptorSupplier() {} + } + + private static final class ConsumerServiceMethodDescriptorSupplier + extends ConsumerServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final String methodName; + + ConsumerServiceMethodDescriptorSupplier(String methodName) { + this.methodName = methodName; + } + + @Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (ConsumerServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new ConsumerServiceFileDescriptorSupplier()) + .addMethod(getSubscribeMethod()) + .addMethod(getSubscribeStreamMethod()) + .addMethod(getUnsubscribeMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/EventmeshGrpc.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/EventmeshGrpc.java new file mode 100644 index 0000000000..4a1f2de63f --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/EventmeshGrpc.java @@ -0,0 +1,283 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +@SuppressWarnings({"all"}) +public final class EventmeshGrpc { + private EventmeshGrpc() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_RequestHeader_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_RequestHeader_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_PropertiesEntry_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_PropertiesEntry_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_BatchMessage_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_BatchMessage_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_PropertiesEntry_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_PropertiesEntry_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_Response_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_Response_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_Subscription_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_PropertiesEntry_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_PropertiesEntry_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_Heartbeat_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_Heartbeat_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + String[] descriptorData = { + "\n\026eventmesh-client.proto\022\036eventmesh.comm" + + "on.protocol.grpc\"\332\001\n\rRequestHeader\022\013\n\003en" + + "v\030\001 \001(\t\022\016\n\006region\030\002 \001(\t\022\013\n\003idc\030\003 \001(\t\022\n\n\002" + + "ip\030\004 \001(\t\022\013\n\003pid\030\005 \001(\t\022\013\n\003sys\030\006 \001(\t\022\020\n\010us" + + "ername\030\007 \001(\t\022\020\n\010password\030\010 \001(\t\022\020\n\010langua" + + "ge\030\t \001(\t\022\024\n\014protocolType\030\n \001(\t\022\027\n\017protoc" + + "olVersion\030\013 \001(\t\022\024\n\014protocolDesc\030\014 \001(\t\"\307\002" + + "\n\rSimpleMessage\022=\n\006header\030\001 \001(\0132-.eventm" + + "esh.common.protocol.grpc.RequestHeader\022\025" + + "\n\rproducerGroup\030\002 \001(\t\022\r\n\005topic\030\003 \001(\t\022\017\n\007" + + "content\030\004 \001(\t\022\013\n\003ttl\030\005 \001(\t\022\020\n\010uniqueId\030\006" + + " \001(\t\022\016\n\006seqNum\030\007 \001(\t\022\013\n\003tag\030\010 \001(\t\022Q\n\npro" + + "perties\030\t \003(\0132=.eventmesh.common.protoco" + + "l.grpc.SimpleMessage.PropertiesEntry\0321\n\017" + + "PropertiesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 " + + "\001(\t:\0028\001\"\260\003\n\014BatchMessage\022=\n\006header\030\001 \001(\013" + + "2-.eventmesh.common.protocol.grpc.Reques" + + "tHeader\022\025\n\rproducerGroup\030\002 \001(\t\022\r\n\005topic\030" + + "\003 \001(\t\022M\n\013messageItem\030\004 \003(\01328.eventmesh.c" + + "ommon.protocol.grpc.BatchMessage.Message" + + "Item\032\353\001\n\013MessageItem\022\017\n\007content\030\001 \001(\t\022\013\n" + + "\003ttl\030\002 \001(\t\022\020\n\010uniqueId\030\003 \001(\t\022\016\n\006seqNum\030\004" + + " \001(\t\022\013\n\003tag\030\005 \001(\t\022\\\n\nproperties\030\006 \003(\0132H." + + "eventmesh.common.protocol.grpc.BatchMess" + + "age.MessageItem.PropertiesEntry\0321\n\017Prope" + + "rtiesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\002" + + "8\001\"?\n\010Response\022\020\n\010respCode\030\001 \001(\t\022\017\n\007resp" + + "Msg\030\002 \001(\t\022\020\n\010respTime\030\003 \001(\t\"\325\006\n\014Subscrip" + + "tion\022=\n\006header\030\001 \001(\0132-.eventmesh.common." + + "protocol.grpc.RequestHeader\022\025\n\rconsumerG" + + "roup\030\002 \001(\t\022X\n\021subscriptionItems\030\003 \003(\0132=." + + "eventmesh.common.protocol.grpc.Subscript" + + "ion.SubscriptionItem\022\013\n\003url\030\004 \001(\t\022A\n\005rep" + + "ly\030\005 \001(\01322.eventmesh.common.protocol.grp" + + "c.Subscription.Reply\032\274\002\n\020SubscriptionIte" + + "m\022\r\n\005topic\030\001 \001(\t\022\\\n\004mode\030\002 \001(\0162N.eventme" + + "sh.common.protocol.grpc.Subscription.Sub" + + "scriptionItem.SubscriptionMode\022\\\n\004type\030\003" + + " \001(\0162N.eventmesh.common.protocol.grpc.Su" + + "bscription.SubscriptionItem.Subscription" + + "Type\"4\n\020SubscriptionMode\022\016\n\nCLUSTERING\020\000" + + "\022\020\n\014BROADCASTING\020\001\"\'\n\020SubscriptionType\022\t" + + "\n\005ASYNC\020\000\022\010\n\004SYNC\020\001\032\205\002\n\005Reply\022\025\n\rproduce" + + "rGroup\030\001 \001(\t\022\r\n\005topic\030\002 \001(\t\022\017\n\007content\030\003" + + " \001(\t\022\013\n\003ttl\030\004 \001(\t\022\020\n\010uniqueId\030\005 \001(\t\022\016\n\006s" + + "eqNum\030\006 \001(\t\022\013\n\003tag\030\007 \001(\t\022V\n\nproperties\030\010" + + " \003(\0132B.eventmesh.common.protocol.grpc.Su" + + "bscription.Reply.PropertiesEntry\0321\n\017Prop" + + "ertiesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:" + + "\0028\001\"\340\002\n\tHeartbeat\022=\n\006header\030\001 \001(\0132-.even" + + "tmesh.common.protocol.grpc.RequestHeader" + + "\022H\n\nclientType\030\002 \001(\01624.eventmesh.common." + + "protocol.grpc.Heartbeat.ClientType\022\025\n\rpr" + + "oducerGroup\030\003 \001(\t\022\025\n\rconsumerGroup\030\004 \001(\t" + + "\022O\n\016heartbeatItems\030\005 \003(\01327.eventmesh.com" + + "mon.protocol.grpc.Heartbeat.HeartbeatIte" + + "m\032+\n\rHeartbeatItem\022\r\n\005topic\030\001 \001(\t\022\013\n\003url" + + "\030\002 \001(\t\"\036\n\nClientType\022\007\n\003PUB\020\000\022\007\n\003SUB\020\0012\314" + + "\002\n\020PublisherService\022b\n\007publish\022-.eventme" + + "sh.common.protocol.grpc.SimpleMessage\032(." + + "eventmesh.common.protocol.grpc.Response\022" + + "l\n\014requestReply\022-.eventmesh.common.proto" + + "col.grpc.SimpleMessage\032-.eventmesh.commo" + + "n.protocol.grpc.SimpleMessage\022f\n\014batchPu" + + "blish\022,.eventmesh.common.protocol.grpc.B" + + "atchMessage\032(.eventmesh.common.protocol." + + "grpc.Response2\321\002\n\017ConsumerService\022c\n\tsub" + + "scribe\022,.eventmesh.common.protocol.grpc." + + "Subscription\032(.eventmesh.common.protocol" + + ".grpc.Response\022r\n\017subscribeStream\022,.even" + + "tmesh.common.protocol.grpc.Subscription\032" + + "-.eventmesh.common.protocol.grpc.SimpleM" + + "essage(\0010\001\022e\n\013unsubscribe\022,.eventmesh.co" + + "mmon.protocol.grpc.Subscription\032(.eventm" + + "esh.common.protocol.grpc.Response2t\n\020Hea" + + "rtbeatService\022`\n\theartbeat\022).eventmesh.c" + + "ommon.protocol.grpc.Heartbeat\032(.eventmes" + + "h.common.protocol.grpc.ResponseBC\n0org.a" + + "pache.eventmesh.common.protocol.grpc.pro" + + "tosB\rEventmeshGrpcP\001b\006proto3" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + internal_static_eventmesh_common_protocol_grpc_RequestHeader_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_eventmesh_common_protocol_grpc_RequestHeader_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_RequestHeader_descriptor, + new String[] { "Env", "Region", "Idc", "Ip", "Pid", "Sys", "Username", "Password", "Language", "ProtocolType", "ProtocolVersion", "ProtocolDesc", }); + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_descriptor, + new String[] { "Header", "ProducerGroup", "Topic", "Content", "Ttl", "UniqueId", "SeqNum", "Tag", "Properties", }); + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_PropertiesEntry_descriptor = + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_descriptor.getNestedTypes().get(0); + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_PropertiesEntry_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_SimpleMessage_PropertiesEntry_descriptor, + new String[] { "Key", "Value", }); + internal_static_eventmesh_common_protocol_grpc_BatchMessage_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_eventmesh_common_protocol_grpc_BatchMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_BatchMessage_descriptor, + new String[] { "Header", "ProducerGroup", "Topic", "MessageItem", }); + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_descriptor = + internal_static_eventmesh_common_protocol_grpc_BatchMessage_descriptor.getNestedTypes().get(0); + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_descriptor, + new String[] { "Content", "Ttl", "UniqueId", "SeqNum", "Tag", "Properties", }); + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_PropertiesEntry_descriptor = + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_descriptor.getNestedTypes().get(0); + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_PropertiesEntry_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_BatchMessage_MessageItem_PropertiesEntry_descriptor, + new String[] { "Key", "Value", }); + internal_static_eventmesh_common_protocol_grpc_Response_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_eventmesh_common_protocol_grpc_Response_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_Response_descriptor, + new String[] { "RespCode", "RespMsg", "RespTime", }); + internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_eventmesh_common_protocol_grpc_Subscription_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor, + new String[] { "Header", "ConsumerGroup", "SubscriptionItems", "Url", "Reply", }); + internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_descriptor = + internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor.getNestedTypes().get(0); + internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_descriptor, + new String[] { "Topic", "Mode", "Type", }); + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_descriptor = + internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor.getNestedTypes().get(1); + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_descriptor, + new String[] { "ProducerGroup", "Topic", "Content", "Ttl", "UniqueId", "SeqNum", "Tag", "Properties", }); + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_PropertiesEntry_descriptor = + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_descriptor.getNestedTypes().get(0); + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_PropertiesEntry_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_PropertiesEntry_descriptor, + new String[] { "Key", "Value", }); + internal_static_eventmesh_common_protocol_grpc_Heartbeat_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_eventmesh_common_protocol_grpc_Heartbeat_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_Heartbeat_descriptor, + new String[] { "Header", "ClientType", "ProducerGroup", "ConsumerGroup", "HeartbeatItems", }); + internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_descriptor = + internal_static_eventmesh_common_protocol_grpc_Heartbeat_descriptor.getNestedTypes().get(0); + internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_descriptor, + new String[] { "Topic", "Url", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Heartbeat.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Heartbeat.java new file mode 100644 index 0000000000..bbab602dba --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Heartbeat.java @@ -0,0 +1,2033 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +/** + * Protobuf type {@code eventmesh.common.protocol.grpc.Heartbeat} + */ +@SuppressWarnings({"all"}) +public final class Heartbeat extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.Heartbeat) + HeartbeatOrBuilder { +private static final long serialVersionUID = 0L; + // Use Heartbeat.newBuilder() to construct. + private Heartbeat(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Heartbeat() { + clientType_ = 0; + producerGroup_ = ""; + consumerGroup_ = ""; + heartbeatItems_ = java.util.Collections.emptyList(); + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Heartbeat( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + RequestHeader.Builder subBuilder = null; + if (header_ != null) { + subBuilder = header_.toBuilder(); + } + header_ = input.readMessage(RequestHeader.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(header_); + header_ = subBuilder.buildPartial(); + } + + break; + } + case 16: { + int rawValue = input.readEnum(); + + clientType_ = rawValue; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + producerGroup_ = s; + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + consumerGroup_ = s; + break; + } + case 42: { + if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + heartbeatItems_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000010; + } + heartbeatItems_.add( + input.readMessage(HeartbeatItem.parser(), extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + heartbeatItems_ = java.util.Collections.unmodifiableList(heartbeatItems_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Heartbeat.class, Builder.class); + } + + /** + * Protobuf enum {@code eventmesh.common.protocol.grpc.Heartbeat.ClientType} + */ + public enum ClientType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * PUB = 0; + */ + PUB(0), + /** + * SUB = 1; + */ + SUB(1), + UNRECOGNIZED(-1), + ; + + /** + * PUB = 0; + */ + public static final int PUB_VALUE = 0; + /** + * SUB = 1; + */ + public static final int SUB_VALUE = 1; + + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @deprecated Use {@link #forNumber(int)} instead. + */ + @Deprecated + public static ClientType valueOf(int value) { + return forNumber(value); + } + + public static ClientType forNumber(int value) { + switch (value) { + case 0: return PUB; + case 1: return SUB; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + ClientType> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ClientType findValueByNumber(int number) { + return ClientType.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return Heartbeat.getDescriptor().getEnumTypes().get(0); + } + + private static final ClientType[] VALUES = values(); + + public static ClientType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private ClientType(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:eventmesh.common.protocol.grpc.Heartbeat.ClientType) + } + + public interface HeartbeatItemOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem) + com.google.protobuf.MessageOrBuilder { + + /** + * string topic = 1; + */ + String getTopic(); + /** + * string topic = 1; + */ + com.google.protobuf.ByteString + getTopicBytes(); + + /** + * string url = 2; + */ + String getUrl(); + /** + * string url = 2; + */ + com.google.protobuf.ByteString + getUrlBytes(); + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem} + */ + public static final class HeartbeatItem extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem) + HeartbeatItemOrBuilder { + private static final long serialVersionUID = 0L; + // Use HeartbeatItem.newBuilder() to construct. + private HeartbeatItem(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private HeartbeatItem() { + topic_ = ""; + url_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private HeartbeatItem( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + String s = input.readStringRequireUtf8(); + + topic_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + url_ = s; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_fieldAccessorTable + .ensureFieldAccessorsInitialized( + HeartbeatItem.class, Builder.class); + } + + public static final int TOPIC_FIELD_NUMBER = 1; + private volatile Object topic_; + /** + * string topic = 1; + */ + public String getTopic() { + Object ref = topic_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } + } + /** + * string topic = 1; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int URL_FIELD_NUMBER = 2; + private volatile Object url_; + /** + * string url = 2; + */ + public String getUrl() { + Object ref = url_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + url_ = s; + return s; + } + } + /** + * string url = 2; + */ + public com.google.protobuf.ByteString + getUrlBytes() { + Object ref = url_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getTopicBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, topic_); + } + if (!getUrlBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, url_); + } + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getTopicBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, topic_); + } + if (!getUrlBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, url_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof HeartbeatItem)) { + return super.equals(obj); + } + HeartbeatItem other = (HeartbeatItem) obj; + + boolean result = true; + result = result && getTopic() + .equals(other.getTopic()); + result = result && getUrl() + .equals(other.getUrl()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + TOPIC_FIELD_NUMBER; + hash = (53 * hash) + getTopic().hashCode(); + hash = (37 * hash) + URL_FIELD_NUMBER; + hash = (53 * hash) + getUrl().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static HeartbeatItem parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static HeartbeatItem parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static HeartbeatItem parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static HeartbeatItem parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static HeartbeatItem parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static HeartbeatItem parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static HeartbeatItem parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static HeartbeatItem parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static HeartbeatItem parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static HeartbeatItem parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static HeartbeatItem parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static HeartbeatItem parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(HeartbeatItem prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem) + HeartbeatItemOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_fieldAccessorTable + .ensureFieldAccessorsInitialized( + HeartbeatItem.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat.HeartbeatItem.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + topic_ = ""; + + url_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_HeartbeatItem_descriptor; + } + + public HeartbeatItem getDefaultInstanceForType() { + return HeartbeatItem.getDefaultInstance(); + } + + public HeartbeatItem build() { + HeartbeatItem result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public HeartbeatItem buildPartial() { + HeartbeatItem result = new HeartbeatItem(this); + result.topic_ = topic_; + result.url_ = url_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof HeartbeatItem) { + return mergeFrom((HeartbeatItem)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(HeartbeatItem other) { + if (other == HeartbeatItem.getDefaultInstance()) return this; + if (!other.getTopic().isEmpty()) { + topic_ = other.topic_; + onChanged(); + } + if (!other.getUrl().isEmpty()) { + url_ = other.url_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + HeartbeatItem parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (HeartbeatItem) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private Object topic_ = ""; + /** + * string topic = 1; + */ + public String getTopic() { + Object ref = topic_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string topic = 1; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string topic = 1; + */ + public Builder setTopic( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + topic_ = value; + onChanged(); + return this; + } + /** + * string topic = 1; + */ + public Builder clearTopic() { + + topic_ = getDefaultInstance().getTopic(); + onChanged(); + return this; + } + /** + * string topic = 1; + */ + public Builder setTopicBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + topic_ = value; + onChanged(); + return this; + } + + private Object url_ = ""; + /** + * string url = 2; + */ + public String getUrl() { + Object ref = url_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + url_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string url = 2; + */ + public com.google.protobuf.ByteString + getUrlBytes() { + Object ref = url_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string url = 2; + */ + public Builder setUrl( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + url_ = value; + onChanged(); + return this; + } + /** + * string url = 2; + */ + public Builder clearUrl() { + + url_ = getDefaultInstance().getUrl(); + onChanged(); + return this; + } + /** + * string url = 2; + */ + public Builder setUrlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + url_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem) + private static final HeartbeatItem DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new HeartbeatItem(); + } + + public static HeartbeatItem getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public HeartbeatItem parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new HeartbeatItem(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public HeartbeatItem getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private int bitField0_; + public static final int HEADER_FIELD_NUMBER = 1; + private RequestHeader header_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + return getHeader(); + } + + public static final int CLIENTTYPE_FIELD_NUMBER = 2; + private int clientType_; + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + public int getClientTypeValue() { + return clientType_; + } + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + public ClientType getClientType() { + ClientType result = ClientType.valueOf(clientType_); + return result == null ? ClientType.UNRECOGNIZED : result; + } + + public static final int PRODUCERGROUP_FIELD_NUMBER = 3; + private volatile Object producerGroup_; + /** + * string producerGroup = 3; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } + } + /** + * string producerGroup = 3; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CONSUMERGROUP_FIELD_NUMBER = 4; + private volatile Object consumerGroup_; + /** + * string consumerGroup = 4; + */ + public String getConsumerGroup() { + Object ref = consumerGroup_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + consumerGroup_ = s; + return s; + } + } + /** + * string consumerGroup = 4; + */ + public com.google.protobuf.ByteString + getConsumerGroupBytes() { + Object ref = consumerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + consumerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int HEARTBEATITEMS_FIELD_NUMBER = 5; + private java.util.List heartbeatItems_; + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public java.util.List getHeartbeatItemsList() { + return heartbeatItems_; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public java.util.List + getHeartbeatItemsOrBuilderList() { + return heartbeatItems_; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public int getHeartbeatItemsCount() { + return heartbeatItems_.size(); + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public HeartbeatItem getHeartbeatItems(int index) { + return heartbeatItems_.get(index); + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public HeartbeatItemOrBuilder getHeartbeatItemsOrBuilder( + int index) { + return heartbeatItems_.get(index); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (header_ != null) { + output.writeMessage(1, getHeader()); + } + if (clientType_ != ClientType.PUB.getNumber()) { + output.writeEnum(2, clientType_); + } + if (!getProducerGroupBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, producerGroup_); + } + if (!getConsumerGroupBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, consumerGroup_); + } + for (int i = 0; i < heartbeatItems_.size(); i++) { + output.writeMessage(5, heartbeatItems_.get(i)); + } + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (header_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getHeader()); + } + if (clientType_ != ClientType.PUB.getNumber()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, clientType_); + } + if (!getProducerGroupBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, producerGroup_); + } + if (!getConsumerGroupBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, consumerGroup_); + } + for (int i = 0; i < heartbeatItems_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, heartbeatItems_.get(i)); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Heartbeat)) { + return super.equals(obj); + } + Heartbeat other = (Heartbeat) obj; + + boolean result = true; + result = result && (hasHeader() == other.hasHeader()); + if (hasHeader()) { + result = result && getHeader() + .equals(other.getHeader()); + } + result = result && clientType_ == other.clientType_; + result = result && getProducerGroup() + .equals(other.getProducerGroup()); + result = result && getConsumerGroup() + .equals(other.getConsumerGroup()); + result = result && getHeartbeatItemsList() + .equals(other.getHeartbeatItemsList()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasHeader()) { + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + } + hash = (37 * hash) + CLIENTTYPE_FIELD_NUMBER; + hash = (53 * hash) + clientType_; + hash = (37 * hash) + PRODUCERGROUP_FIELD_NUMBER; + hash = (53 * hash) + getProducerGroup().hashCode(); + hash = (37 * hash) + CONSUMERGROUP_FIELD_NUMBER; + hash = (53 * hash) + getConsumerGroup().hashCode(); + if (getHeartbeatItemsCount() > 0) { + hash = (37 * hash) + HEARTBEATITEMS_FIELD_NUMBER; + hash = (53 * hash) + getHeartbeatItemsList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static Heartbeat parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Heartbeat parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Heartbeat parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Heartbeat parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Heartbeat parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Heartbeat parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Heartbeat parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Heartbeat parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static Heartbeat parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static Heartbeat parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static Heartbeat parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Heartbeat parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(Heartbeat prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Heartbeat} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.Heartbeat) + HeartbeatOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Heartbeat.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getHeartbeatItemsFieldBuilder(); + } + } + public Builder clear() { + super.clear(); + if (headerBuilder_ == null) { + header_ = null; + } else { + header_ = null; + headerBuilder_ = null; + } + clientType_ = 0; + + producerGroup_ = ""; + + consumerGroup_ = ""; + + if (heartbeatItemsBuilder_ == null) { + heartbeatItems_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); + } else { + heartbeatItemsBuilder_.clear(); + } + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Heartbeat_descriptor; + } + + public Heartbeat getDefaultInstanceForType() { + return Heartbeat.getDefaultInstance(); + } + + public Heartbeat build() { + Heartbeat result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public Heartbeat buildPartial() { + Heartbeat result = new Heartbeat(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (headerBuilder_ == null) { + result.header_ = header_; + } else { + result.header_ = headerBuilder_.build(); + } + result.clientType_ = clientType_; + result.producerGroup_ = producerGroup_; + result.consumerGroup_ = consumerGroup_; + if (heartbeatItemsBuilder_ == null) { + if (((bitField0_ & 0x00000010) == 0x00000010)) { + heartbeatItems_ = java.util.Collections.unmodifiableList(heartbeatItems_); + bitField0_ = (bitField0_ & ~0x00000010); + } + result.heartbeatItems_ = heartbeatItems_; + } else { + result.heartbeatItems_ = heartbeatItemsBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof Heartbeat) { + return mergeFrom((Heartbeat)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(Heartbeat other) { + if (other == Heartbeat.getDefaultInstance()) return this; + if (other.hasHeader()) { + mergeHeader(other.getHeader()); + } + if (other.clientType_ != 0) { + setClientTypeValue(other.getClientTypeValue()); + } + if (!other.getProducerGroup().isEmpty()) { + producerGroup_ = other.producerGroup_; + onChanged(); + } + if (!other.getConsumerGroup().isEmpty()) { + consumerGroup_ = other.consumerGroup_; + onChanged(); + } + if (heartbeatItemsBuilder_ == null) { + if (!other.heartbeatItems_.isEmpty()) { + if (heartbeatItems_.isEmpty()) { + heartbeatItems_ = other.heartbeatItems_; + bitField0_ = (bitField0_ & ~0x00000010); + } else { + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.addAll(other.heartbeatItems_); + } + onChanged(); + } + } else { + if (!other.heartbeatItems_.isEmpty()) { + if (heartbeatItemsBuilder_.isEmpty()) { + heartbeatItemsBuilder_.dispose(); + heartbeatItemsBuilder_ = null; + heartbeatItems_ = other.heartbeatItems_; + bitField0_ = (bitField0_ & ~0x00000010); + heartbeatItemsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getHeartbeatItemsFieldBuilder() : null; + } else { + heartbeatItemsBuilder_.addAllMessages(other.heartbeatItems_); + } + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Heartbeat parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (Heartbeat) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private RequestHeader header_ = null; + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> headerBuilder_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return headerBuilder_ != null || header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + if (headerBuilder_ == null) { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } else { + return headerBuilder_.getMessage(); + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + header_ = value; + onChanged(); + } else { + headerBuilder_.setMessage(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader( + RequestHeader.Builder builderForValue) { + if (headerBuilder_ == null) { + header_ = builderForValue.build(); + onChanged(); + } else { + headerBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder mergeHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (header_ != null) { + header_ = + RequestHeader.newBuilder(header_).mergeFrom(value).buildPartial(); + } else { + header_ = value; + } + onChanged(); + } else { + headerBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder clearHeader() { + if (headerBuilder_ == null) { + header_ = null; + onChanged(); + } else { + header_ = null; + headerBuilder_ = null; + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader.Builder getHeaderBuilder() { + + onChanged(); + return getHeaderFieldBuilder().getBuilder(); + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + if (headerBuilder_ != null) { + return headerBuilder_.getMessageOrBuilder(); + } else { + return header_ == null ? + RequestHeader.getDefaultInstance() : header_; + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> + getHeaderFieldBuilder() { + if (headerBuilder_ == null) { + headerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder>( + getHeader(), + getParentForChildren(), + isClean()); + header_ = null; + } + return headerBuilder_; + } + + private int clientType_ = 0; + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + public int getClientTypeValue() { + return clientType_; + } + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + public Builder setClientTypeValue(int value) { + clientType_ = value; + onChanged(); + return this; + } + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + public ClientType getClientType() { + ClientType result = ClientType.valueOf(clientType_); + return result == null ? ClientType.UNRECOGNIZED : result; + } + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + public Builder setClientType(ClientType value) { + if (value == null) { + throw new NullPointerException(); + } + + clientType_ = value.getNumber(); + onChanged(); + return this; + } + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + public Builder clearClientType() { + + clientType_ = 0; + onChanged(); + return this; + } + + private Object producerGroup_ = ""; + /** + * string producerGroup = 3; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string producerGroup = 3; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string producerGroup = 3; + */ + public Builder setProducerGroup( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + producerGroup_ = value; + onChanged(); + return this; + } + /** + * string producerGroup = 3; + */ + public Builder clearProducerGroup() { + + producerGroup_ = getDefaultInstance().getProducerGroup(); + onChanged(); + return this; + } + /** + * string producerGroup = 3; + */ + public Builder setProducerGroupBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + producerGroup_ = value; + onChanged(); + return this; + } + + private Object consumerGroup_ = ""; + /** + * string consumerGroup = 4; + */ + public String getConsumerGroup() { + Object ref = consumerGroup_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + consumerGroup_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string consumerGroup = 4; + */ + public com.google.protobuf.ByteString + getConsumerGroupBytes() { + Object ref = consumerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + consumerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string consumerGroup = 4; + */ + public Builder setConsumerGroup( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + consumerGroup_ = value; + onChanged(); + return this; + } + /** + * string consumerGroup = 4; + */ + public Builder clearConsumerGroup() { + + consumerGroup_ = getDefaultInstance().getConsumerGroup(); + onChanged(); + return this; + } + /** + * string consumerGroup = 4; + */ + public Builder setConsumerGroupBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + consumerGroup_ = value; + onChanged(); + return this; + } + + private java.util.List heartbeatItems_ = + java.util.Collections.emptyList(); + private void ensureHeartbeatItemsIsMutable() { + if (!((bitField0_ & 0x00000010) == 0x00000010)) { + heartbeatItems_ = new java.util.ArrayList(heartbeatItems_); + bitField0_ |= 0x00000010; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + HeartbeatItem, HeartbeatItem.Builder, HeartbeatItemOrBuilder> heartbeatItemsBuilder_; + + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public java.util.List getHeartbeatItemsList() { + if (heartbeatItemsBuilder_ == null) { + return java.util.Collections.unmodifiableList(heartbeatItems_); + } else { + return heartbeatItemsBuilder_.getMessageList(); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public int getHeartbeatItemsCount() { + if (heartbeatItemsBuilder_ == null) { + return heartbeatItems_.size(); + } else { + return heartbeatItemsBuilder_.getCount(); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public HeartbeatItem getHeartbeatItems(int index) { + if (heartbeatItemsBuilder_ == null) { + return heartbeatItems_.get(index); + } else { + return heartbeatItemsBuilder_.getMessage(index); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder setHeartbeatItems( + int index, HeartbeatItem value) { + if (heartbeatItemsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.set(index, value); + onChanged(); + } else { + heartbeatItemsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder setHeartbeatItems( + int index, HeartbeatItem.Builder builderForValue) { + if (heartbeatItemsBuilder_ == null) { + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.set(index, builderForValue.build()); + onChanged(); + } else { + heartbeatItemsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder addHeartbeatItems(HeartbeatItem value) { + if (heartbeatItemsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.add(value); + onChanged(); + } else { + heartbeatItemsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder addHeartbeatItems( + int index, HeartbeatItem value) { + if (heartbeatItemsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.add(index, value); + onChanged(); + } else { + heartbeatItemsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder addHeartbeatItems( + HeartbeatItem.Builder builderForValue) { + if (heartbeatItemsBuilder_ == null) { + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.add(builderForValue.build()); + onChanged(); + } else { + heartbeatItemsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder addHeartbeatItems( + int index, HeartbeatItem.Builder builderForValue) { + if (heartbeatItemsBuilder_ == null) { + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.add(index, builderForValue.build()); + onChanged(); + } else { + heartbeatItemsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder addAllHeartbeatItems( + Iterable values) { + if (heartbeatItemsBuilder_ == null) { + ensureHeartbeatItemsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, heartbeatItems_); + onChanged(); + } else { + heartbeatItemsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder clearHeartbeatItems() { + if (heartbeatItemsBuilder_ == null) { + heartbeatItems_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); + onChanged(); + } else { + heartbeatItemsBuilder_.clear(); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public Builder removeHeartbeatItems(int index) { + if (heartbeatItemsBuilder_ == null) { + ensureHeartbeatItemsIsMutable(); + heartbeatItems_.remove(index); + onChanged(); + } else { + heartbeatItemsBuilder_.remove(index); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public HeartbeatItem.Builder getHeartbeatItemsBuilder( + int index) { + return getHeartbeatItemsFieldBuilder().getBuilder(index); + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public HeartbeatItemOrBuilder getHeartbeatItemsOrBuilder( + int index) { + if (heartbeatItemsBuilder_ == null) { + return heartbeatItems_.get(index); } else { + return heartbeatItemsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public java.util.List + getHeartbeatItemsOrBuilderList() { + if (heartbeatItemsBuilder_ != null) { + return heartbeatItemsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(heartbeatItems_); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public HeartbeatItem.Builder addHeartbeatItemsBuilder() { + return getHeartbeatItemsFieldBuilder().addBuilder( + HeartbeatItem.getDefaultInstance()); + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public HeartbeatItem.Builder addHeartbeatItemsBuilder( + int index) { + return getHeartbeatItemsFieldBuilder().addBuilder( + index, HeartbeatItem.getDefaultInstance()); + } + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + public java.util.List + getHeartbeatItemsBuilderList() { + return getHeartbeatItemsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + HeartbeatItem, HeartbeatItem.Builder, HeartbeatItemOrBuilder> + getHeartbeatItemsFieldBuilder() { + if (heartbeatItemsBuilder_ == null) { + heartbeatItemsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + HeartbeatItem, HeartbeatItem.Builder, HeartbeatItemOrBuilder>( + heartbeatItems_, + ((bitField0_ & 0x00000010) == 0x00000010), + getParentForChildren(), + isClean()); + heartbeatItems_ = null; + } + return heartbeatItemsBuilder_; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.Heartbeat) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.Heartbeat) + private static final Heartbeat DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new Heartbeat(); + } + + public static Heartbeat getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public Heartbeat parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Heartbeat(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public Heartbeat getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatOrBuilder.java new file mode 100644 index 0000000000..c3cddbdb4b --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatOrBuilder.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +@SuppressWarnings({"all"}) +public interface HeartbeatOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.Heartbeat) + com.google.protobuf.MessageOrBuilder { + + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + boolean hasHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeader getHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeaderOrBuilder getHeaderOrBuilder(); + + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + int getClientTypeValue(); + /** + * .eventmesh.common.protocol.grpc.Heartbeat.ClientType clientType = 2; + */ + Heartbeat.ClientType getClientType(); + + /** + * string producerGroup = 3; + */ + String getProducerGroup(); + /** + * string producerGroup = 3; + */ + com.google.protobuf.ByteString + getProducerGroupBytes(); + + /** + * string consumerGroup = 4; + */ + String getConsumerGroup(); + /** + * string consumerGroup = 4; + */ + com.google.protobuf.ByteString + getConsumerGroupBytes(); + + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + java.util.List + getHeartbeatItemsList(); + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + Heartbeat.HeartbeatItem getHeartbeatItems(int index); + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + int getHeartbeatItemsCount(); + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + java.util.List + getHeartbeatItemsOrBuilderList(); + /** + * repeated .eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem heartbeatItems = 5; + */ + Heartbeat.HeartbeatItemOrBuilder getHeartbeatItemsOrBuilder( + int index); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatServiceGrpc.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatServiceGrpc.java new file mode 100644 index 0000000000..0860cc7e23 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatServiceGrpc.java @@ -0,0 +1,290 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.grpc.protos; + +import static io.grpc.MethodDescriptor.generateFullMethodName; +import static io.grpc.stub.ClientCalls.asyncUnaryCall; +import static io.grpc.stub.ClientCalls.blockingUnaryCall; +import static io.grpc.stub.ClientCalls.futureUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +/** + */ +@SuppressWarnings({"all"}) +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.17.1)", + comments = "Source: eventmesh-client.proto") +public final class HeartbeatServiceGrpc { + + private HeartbeatServiceGrpc() {} + + public static final String SERVICE_NAME = "eventmesh.common.protocol.grpc.HeartbeatService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getHeartbeatMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "heartbeat", + requestType = Heartbeat.class, + responseType = Response.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getHeartbeatMethod() { + io.grpc.MethodDescriptor getHeartbeatMethod; + if ((getHeartbeatMethod = HeartbeatServiceGrpc.getHeartbeatMethod) == null) { + synchronized (HeartbeatServiceGrpc.class) { + if ((getHeartbeatMethod = HeartbeatServiceGrpc.getHeartbeatMethod) == null) { + HeartbeatServiceGrpc.getHeartbeatMethod = getHeartbeatMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "eventmesh.common.protocol.grpc.HeartbeatService", "heartbeat")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Heartbeat.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Response.getDefaultInstance())) + .setSchemaDescriptor(new HeartbeatServiceMethodDescriptorSupplier("heartbeat")) + .build(); + } + } + } + return getHeartbeatMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static HeartbeatServiceStub newStub(io.grpc.Channel channel) { + return new HeartbeatServiceStub(channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static HeartbeatServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new HeartbeatServiceBlockingStub(channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static HeartbeatServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + return new HeartbeatServiceFutureStub(channel); + } + + /** + */ + public static abstract class HeartbeatServiceImplBase implements io.grpc.BindableService { + + /** + */ + public void heartbeat(Heartbeat request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getHeartbeatMethod(), responseObserver); + } + + @Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getHeartbeatMethod(), + asyncUnaryCall( + new MethodHandlers< + Heartbeat, + Response>( + this, METHODID_HEARTBEAT))) + .build(); + } + } + + /** + */ + public static final class HeartbeatServiceStub extends io.grpc.stub.AbstractStub { + private HeartbeatServiceStub(io.grpc.Channel channel) { + super(channel); + } + + private HeartbeatServiceStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected HeartbeatServiceStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new HeartbeatServiceStub(channel, callOptions); + } + + /** + */ + public void heartbeat(Heartbeat request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getHeartbeatMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class HeartbeatServiceBlockingStub extends io.grpc.stub.AbstractStub { + private HeartbeatServiceBlockingStub(io.grpc.Channel channel) { + super(channel); + } + + private HeartbeatServiceBlockingStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected HeartbeatServiceBlockingStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new HeartbeatServiceBlockingStub(channel, callOptions); + } + + /** + */ + public Response heartbeat(Heartbeat request) { + return blockingUnaryCall( + getChannel(), getHeartbeatMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class HeartbeatServiceFutureStub extends io.grpc.stub.AbstractStub { + private HeartbeatServiceFutureStub(io.grpc.Channel channel) { + super(channel); + } + + private HeartbeatServiceFutureStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected HeartbeatServiceFutureStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new HeartbeatServiceFutureStub(channel, callOptions); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture heartbeat( + Heartbeat request) { + return futureUnaryCall( + getChannel().newCall(getHeartbeatMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_HEARTBEAT = 0; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final HeartbeatServiceImplBase serviceImpl; + private final int methodId; + + MethodHandlers(HeartbeatServiceImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @Override + @SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_HEARTBEAT: + serviceImpl.heartbeat((Heartbeat) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @Override + @SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + private static abstract class HeartbeatServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { + HeartbeatServiceBaseDescriptorSupplier() {} + + @Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return EventmeshGrpc.getDescriptor(); + } + + @Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("HeartbeatService"); + } + } + + private static final class HeartbeatServiceFileDescriptorSupplier + extends HeartbeatServiceBaseDescriptorSupplier { + HeartbeatServiceFileDescriptorSupplier() {} + } + + private static final class HeartbeatServiceMethodDescriptorSupplier + extends HeartbeatServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final String methodName; + + HeartbeatServiceMethodDescriptorSupplier(String methodName) { + this.methodName = methodName; + } + + @Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (HeartbeatServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new HeartbeatServiceFileDescriptorSupplier()) + .addMethod(getHeartbeatMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/PublisherServiceGrpc.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/PublisherServiceGrpc.java new file mode 100644 index 0000000000..c223f47a38 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/PublisherServiceGrpc.java @@ -0,0 +1,476 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.grpc.protos; + +import static io.grpc.MethodDescriptor.generateFullMethodName; +import static io.grpc.stub.ClientCalls.asyncUnaryCall; +import static io.grpc.stub.ClientCalls.blockingUnaryCall; +import static io.grpc.stub.ClientCalls.futureUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +/** + */ +@SuppressWarnings({"all"}) +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.17.1)", + comments = "Source: eventmesh-client.proto") +public final class PublisherServiceGrpc { + + private PublisherServiceGrpc() {} + + public static final String SERVICE_NAME = "eventmesh.common.protocol.grpc.PublisherService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getPublishMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "publish", + requestType = SimpleMessage.class, + responseType = Response.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getPublishMethod() { + io.grpc.MethodDescriptor getPublishMethod; + if ((getPublishMethod = PublisherServiceGrpc.getPublishMethod) == null) { + synchronized (PublisherServiceGrpc.class) { + if ((getPublishMethod = PublisherServiceGrpc.getPublishMethod) == null) { + PublisherServiceGrpc.getPublishMethod = getPublishMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "eventmesh.common.protocol.grpc.PublisherService", "publish")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + SimpleMessage.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Response.getDefaultInstance())) + .setSchemaDescriptor(new PublisherServiceMethodDescriptorSupplier("publish")) + .build(); + } + } + } + return getPublishMethod; + } + + private static volatile io.grpc.MethodDescriptor getRequestReplyMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "requestReply", + requestType = SimpleMessage.class, + responseType = SimpleMessage.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getRequestReplyMethod() { + io.grpc.MethodDescriptor getRequestReplyMethod; + if ((getRequestReplyMethod = PublisherServiceGrpc.getRequestReplyMethod) == null) { + synchronized (PublisherServiceGrpc.class) { + if ((getRequestReplyMethod = PublisherServiceGrpc.getRequestReplyMethod) == null) { + PublisherServiceGrpc.getRequestReplyMethod = getRequestReplyMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "eventmesh.common.protocol.grpc.PublisherService", "requestReply")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + SimpleMessage.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + SimpleMessage.getDefaultInstance())) + .setSchemaDescriptor(new PublisherServiceMethodDescriptorSupplier("requestReply")) + .build(); + } + } + } + return getRequestReplyMethod; + } + + private static volatile io.grpc.MethodDescriptor getBatchPublishMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "batchPublish", + requestType = BatchMessage.class, + responseType = Response.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getBatchPublishMethod() { + io.grpc.MethodDescriptor getBatchPublishMethod; + if ((getBatchPublishMethod = PublisherServiceGrpc.getBatchPublishMethod) == null) { + synchronized (PublisherServiceGrpc.class) { + if ((getBatchPublishMethod = PublisherServiceGrpc.getBatchPublishMethod) == null) { + PublisherServiceGrpc.getBatchPublishMethod = getBatchPublishMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "eventmesh.common.protocol.grpc.PublisherService", "batchPublish")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + BatchMessage.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + Response.getDefaultInstance())) + .setSchemaDescriptor(new PublisherServiceMethodDescriptorSupplier("batchPublish")) + .build(); + } + } + } + return getBatchPublishMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static PublisherServiceStub newStub(io.grpc.Channel channel) { + return new PublisherServiceStub(channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static PublisherServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new PublisherServiceBlockingStub(channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static PublisherServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + return new PublisherServiceFutureStub(channel); + } + + /** + */ + public static abstract class PublisherServiceImplBase implements io.grpc.BindableService { + + /** + *
+     * Async event publish
+     * 
+ */ + public void publish(SimpleMessage request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getPublishMethod(), responseObserver); + } + + /** + *
+     * Sync event publish
+     * 
+ */ + public void requestReply(SimpleMessage request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getRequestReplyMethod(), responseObserver); + } + + /** + *
+     * Async batch event publish
+     * 
+ */ + public void batchPublish(BatchMessage request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getBatchPublishMethod(), responseObserver); + } + + @Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getPublishMethod(), + asyncUnaryCall( + new MethodHandlers< + SimpleMessage, + Response>( + this, METHODID_PUBLISH))) + .addMethod( + getRequestReplyMethod(), + asyncUnaryCall( + new MethodHandlers< + SimpleMessage, + SimpleMessage>( + this, METHODID_REQUEST_REPLY))) + .addMethod( + getBatchPublishMethod(), + asyncUnaryCall( + new MethodHandlers< + BatchMessage, + Response>( + this, METHODID_BATCH_PUBLISH))) + .build(); + } + } + + /** + */ + public static final class PublisherServiceStub extends io.grpc.stub.AbstractStub { + private PublisherServiceStub(io.grpc.Channel channel) { + super(channel); + } + + private PublisherServiceStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected PublisherServiceStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new PublisherServiceStub(channel, callOptions); + } + + /** + *
+     * Async event publish
+     * 
+ */ + public void publish(SimpleMessage request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getPublishMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Sync event publish
+     * 
+ */ + public void requestReply(SimpleMessage request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getRequestReplyMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Async batch event publish
+     * 
+ */ + public void batchPublish(BatchMessage request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getBatchPublishMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class PublisherServiceBlockingStub extends io.grpc.stub.AbstractStub { + private PublisherServiceBlockingStub(io.grpc.Channel channel) { + super(channel); + } + + private PublisherServiceBlockingStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected PublisherServiceBlockingStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new PublisherServiceBlockingStub(channel, callOptions); + } + + /** + *
+     * Async event publish
+     * 
+ */ + public Response publish(SimpleMessage request) { + return blockingUnaryCall( + getChannel(), getPublishMethod(), getCallOptions(), request); + } + + /** + *
+     * Sync event publish
+     * 
+ */ + public SimpleMessage requestReply(SimpleMessage request) { + return blockingUnaryCall( + getChannel(), getRequestReplyMethod(), getCallOptions(), request); + } + + /** + *
+     * Async batch event publish
+     * 
+ */ + public Response batchPublish(BatchMessage request) { + return blockingUnaryCall( + getChannel(), getBatchPublishMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class PublisherServiceFutureStub extends io.grpc.stub.AbstractStub { + private PublisherServiceFutureStub(io.grpc.Channel channel) { + super(channel); + } + + private PublisherServiceFutureStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected PublisherServiceFutureStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new PublisherServiceFutureStub(channel, callOptions); + } + + /** + *
+     * Async event publish
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture publish( + SimpleMessage request) { + return futureUnaryCall( + getChannel().newCall(getPublishMethod(), getCallOptions()), request); + } + + /** + *
+     * Sync event publish
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture requestReply( + SimpleMessage request) { + return futureUnaryCall( + getChannel().newCall(getRequestReplyMethod(), getCallOptions()), request); + } + + /** + *
+     * Async batch event publish
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture batchPublish( + BatchMessage request) { + return futureUnaryCall( + getChannel().newCall(getBatchPublishMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_PUBLISH = 0; + private static final int METHODID_REQUEST_REPLY = 1; + private static final int METHODID_BATCH_PUBLISH = 2; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final PublisherServiceImplBase serviceImpl; + private final int methodId; + + MethodHandlers(PublisherServiceImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @Override + @SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_PUBLISH: + serviceImpl.publish((SimpleMessage) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_REQUEST_REPLY: + serviceImpl.requestReply((SimpleMessage) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_BATCH_PUBLISH: + serviceImpl.batchPublish((BatchMessage) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @Override + @SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + private static abstract class PublisherServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { + PublisherServiceBaseDescriptorSupplier() {} + + @Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return EventmeshGrpc.getDescriptor(); + } + + @Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("PublisherService"); + } + } + + private static final class PublisherServiceFileDescriptorSupplier + extends PublisherServiceBaseDescriptorSupplier { + PublisherServiceFileDescriptorSupplier() {} + } + + private static final class PublisherServiceMethodDescriptorSupplier + extends PublisherServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final String methodName; + + PublisherServiceMethodDescriptorSupplier(String methodName) { + this.methodName = methodName; + } + + @Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (PublisherServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new PublisherServiceFileDescriptorSupplier()) + .addMethod(getPublishMethod()) + .addMethod(getRequestReplyMethod()) + .addMethod(getBatchPublishMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeader.java new file mode 100644 index 0000000000..3bd71b33e4 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeader.java @@ -0,0 +1,1931 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +/** + * Protobuf type {@code eventmesh.common.protocol.grpc.RequestHeader} + */ +@SuppressWarnings({"all"}) +public final class RequestHeader extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.RequestHeader) + RequestHeaderOrBuilder { +private static final long serialVersionUID = 0L; + // Use RequestHeader.newBuilder() to construct. + private RequestHeader(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private RequestHeader() { + env_ = ""; + region_ = ""; + idc_ = ""; + ip_ = ""; + pid_ = ""; + sys_ = ""; + username_ = ""; + password_ = ""; + language_ = ""; + protocolType_ = ""; + protocolVersion_ = ""; + protocolDesc_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private RequestHeader( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + String s = input.readStringRequireUtf8(); + + env_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + region_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + idc_ = s; + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + ip_ = s; + break; + } + case 42: { + String s = input.readStringRequireUtf8(); + + pid_ = s; + break; + } + case 50: { + String s = input.readStringRequireUtf8(); + + sys_ = s; + break; + } + case 58: { + String s = input.readStringRequireUtf8(); + + username_ = s; + break; + } + case 66: { + String s = input.readStringRequireUtf8(); + + password_ = s; + break; + } + case 74: { + String s = input.readStringRequireUtf8(); + + language_ = s; + break; + } + case 82: { + String s = input.readStringRequireUtf8(); + + protocolType_ = s; + break; + } + case 90: { + String s = input.readStringRequireUtf8(); + + protocolVersion_ = s; + break; + } + case 98: { + String s = input.readStringRequireUtf8(); + + protocolDesc_ = s; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_RequestHeader_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_RequestHeader_fieldAccessorTable + .ensureFieldAccessorsInitialized( + RequestHeader.class, Builder.class); + } + + public static final int ENV_FIELD_NUMBER = 1; + private volatile Object env_; + /** + * string env = 1; + */ + public String getEnv() { + Object ref = env_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + env_ = s; + return s; + } + } + /** + * string env = 1; + */ + public com.google.protobuf.ByteString + getEnvBytes() { + Object ref = env_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + env_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int REGION_FIELD_NUMBER = 2; + private volatile Object region_; + /** + * string region = 2; + */ + public String getRegion() { + Object ref = region_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + region_ = s; + return s; + } + } + /** + * string region = 2; + */ + public com.google.protobuf.ByteString + getRegionBytes() { + Object ref = region_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + region_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int IDC_FIELD_NUMBER = 3; + private volatile Object idc_; + /** + * string idc = 3; + */ + public String getIdc() { + Object ref = idc_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + idc_ = s; + return s; + } + } + /** + * string idc = 3; + */ + public com.google.protobuf.ByteString + getIdcBytes() { + Object ref = idc_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + idc_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int IP_FIELD_NUMBER = 4; + private volatile Object ip_; + /** + * string ip = 4; + */ + public String getIp() { + Object ref = ip_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ip_ = s; + return s; + } + } + /** + * string ip = 4; + */ + public com.google.protobuf.ByteString + getIpBytes() { + Object ref = ip_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ip_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PID_FIELD_NUMBER = 5; + private volatile Object pid_; + /** + * string pid = 5; + */ + public String getPid() { + Object ref = pid_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + pid_ = s; + return s; + } + } + /** + * string pid = 5; + */ + public com.google.protobuf.ByteString + getPidBytes() { + Object ref = pid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + pid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SYS_FIELD_NUMBER = 6; + private volatile Object sys_; + /** + * string sys = 6; + */ + public String getSys() { + Object ref = sys_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + sys_ = s; + return s; + } + } + /** + * string sys = 6; + */ + public com.google.protobuf.ByteString + getSysBytes() { + Object ref = sys_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + sys_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int USERNAME_FIELD_NUMBER = 7; + private volatile Object username_; + /** + * string username = 7; + */ + public String getUsername() { + Object ref = username_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + username_ = s; + return s; + } + } + /** + * string username = 7; + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PASSWORD_FIELD_NUMBER = 8; + private volatile Object password_; + /** + * string password = 8; + */ + public String getPassword() { + Object ref = password_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + password_ = s; + return s; + } + } + /** + * string password = 8; + */ + public com.google.protobuf.ByteString + getPasswordBytes() { + Object ref = password_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + password_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int LANGUAGE_FIELD_NUMBER = 9; + private volatile Object language_; + /** + * string language = 9; + */ + public String getLanguage() { + Object ref = language_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + language_ = s; + return s; + } + } + /** + * string language = 9; + */ + public com.google.protobuf.ByteString + getLanguageBytes() { + Object ref = language_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + language_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PROTOCOLTYPE_FIELD_NUMBER = 10; + private volatile Object protocolType_; + /** + * string protocolType = 10; + */ + public String getProtocolType() { + Object ref = protocolType_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + protocolType_ = s; + return s; + } + } + /** + * string protocolType = 10; + */ + public com.google.protobuf.ByteString + getProtocolTypeBytes() { + Object ref = protocolType_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + protocolType_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PROTOCOLVERSION_FIELD_NUMBER = 11; + private volatile Object protocolVersion_; + /** + * string protocolVersion = 11; + */ + public String getProtocolVersion() { + Object ref = protocolVersion_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + protocolVersion_ = s; + return s; + } + } + /** + * string protocolVersion = 11; + */ + public com.google.protobuf.ByteString + getProtocolVersionBytes() { + Object ref = protocolVersion_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + protocolVersion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PROTOCOLDESC_FIELD_NUMBER = 12; + private volatile Object protocolDesc_; + /** + * string protocolDesc = 12; + */ + public String getProtocolDesc() { + Object ref = protocolDesc_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + protocolDesc_ = s; + return s; + } + } + /** + * string protocolDesc = 12; + */ + public com.google.protobuf.ByteString + getProtocolDescBytes() { + Object ref = protocolDesc_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + protocolDesc_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getEnvBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, env_); + } + if (!getRegionBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, region_); + } + if (!getIdcBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, idc_); + } + if (!getIpBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, ip_); + } + if (!getPidBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, pid_); + } + if (!getSysBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, sys_); + } + if (!getUsernameBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 7, username_); + } + if (!getPasswordBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 8, password_); + } + if (!getLanguageBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 9, language_); + } + if (!getProtocolTypeBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 10, protocolType_); + } + if (!getProtocolVersionBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 11, protocolVersion_); + } + if (!getProtocolDescBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 12, protocolDesc_); + } + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getEnvBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, env_); + } + if (!getRegionBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, region_); + } + if (!getIdcBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, idc_); + } + if (!getIpBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, ip_); + } + if (!getPidBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, pid_); + } + if (!getSysBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, sys_); + } + if (!getUsernameBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, username_); + } + if (!getPasswordBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, password_); + } + if (!getLanguageBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(9, language_); + } + if (!getProtocolTypeBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(10, protocolType_); + } + if (!getProtocolVersionBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(11, protocolVersion_); + } + if (!getProtocolDescBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(12, protocolDesc_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof RequestHeader)) { + return super.equals(obj); + } + RequestHeader other = (RequestHeader) obj; + + boolean result = true; + result = result && getEnv() + .equals(other.getEnv()); + result = result && getRegion() + .equals(other.getRegion()); + result = result && getIdc() + .equals(other.getIdc()); + result = result && getIp() + .equals(other.getIp()); + result = result && getPid() + .equals(other.getPid()); + result = result && getSys() + .equals(other.getSys()); + result = result && getUsername() + .equals(other.getUsername()); + result = result && getPassword() + .equals(other.getPassword()); + result = result && getLanguage() + .equals(other.getLanguage()); + result = result && getProtocolType() + .equals(other.getProtocolType()); + result = result && getProtocolVersion() + .equals(other.getProtocolVersion()); + result = result && getProtocolDesc() + .equals(other.getProtocolDesc()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ENV_FIELD_NUMBER; + hash = (53 * hash) + getEnv().hashCode(); + hash = (37 * hash) + REGION_FIELD_NUMBER; + hash = (53 * hash) + getRegion().hashCode(); + hash = (37 * hash) + IDC_FIELD_NUMBER; + hash = (53 * hash) + getIdc().hashCode(); + hash = (37 * hash) + IP_FIELD_NUMBER; + hash = (53 * hash) + getIp().hashCode(); + hash = (37 * hash) + PID_FIELD_NUMBER; + hash = (53 * hash) + getPid().hashCode(); + hash = (37 * hash) + SYS_FIELD_NUMBER; + hash = (53 * hash) + getSys().hashCode(); + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + hash = (37 * hash) + PASSWORD_FIELD_NUMBER; + hash = (53 * hash) + getPassword().hashCode(); + hash = (37 * hash) + LANGUAGE_FIELD_NUMBER; + hash = (53 * hash) + getLanguage().hashCode(); + hash = (37 * hash) + PROTOCOLTYPE_FIELD_NUMBER; + hash = (53 * hash) + getProtocolType().hashCode(); + hash = (37 * hash) + PROTOCOLVERSION_FIELD_NUMBER; + hash = (53 * hash) + getProtocolVersion().hashCode(); + hash = (37 * hash) + PROTOCOLDESC_FIELD_NUMBER; + hash = (53 * hash) + getProtocolDesc().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static RequestHeader parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static RequestHeader parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static RequestHeader parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static RequestHeader parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static RequestHeader parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static RequestHeader parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static RequestHeader parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static RequestHeader parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static RequestHeader parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static RequestHeader parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static RequestHeader parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static RequestHeader parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(RequestHeader prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.RequestHeader} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.RequestHeader) + RequestHeaderOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_RequestHeader_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_RequestHeader_fieldAccessorTable + .ensureFieldAccessorsInitialized( + RequestHeader.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + env_ = ""; + + region_ = ""; + + idc_ = ""; + + ip_ = ""; + + pid_ = ""; + + sys_ = ""; + + username_ = ""; + + password_ = ""; + + language_ = ""; + + protocolType_ = ""; + + protocolVersion_ = ""; + + protocolDesc_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_RequestHeader_descriptor; + } + + public RequestHeader getDefaultInstanceForType() { + return RequestHeader.getDefaultInstance(); + } + + public RequestHeader build() { + RequestHeader result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public RequestHeader buildPartial() { + RequestHeader result = new RequestHeader(this); + result.env_ = env_; + result.region_ = region_; + result.idc_ = idc_; + result.ip_ = ip_; + result.pid_ = pid_; + result.sys_ = sys_; + result.username_ = username_; + result.password_ = password_; + result.language_ = language_; + result.protocolType_ = protocolType_; + result.protocolVersion_ = protocolVersion_; + result.protocolDesc_ = protocolDesc_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof RequestHeader) { + return mergeFrom((RequestHeader)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(RequestHeader other) { + if (other == RequestHeader.getDefaultInstance()) return this; + if (!other.getEnv().isEmpty()) { + env_ = other.env_; + onChanged(); + } + if (!other.getRegion().isEmpty()) { + region_ = other.region_; + onChanged(); + } + if (!other.getIdc().isEmpty()) { + idc_ = other.idc_; + onChanged(); + } + if (!other.getIp().isEmpty()) { + ip_ = other.ip_; + onChanged(); + } + if (!other.getPid().isEmpty()) { + pid_ = other.pid_; + onChanged(); + } + if (!other.getSys().isEmpty()) { + sys_ = other.sys_; + onChanged(); + } + if (!other.getUsername().isEmpty()) { + username_ = other.username_; + onChanged(); + } + if (!other.getPassword().isEmpty()) { + password_ = other.password_; + onChanged(); + } + if (!other.getLanguage().isEmpty()) { + language_ = other.language_; + onChanged(); + } + if (!other.getProtocolType().isEmpty()) { + protocolType_ = other.protocolType_; + onChanged(); + } + if (!other.getProtocolVersion().isEmpty()) { + protocolVersion_ = other.protocolVersion_; + onChanged(); + } + if (!other.getProtocolDesc().isEmpty()) { + protocolDesc_ = other.protocolDesc_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + RequestHeader parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (RequestHeader) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private Object env_ = ""; + /** + * string env = 1; + */ + public String getEnv() { + Object ref = env_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + env_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string env = 1; + */ + public com.google.protobuf.ByteString + getEnvBytes() { + Object ref = env_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + env_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string env = 1; + */ + public Builder setEnv( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + env_ = value; + onChanged(); + return this; + } + /** + * string env = 1; + */ + public Builder clearEnv() { + + env_ = getDefaultInstance().getEnv(); + onChanged(); + return this; + } + /** + * string env = 1; + */ + public Builder setEnvBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + env_ = value; + onChanged(); + return this; + } + + private Object region_ = ""; + /** + * string region = 2; + */ + public String getRegion() { + Object ref = region_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + region_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string region = 2; + */ + public com.google.protobuf.ByteString + getRegionBytes() { + Object ref = region_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + region_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string region = 2; + */ + public Builder setRegion( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + region_ = value; + onChanged(); + return this; + } + /** + * string region = 2; + */ + public Builder clearRegion() { + + region_ = getDefaultInstance().getRegion(); + onChanged(); + return this; + } + /** + * string region = 2; + */ + public Builder setRegionBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + region_ = value; + onChanged(); + return this; + } + + private Object idc_ = ""; + /** + * string idc = 3; + */ + public String getIdc() { + Object ref = idc_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + idc_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string idc = 3; + */ + public com.google.protobuf.ByteString + getIdcBytes() { + Object ref = idc_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + idc_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string idc = 3; + */ + public Builder setIdc( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + idc_ = value; + onChanged(); + return this; + } + /** + * string idc = 3; + */ + public Builder clearIdc() { + + idc_ = getDefaultInstance().getIdc(); + onChanged(); + return this; + } + /** + * string idc = 3; + */ + public Builder setIdcBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + idc_ = value; + onChanged(); + return this; + } + + private Object ip_ = ""; + /** + * string ip = 4; + */ + public String getIp() { + Object ref = ip_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ip_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string ip = 4; + */ + public com.google.protobuf.ByteString + getIpBytes() { + Object ref = ip_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ip_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string ip = 4; + */ + public Builder setIp( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + ip_ = value; + onChanged(); + return this; + } + /** + * string ip = 4; + */ + public Builder clearIp() { + + ip_ = getDefaultInstance().getIp(); + onChanged(); + return this; + } + /** + * string ip = 4; + */ + public Builder setIpBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + ip_ = value; + onChanged(); + return this; + } + + private Object pid_ = ""; + /** + * string pid = 5; + */ + public String getPid() { + Object ref = pid_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + pid_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string pid = 5; + */ + public com.google.protobuf.ByteString + getPidBytes() { + Object ref = pid_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + pid_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string pid = 5; + */ + public Builder setPid( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + pid_ = value; + onChanged(); + return this; + } + /** + * string pid = 5; + */ + public Builder clearPid() { + + pid_ = getDefaultInstance().getPid(); + onChanged(); + return this; + } + /** + * string pid = 5; + */ + public Builder setPidBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + pid_ = value; + onChanged(); + return this; + } + + private Object sys_ = ""; + /** + * string sys = 6; + */ + public String getSys() { + Object ref = sys_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + sys_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string sys = 6; + */ + public com.google.protobuf.ByteString + getSysBytes() { + Object ref = sys_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + sys_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string sys = 6; + */ + public Builder setSys( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + sys_ = value; + onChanged(); + return this; + } + /** + * string sys = 6; + */ + public Builder clearSys() { + + sys_ = getDefaultInstance().getSys(); + onChanged(); + return this; + } + /** + * string sys = 6; + */ + public Builder setSysBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + sys_ = value; + onChanged(); + return this; + } + + private Object username_ = ""; + /** + * string username = 7; + */ + public String getUsername() { + Object ref = username_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + username_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string username = 7; + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string username = 7; + */ + public Builder setUsername( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + username_ = value; + onChanged(); + return this; + } + /** + * string username = 7; + */ + public Builder clearUsername() { + + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * string username = 7; + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + username_ = value; + onChanged(); + return this; + } + + private Object password_ = ""; + /** + * string password = 8; + */ + public String getPassword() { + Object ref = password_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + password_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string password = 8; + */ + public com.google.protobuf.ByteString + getPasswordBytes() { + Object ref = password_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + password_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string password = 8; + */ + public Builder setPassword( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + password_ = value; + onChanged(); + return this; + } + /** + * string password = 8; + */ + public Builder clearPassword() { + + password_ = getDefaultInstance().getPassword(); + onChanged(); + return this; + } + /** + * string password = 8; + */ + public Builder setPasswordBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + password_ = value; + onChanged(); + return this; + } + + private Object language_ = ""; + /** + * string language = 9; + */ + public String getLanguage() { + Object ref = language_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + language_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string language = 9; + */ + public com.google.protobuf.ByteString + getLanguageBytes() { + Object ref = language_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + language_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string language = 9; + */ + public Builder setLanguage( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + language_ = value; + onChanged(); + return this; + } + /** + * string language = 9; + */ + public Builder clearLanguage() { + + language_ = getDefaultInstance().getLanguage(); + onChanged(); + return this; + } + /** + * string language = 9; + */ + public Builder setLanguageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + language_ = value; + onChanged(); + return this; + } + + private Object protocolType_ = ""; + /** + * string protocolType = 10; + */ + public String getProtocolType() { + Object ref = protocolType_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + protocolType_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string protocolType = 10; + */ + public com.google.protobuf.ByteString + getProtocolTypeBytes() { + Object ref = protocolType_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + protocolType_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string protocolType = 10; + */ + public Builder setProtocolType( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + protocolType_ = value; + onChanged(); + return this; + } + /** + * string protocolType = 10; + */ + public Builder clearProtocolType() { + + protocolType_ = getDefaultInstance().getProtocolType(); + onChanged(); + return this; + } + /** + * string protocolType = 10; + */ + public Builder setProtocolTypeBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + protocolType_ = value; + onChanged(); + return this; + } + + private Object protocolVersion_ = ""; + /** + * string protocolVersion = 11; + */ + public String getProtocolVersion() { + Object ref = protocolVersion_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + protocolVersion_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string protocolVersion = 11; + */ + public com.google.protobuf.ByteString + getProtocolVersionBytes() { + Object ref = protocolVersion_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + protocolVersion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string protocolVersion = 11; + */ + public Builder setProtocolVersion( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + protocolVersion_ = value; + onChanged(); + return this; + } + /** + * string protocolVersion = 11; + */ + public Builder clearProtocolVersion() { + + protocolVersion_ = getDefaultInstance().getProtocolVersion(); + onChanged(); + return this; + } + /** + * string protocolVersion = 11; + */ + public Builder setProtocolVersionBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + protocolVersion_ = value; + onChanged(); + return this; + } + + private Object protocolDesc_ = ""; + /** + * string protocolDesc = 12; + */ + public String getProtocolDesc() { + Object ref = protocolDesc_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + protocolDesc_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string protocolDesc = 12; + */ + public com.google.protobuf.ByteString + getProtocolDescBytes() { + Object ref = protocolDesc_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + protocolDesc_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string protocolDesc = 12; + */ + public Builder setProtocolDesc( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + protocolDesc_ = value; + onChanged(); + return this; + } + /** + * string protocolDesc = 12; + */ + public Builder clearProtocolDesc() { + + protocolDesc_ = getDefaultInstance().getProtocolDesc(); + onChanged(); + return this; + } + /** + * string protocolDesc = 12; + */ + public Builder setProtocolDescBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + protocolDesc_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.RequestHeader) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.RequestHeader) + private static final RequestHeader DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new RequestHeader(); + } + + public static RequestHeader getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public RequestHeader parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new RequestHeader(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public RequestHeader getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeaderOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeaderOrBuilder.java new file mode 100644 index 0000000000..ec8a176bba --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeaderOrBuilder.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +@SuppressWarnings({"all"}) +public interface RequestHeaderOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.RequestHeader) + com.google.protobuf.MessageOrBuilder { + + /** + * string env = 1; + */ + String getEnv(); + /** + * string env = 1; + */ + com.google.protobuf.ByteString + getEnvBytes(); + + /** + * string region = 2; + */ + String getRegion(); + /** + * string region = 2; + */ + com.google.protobuf.ByteString + getRegionBytes(); + + /** + * string idc = 3; + */ + String getIdc(); + /** + * string idc = 3; + */ + com.google.protobuf.ByteString + getIdcBytes(); + + /** + * string ip = 4; + */ + String getIp(); + /** + * string ip = 4; + */ + com.google.protobuf.ByteString + getIpBytes(); + + /** + * string pid = 5; + */ + String getPid(); + /** + * string pid = 5; + */ + com.google.protobuf.ByteString + getPidBytes(); + + /** + * string sys = 6; + */ + String getSys(); + /** + * string sys = 6; + */ + com.google.protobuf.ByteString + getSysBytes(); + + /** + * string username = 7; + */ + String getUsername(); + /** + * string username = 7; + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * string password = 8; + */ + String getPassword(); + /** + * string password = 8; + */ + com.google.protobuf.ByteString + getPasswordBytes(); + + /** + * string language = 9; + */ + String getLanguage(); + /** + * string language = 9; + */ + com.google.protobuf.ByteString + getLanguageBytes(); + + /** + * string protocolType = 10; + */ + String getProtocolType(); + /** + * string protocolType = 10; + */ + com.google.protobuf.ByteString + getProtocolTypeBytes(); + + /** + * string protocolVersion = 11; + */ + String getProtocolVersion(); + /** + * string protocolVersion = 11; + */ + com.google.protobuf.ByteString + getProtocolVersionBytes(); + + /** + * string protocolDesc = 12; + */ + String getProtocolDesc(); + /** + * string protocolDesc = 12; + */ + com.google.protobuf.ByteString + getProtocolDescBytes(); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Response.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Response.java new file mode 100644 index 0000000000..c8a1f79dec --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Response.java @@ -0,0 +1,788 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +/** + * Protobuf type {@code eventmesh.common.protocol.grpc.Response} + */ +@SuppressWarnings({"all"}) +public final class Response extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.Response) + ResponseOrBuilder { +private static final long serialVersionUID = 0L; + // Use Response.newBuilder() to construct. + private Response(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Response() { + respCode_ = ""; + respMsg_ = ""; + respTime_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Response( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + String s = input.readStringRequireUtf8(); + + respCode_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + respMsg_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + respTime_ = s; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Response_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Response_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Response.class, Builder.class); + } + + public static final int RESPCODE_FIELD_NUMBER = 1; + private volatile Object respCode_; + /** + * string respCode = 1; + */ + public String getRespCode() { + Object ref = respCode_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + respCode_ = s; + return s; + } + } + /** + * string respCode = 1; + */ + public com.google.protobuf.ByteString + getRespCodeBytes() { + Object ref = respCode_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + respCode_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int RESPMSG_FIELD_NUMBER = 2; + private volatile Object respMsg_; + /** + * string respMsg = 2; + */ + public String getRespMsg() { + Object ref = respMsg_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + respMsg_ = s; + return s; + } + } + /** + * string respMsg = 2; + */ + public com.google.protobuf.ByteString + getRespMsgBytes() { + Object ref = respMsg_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + respMsg_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int RESPTIME_FIELD_NUMBER = 3; + private volatile Object respTime_; + /** + * string respTime = 3; + */ + public String getRespTime() { + Object ref = respTime_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + respTime_ = s; + return s; + } + } + /** + * string respTime = 3; + */ + public com.google.protobuf.ByteString + getRespTimeBytes() { + Object ref = respTime_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + respTime_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getRespCodeBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, respCode_); + } + if (!getRespMsgBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, respMsg_); + } + if (!getRespTimeBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, respTime_); + } + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getRespCodeBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, respCode_); + } + if (!getRespMsgBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, respMsg_); + } + if (!getRespTimeBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, respTime_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Response)) { + return super.equals(obj); + } + Response other = (Response) obj; + + boolean result = true; + result = result && getRespCode() + .equals(other.getRespCode()); + result = result && getRespMsg() + .equals(other.getRespMsg()); + result = result && getRespTime() + .equals(other.getRespTime()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + RESPCODE_FIELD_NUMBER; + hash = (53 * hash) + getRespCode().hashCode(); + hash = (37 * hash) + RESPMSG_FIELD_NUMBER; + hash = (53 * hash) + getRespMsg().hashCode(); + hash = (37 * hash) + RESPTIME_FIELD_NUMBER; + hash = (53 * hash) + getRespTime().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static Response parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Response parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Response parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Response parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Response parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Response parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Response parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Response parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static Response parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static Response parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static Response parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Response parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(Response prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Response} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.Response) + ResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Response_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Response_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Response.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.Response.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + respCode_ = ""; + + respMsg_ = ""; + + respTime_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Response_descriptor; + } + + public Response getDefaultInstanceForType() { + return Response.getDefaultInstance(); + } + + public Response build() { + Response result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public Response buildPartial() { + Response result = new Response(this); + result.respCode_ = respCode_; + result.respMsg_ = respMsg_; + result.respTime_ = respTime_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof Response) { + return mergeFrom((Response)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(Response other) { + if (other == Response.getDefaultInstance()) return this; + if (!other.getRespCode().isEmpty()) { + respCode_ = other.respCode_; + onChanged(); + } + if (!other.getRespMsg().isEmpty()) { + respMsg_ = other.respMsg_; + onChanged(); + } + if (!other.getRespTime().isEmpty()) { + respTime_ = other.respTime_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Response parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (Response) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private Object respCode_ = ""; + /** + * string respCode = 1; + */ + public String getRespCode() { + Object ref = respCode_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + respCode_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string respCode = 1; + */ + public com.google.protobuf.ByteString + getRespCodeBytes() { + Object ref = respCode_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + respCode_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string respCode = 1; + */ + public Builder setRespCode( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + respCode_ = value; + onChanged(); + return this; + } + /** + * string respCode = 1; + */ + public Builder clearRespCode() { + + respCode_ = getDefaultInstance().getRespCode(); + onChanged(); + return this; + } + /** + * string respCode = 1; + */ + public Builder setRespCodeBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + respCode_ = value; + onChanged(); + return this; + } + + private Object respMsg_ = ""; + /** + * string respMsg = 2; + */ + public String getRespMsg() { + Object ref = respMsg_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + respMsg_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string respMsg = 2; + */ + public com.google.protobuf.ByteString + getRespMsgBytes() { + Object ref = respMsg_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + respMsg_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string respMsg = 2; + */ + public Builder setRespMsg( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + respMsg_ = value; + onChanged(); + return this; + } + /** + * string respMsg = 2; + */ + public Builder clearRespMsg() { + + respMsg_ = getDefaultInstance().getRespMsg(); + onChanged(); + return this; + } + /** + * string respMsg = 2; + */ + public Builder setRespMsgBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + respMsg_ = value; + onChanged(); + return this; + } + + private Object respTime_ = ""; + /** + * string respTime = 3; + */ + public String getRespTime() { + Object ref = respTime_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + respTime_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string respTime = 3; + */ + public com.google.protobuf.ByteString + getRespTimeBytes() { + Object ref = respTime_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + respTime_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string respTime = 3; + */ + public Builder setRespTime( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + respTime_ = value; + onChanged(); + return this; + } + /** + * string respTime = 3; + */ + public Builder clearRespTime() { + + respTime_ = getDefaultInstance().getRespTime(); + onChanged(); + return this; + } + /** + * string respTime = 3; + */ + public Builder setRespTimeBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + respTime_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.Response) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.Response) + private static final Response DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new Response(); + } + + public static Response getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public Response parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Response(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public Response getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ResponseOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ResponseOrBuilder.java new file mode 100644 index 0000000000..9ffcff9482 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ResponseOrBuilder.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +@SuppressWarnings({"all"}) +public interface ResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.Response) + com.google.protobuf.MessageOrBuilder { + + /** + * string respCode = 1; + */ + String getRespCode(); + /** + * string respCode = 1; + */ + com.google.protobuf.ByteString + getRespCodeBytes(); + + /** + * string respMsg = 2; + */ + String getRespMsg(); + /** + * string respMsg = 2; + */ + com.google.protobuf.ByteString + getRespMsgBytes(); + + /** + * string respTime = 3; + */ + String getRespTime(); + /** + * string respTime = 3; + */ + com.google.protobuf.ByteString + getRespTimeBytes(); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessage.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessage.java new file mode 100644 index 0000000000..5ca4c70f12 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessage.java @@ -0,0 +1,1754 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +/** + * Protobuf type {@code eventmesh.common.protocol.grpc.SimpleMessage} + */ +@SuppressWarnings({"all"}) +public final class SimpleMessage extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.SimpleMessage) + SimpleMessageOrBuilder { +private static final long serialVersionUID = 0L; + // Use SimpleMessage.newBuilder() to construct. + private SimpleMessage(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private SimpleMessage() { + producerGroup_ = ""; + topic_ = ""; + content_ = ""; + ttl_ = ""; + uniqueId_ = ""; + seqNum_ = ""; + tag_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SimpleMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + RequestHeader.Builder subBuilder = null; + if (header_ != null) { + subBuilder = header_.toBuilder(); + } + header_ = input.readMessage(RequestHeader.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(header_); + header_ = subBuilder.buildPartial(); + } + + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + producerGroup_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + topic_ = s; + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + content_ = s; + break; + } + case 42: { + String s = input.readStringRequireUtf8(); + + ttl_ = s; + break; + } + case 50: { + String s = input.readStringRequireUtf8(); + + uniqueId_ = s; + break; + } + case 58: { + String s = input.readStringRequireUtf8(); + + seqNum_ = s; + break; + } + case 66: { + String s = input.readStringRequireUtf8(); + + tag_ = s; + break; + } + case 74: { + if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) { + properties_ = com.google.protobuf.MapField.newMapField( + PropertiesDefaultEntryHolder.defaultEntry); + mutable_bitField0_ |= 0x00000100; + } + com.google.protobuf.MapEntry + properties__ = input.readMessage( + PropertiesDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); + properties_.getMutableMap().put( + properties__.getKey(), properties__.getValue()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_SimpleMessage_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 9: + return internalGetProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_SimpleMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + SimpleMessage.class, Builder.class); + } + + private int bitField0_; + public static final int HEADER_FIELD_NUMBER = 1; + private RequestHeader header_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + return getHeader(); + } + + public static final int PRODUCERGROUP_FIELD_NUMBER = 2; + private volatile Object producerGroup_; + /** + * string producerGroup = 2; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } + } + /** + * string producerGroup = 2; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TOPIC_FIELD_NUMBER = 3; + private volatile Object topic_; + /** + * string topic = 3; + */ + public String getTopic() { + Object ref = topic_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } + } + /** + * string topic = 3; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CONTENT_FIELD_NUMBER = 4; + private volatile Object content_; + /** + * string content = 4; + */ + public String getContent() { + Object ref = content_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + content_ = s; + return s; + } + } + /** + * string content = 4; + */ + public com.google.protobuf.ByteString + getContentBytes() { + Object ref = content_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TTL_FIELD_NUMBER = 5; + private volatile Object ttl_; + /** + * string ttl = 5; + */ + public String getTtl() { + Object ref = ttl_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ttl_ = s; + return s; + } + } + /** + * string ttl = 5; + */ + public com.google.protobuf.ByteString + getTtlBytes() { + Object ref = ttl_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ttl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int UNIQUEID_FIELD_NUMBER = 6; + private volatile Object uniqueId_; + /** + * string uniqueId = 6; + */ + public String getUniqueId() { + Object ref = uniqueId_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + uniqueId_ = s; + return s; + } + } + /** + * string uniqueId = 6; + */ + public com.google.protobuf.ByteString + getUniqueIdBytes() { + Object ref = uniqueId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + uniqueId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SEQNUM_FIELD_NUMBER = 7; + private volatile Object seqNum_; + /** + * string seqNum = 7; + */ + public String getSeqNum() { + Object ref = seqNum_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + seqNum_ = s; + return s; + } + } + /** + * string seqNum = 7; + */ + public com.google.protobuf.ByteString + getSeqNumBytes() { + Object ref = seqNum_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + seqNum_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TAG_FIELD_NUMBER = 8; + private volatile Object tag_; + /** + * string tag = 8; + */ + public String getTag() { + Object ref = tag_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + tag_ = s; + return s; + } + } + /** + * string tag = 8; + */ + public com.google.protobuf.ByteString + getTagBytes() { + Object ref = tag_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + tag_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PROPERTIES_FIELD_NUMBER = 9; + private static final class PropertiesDefaultEntryHolder { + static final com.google.protobuf.MapEntry< + String, String> defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_SimpleMessage_PropertiesEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.STRING, + ""); + } + private com.google.protobuf.MapField< + String, String> properties_; + private com.google.protobuf.MapField + internalGetProperties() { + if (properties_ == null) { + return com.google.protobuf.MapField.emptyMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + return properties_; + } + + public int getPropertiesCount() { + return internalGetProperties().getMap().size(); + } + /** + * map<string, string> properties = 9; + */ + + public boolean containsProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetProperties().getMap().containsKey(key); + } + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + public java.util.Map getProperties() { + return getPropertiesMap(); + } + /** + * map<string, string> properties = 9; + */ + + public java.util.Map getPropertiesMap() { + return internalGetProperties().getMap(); + } + /** + * map<string, string> properties = 9; + */ + + public String getPropertiesOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> properties = 9; + */ + + public String getPropertiesOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (header_ != null) { + output.writeMessage(1, getHeader()); + } + if (!getProducerGroupBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, producerGroup_); + } + if (!getTopicBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, topic_); + } + if (!getContentBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, content_); + } + if (!getTtlBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, ttl_); + } + if (!getUniqueIdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, uniqueId_); + } + if (!getSeqNumBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 7, seqNum_); + } + if (!getTagBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 8, tag_); + } + com.google.protobuf.GeneratedMessageV3 + .serializeStringMapTo( + output, + internalGetProperties(), + PropertiesDefaultEntryHolder.defaultEntry, + 9); + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (header_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getHeader()); + } + if (!getProducerGroupBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, producerGroup_); + } + if (!getTopicBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, topic_); + } + if (!getContentBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, content_); + } + if (!getTtlBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, ttl_); + } + if (!getUniqueIdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, uniqueId_); + } + if (!getSeqNumBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, seqNum_); + } + if (!getTagBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, tag_); + } + for (java.util.Map.Entry entry + : internalGetProperties().getMap().entrySet()) { + com.google.protobuf.MapEntry + properties__ = PropertiesDefaultEntryHolder.defaultEntry.newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(9, properties__); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SimpleMessage)) { + return super.equals(obj); + } + SimpleMessage other = (SimpleMessage) obj; + + boolean result = true; + result = result && (hasHeader() == other.hasHeader()); + if (hasHeader()) { + result = result && getHeader() + .equals(other.getHeader()); + } + result = result && getProducerGroup() + .equals(other.getProducerGroup()); + result = result && getTopic() + .equals(other.getTopic()); + result = result && getContent() + .equals(other.getContent()); + result = result && getTtl() + .equals(other.getTtl()); + result = result && getUniqueId() + .equals(other.getUniqueId()); + result = result && getSeqNum() + .equals(other.getSeqNum()); + result = result && getTag() + .equals(other.getTag()); + result = result && internalGetProperties().equals( + other.internalGetProperties()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasHeader()) { + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + } + hash = (37 * hash) + PRODUCERGROUP_FIELD_NUMBER; + hash = (53 * hash) + getProducerGroup().hashCode(); + hash = (37 * hash) + TOPIC_FIELD_NUMBER; + hash = (53 * hash) + getTopic().hashCode(); + hash = (37 * hash) + CONTENT_FIELD_NUMBER; + hash = (53 * hash) + getContent().hashCode(); + hash = (37 * hash) + TTL_FIELD_NUMBER; + hash = (53 * hash) + getTtl().hashCode(); + hash = (37 * hash) + UNIQUEID_FIELD_NUMBER; + hash = (53 * hash) + getUniqueId().hashCode(); + hash = (37 * hash) + SEQNUM_FIELD_NUMBER; + hash = (53 * hash) + getSeqNum().hashCode(); + hash = (37 * hash) + TAG_FIELD_NUMBER; + hash = (53 * hash) + getTag().hashCode(); + if (!internalGetProperties().getMap().isEmpty()) { + hash = (37 * hash) + PROPERTIES_FIELD_NUMBER; + hash = (53 * hash) + internalGetProperties().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static SimpleMessage parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static SimpleMessage parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static SimpleMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static SimpleMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static SimpleMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static SimpleMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static SimpleMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static SimpleMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static SimpleMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static SimpleMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static SimpleMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static SimpleMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(SimpleMessage prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.SimpleMessage} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.SimpleMessage) + SimpleMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_SimpleMessage_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 9: + return internalGetProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMutableMapField( + int number) { + switch (number) { + case 9: + return internalGetMutableProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_SimpleMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + SimpleMessage.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + if (headerBuilder_ == null) { + header_ = null; + } else { + header_ = null; + headerBuilder_ = null; + } + producerGroup_ = ""; + + topic_ = ""; + + content_ = ""; + + ttl_ = ""; + + uniqueId_ = ""; + + seqNum_ = ""; + + tag_ = ""; + + internalGetMutableProperties().clear(); + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_SimpleMessage_descriptor; + } + + public SimpleMessage getDefaultInstanceForType() { + return SimpleMessage.getDefaultInstance(); + } + + public SimpleMessage build() { + SimpleMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public SimpleMessage buildPartial() { + SimpleMessage result = new SimpleMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (headerBuilder_ == null) { + result.header_ = header_; + } else { + result.header_ = headerBuilder_.build(); + } + result.producerGroup_ = producerGroup_; + result.topic_ = topic_; + result.content_ = content_; + result.ttl_ = ttl_; + result.uniqueId_ = uniqueId_; + result.seqNum_ = seqNum_; + result.tag_ = tag_; + result.properties_ = internalGetProperties(); + result.properties_.makeImmutable(); + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof SimpleMessage) { + return mergeFrom((SimpleMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(SimpleMessage other) { + if (other == SimpleMessage.getDefaultInstance()) return this; + if (other.hasHeader()) { + mergeHeader(other.getHeader()); + } + if (!other.getProducerGroup().isEmpty()) { + producerGroup_ = other.producerGroup_; + onChanged(); + } + if (!other.getTopic().isEmpty()) { + topic_ = other.topic_; + onChanged(); + } + if (!other.getContent().isEmpty()) { + content_ = other.content_; + onChanged(); + } + if (!other.getTtl().isEmpty()) { + ttl_ = other.ttl_; + onChanged(); + } + if (!other.getUniqueId().isEmpty()) { + uniqueId_ = other.uniqueId_; + onChanged(); + } + if (!other.getSeqNum().isEmpty()) { + seqNum_ = other.seqNum_; + onChanged(); + } + if (!other.getTag().isEmpty()) { + tag_ = other.tag_; + onChanged(); + } + internalGetMutableProperties().mergeFrom( + other.internalGetProperties()); + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + SimpleMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (SimpleMessage) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private RequestHeader header_ = null; + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> headerBuilder_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return headerBuilder_ != null || header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + if (headerBuilder_ == null) { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } else { + return headerBuilder_.getMessage(); + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + header_ = value; + onChanged(); + } else { + headerBuilder_.setMessage(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader( + RequestHeader.Builder builderForValue) { + if (headerBuilder_ == null) { + header_ = builderForValue.build(); + onChanged(); + } else { + headerBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder mergeHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (header_ != null) { + header_ = + RequestHeader.newBuilder(header_).mergeFrom(value).buildPartial(); + } else { + header_ = value; + } + onChanged(); + } else { + headerBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder clearHeader() { + if (headerBuilder_ == null) { + header_ = null; + onChanged(); + } else { + header_ = null; + headerBuilder_ = null; + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader.Builder getHeaderBuilder() { + + onChanged(); + return getHeaderFieldBuilder().getBuilder(); + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + if (headerBuilder_ != null) { + return headerBuilder_.getMessageOrBuilder(); + } else { + return header_ == null ? + RequestHeader.getDefaultInstance() : header_; + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> + getHeaderFieldBuilder() { + if (headerBuilder_ == null) { + headerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder>( + getHeader(), + getParentForChildren(), + isClean()); + header_ = null; + } + return headerBuilder_; + } + + private Object producerGroup_ = ""; + /** + * string producerGroup = 2; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string producerGroup = 2; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string producerGroup = 2; + */ + public Builder setProducerGroup( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + producerGroup_ = value; + onChanged(); + return this; + } + /** + * string producerGroup = 2; + */ + public Builder clearProducerGroup() { + + producerGroup_ = getDefaultInstance().getProducerGroup(); + onChanged(); + return this; + } + /** + * string producerGroup = 2; + */ + public Builder setProducerGroupBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + producerGroup_ = value; + onChanged(); + return this; + } + + private Object topic_ = ""; + /** + * string topic = 3; + */ + public String getTopic() { + Object ref = topic_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string topic = 3; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string topic = 3; + */ + public Builder setTopic( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + topic_ = value; + onChanged(); + return this; + } + /** + * string topic = 3; + */ + public Builder clearTopic() { + + topic_ = getDefaultInstance().getTopic(); + onChanged(); + return this; + } + /** + * string topic = 3; + */ + public Builder setTopicBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + topic_ = value; + onChanged(); + return this; + } + + private Object content_ = ""; + /** + * string content = 4; + */ + public String getContent() { + Object ref = content_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + content_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string content = 4; + */ + public com.google.protobuf.ByteString + getContentBytes() { + Object ref = content_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string content = 4; + */ + public Builder setContent( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + content_ = value; + onChanged(); + return this; + } + /** + * string content = 4; + */ + public Builder clearContent() { + + content_ = getDefaultInstance().getContent(); + onChanged(); + return this; + } + /** + * string content = 4; + */ + public Builder setContentBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + content_ = value; + onChanged(); + return this; + } + + private Object ttl_ = ""; + /** + * string ttl = 5; + */ + public String getTtl() { + Object ref = ttl_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ttl_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string ttl = 5; + */ + public com.google.protobuf.ByteString + getTtlBytes() { + Object ref = ttl_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ttl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string ttl = 5; + */ + public Builder setTtl( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + ttl_ = value; + onChanged(); + return this; + } + /** + * string ttl = 5; + */ + public Builder clearTtl() { + + ttl_ = getDefaultInstance().getTtl(); + onChanged(); + return this; + } + /** + * string ttl = 5; + */ + public Builder setTtlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + ttl_ = value; + onChanged(); + return this; + } + + private Object uniqueId_ = ""; + /** + * string uniqueId = 6; + */ + public String getUniqueId() { + Object ref = uniqueId_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + uniqueId_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string uniqueId = 6; + */ + public com.google.protobuf.ByteString + getUniqueIdBytes() { + Object ref = uniqueId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + uniqueId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string uniqueId = 6; + */ + public Builder setUniqueId( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + uniqueId_ = value; + onChanged(); + return this; + } + /** + * string uniqueId = 6; + */ + public Builder clearUniqueId() { + + uniqueId_ = getDefaultInstance().getUniqueId(); + onChanged(); + return this; + } + /** + * string uniqueId = 6; + */ + public Builder setUniqueIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + uniqueId_ = value; + onChanged(); + return this; + } + + private Object seqNum_ = ""; + /** + * string seqNum = 7; + */ + public String getSeqNum() { + Object ref = seqNum_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + seqNum_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string seqNum = 7; + */ + public com.google.protobuf.ByteString + getSeqNumBytes() { + Object ref = seqNum_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + seqNum_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string seqNum = 7; + */ + public Builder setSeqNum( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + seqNum_ = value; + onChanged(); + return this; + } + /** + * string seqNum = 7; + */ + public Builder clearSeqNum() { + + seqNum_ = getDefaultInstance().getSeqNum(); + onChanged(); + return this; + } + /** + * string seqNum = 7; + */ + public Builder setSeqNumBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + seqNum_ = value; + onChanged(); + return this; + } + + private Object tag_ = ""; + /** + * string tag = 8; + */ + public String getTag() { + Object ref = tag_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + tag_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string tag = 8; + */ + public com.google.protobuf.ByteString + getTagBytes() { + Object ref = tag_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + tag_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string tag = 8; + */ + public Builder setTag( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + tag_ = value; + onChanged(); + return this; + } + /** + * string tag = 8; + */ + public Builder clearTag() { + + tag_ = getDefaultInstance().getTag(); + onChanged(); + return this; + } + /** + * string tag = 8; + */ + public Builder setTagBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + tag_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.MapField< + String, String> properties_; + private com.google.protobuf.MapField + internalGetProperties() { + if (properties_ == null) { + return com.google.protobuf.MapField.emptyMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + return properties_; + } + private com.google.protobuf.MapField + internalGetMutableProperties() { + onChanged();; + if (properties_ == null) { + properties_ = com.google.protobuf.MapField.newMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + if (!properties_.isMutable()) { + properties_ = properties_.copy(); + } + return properties_; + } + + public int getPropertiesCount() { + return internalGetProperties().getMap().size(); + } + /** + * map<string, string> properties = 9; + */ + + public boolean containsProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetProperties().getMap().containsKey(key); + } + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + public java.util.Map getProperties() { + return getPropertiesMap(); + } + /** + * map<string, string> properties = 9; + */ + + public java.util.Map getPropertiesMap() { + return internalGetProperties().getMap(); + } + /** + * map<string, string> properties = 9; + */ + + public String getPropertiesOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> properties = 9; + */ + + public String getPropertiesOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + public Builder clearProperties() { + internalGetMutableProperties().getMutableMap() + .clear(); + return this; + } + /** + * map<string, string> properties = 9; + */ + + public Builder removeProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + internalGetMutableProperties().getMutableMap() + .remove(key); + return this; + } + /** + * Use alternate mutation accessors instead. + */ + @Deprecated + public java.util.Map + getMutableProperties() { + return internalGetMutableProperties().getMutableMap(); + } + /** + * map<string, string> properties = 9; + */ + public Builder putProperties( + String key, + String value) { + if (key == null) { throw new NullPointerException(); } + if (value == null) { throw new NullPointerException(); } + internalGetMutableProperties().getMutableMap() + .put(key, value); + return this; + } + /** + * map<string, string> properties = 9; + */ + + public Builder putAllProperties( + java.util.Map values) { + internalGetMutableProperties().getMutableMap() + .putAll(values); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.SimpleMessage) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.SimpleMessage) + private static final SimpleMessage DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new SimpleMessage(); + } + + public static SimpleMessage getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public SimpleMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SimpleMessage(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public SimpleMessage getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessageOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessageOrBuilder.java new file mode 100644 index 0000000000..dfda9c63ae --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessageOrBuilder.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +@SuppressWarnings({"all"}) +public interface SimpleMessageOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.SimpleMessage) + com.google.protobuf.MessageOrBuilder { + + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + boolean hasHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeader getHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeaderOrBuilder getHeaderOrBuilder(); + + /** + * string producerGroup = 2; + */ + String getProducerGroup(); + /** + * string producerGroup = 2; + */ + com.google.protobuf.ByteString + getProducerGroupBytes(); + + /** + * string topic = 3; + */ + String getTopic(); + /** + * string topic = 3; + */ + com.google.protobuf.ByteString + getTopicBytes(); + + /** + * string content = 4; + */ + String getContent(); + /** + * string content = 4; + */ + com.google.protobuf.ByteString + getContentBytes(); + + /** + * string ttl = 5; + */ + String getTtl(); + /** + * string ttl = 5; + */ + com.google.protobuf.ByteString + getTtlBytes(); + + /** + * string uniqueId = 6; + */ + String getUniqueId(); + /** + * string uniqueId = 6; + */ + com.google.protobuf.ByteString + getUniqueIdBytes(); + + /** + * string seqNum = 7; + */ + String getSeqNum(); + /** + * string seqNum = 7; + */ + com.google.protobuf.ByteString + getSeqNumBytes(); + + /** + * string tag = 8; + */ + String getTag(); + /** + * string tag = 8; + */ + com.google.protobuf.ByteString + getTagBytes(); + + /** + * map<string, string> properties = 9; + */ + int getPropertiesCount(); + /** + * map<string, string> properties = 9; + */ + boolean containsProperties( + String key); + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + java.util.Map + getProperties(); + /** + * map<string, string> properties = 9; + */ + java.util.Map + getPropertiesMap(); + /** + * map<string, string> properties = 9; + */ + + String getPropertiesOrDefault( + String key, + String defaultValue); + /** + * map<string, string> properties = 9; + */ + + String getPropertiesOrThrow( + String key); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Subscription.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Subscription.java new file mode 100644 index 0000000000..9fd70864c6 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Subscription.java @@ -0,0 +1,3934 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +/** + * Protobuf type {@code eventmesh.common.protocol.grpc.Subscription} + */ +@SuppressWarnings({"all"}) +public final class Subscription extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.Subscription) + SubscriptionOrBuilder { +private static final long serialVersionUID = 0L; + // Use Subscription.newBuilder() to construct. + private Subscription(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Subscription() { + consumerGroup_ = ""; + subscriptionItems_ = java.util.Collections.emptyList(); + url_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Subscription( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + RequestHeader.Builder subBuilder = null; + if (header_ != null) { + subBuilder = header_.toBuilder(); + } + header_ = input.readMessage(RequestHeader.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(header_); + header_ = subBuilder.buildPartial(); + } + + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + consumerGroup_ = s; + break; + } + case 26: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + subscriptionItems_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000004; + } + subscriptionItems_.add( + input.readMessage(SubscriptionItem.parser(), extensionRegistry)); + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + url_ = s; + break; + } + case 42: { + Reply.Builder subBuilder = null; + if (reply_ != null) { + subBuilder = reply_.toBuilder(); + } + reply_ = input.readMessage(Reply.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(reply_); + reply_ = subBuilder.buildPartial(); + } + + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + subscriptionItems_ = java.util.Collections.unmodifiableList(subscriptionItems_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Subscription.class, Builder.class); + } + + public interface SubscriptionItemOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.Subscription.SubscriptionItem) + com.google.protobuf.MessageOrBuilder { + + /** + * string topic = 1; + */ + String getTopic(); + /** + * string topic = 1; + */ + com.google.protobuf.ByteString + getTopicBytes(); + + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + int getModeValue(); + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + SubscriptionItem.SubscriptionMode getMode(); + + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + int getTypeValue(); + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + SubscriptionItem.SubscriptionType getType(); + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Subscription.SubscriptionItem} + */ + public static final class SubscriptionItem extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.Subscription.SubscriptionItem) + SubscriptionItemOrBuilder { + private static final long serialVersionUID = 0L; + // Use SubscriptionItem.newBuilder() to construct. + private SubscriptionItem(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private SubscriptionItem() { + topic_ = ""; + mode_ = 0; + type_ = 0; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SubscriptionItem( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + String s = input.readStringRequireUtf8(); + + topic_ = s; + break; + } + case 16: { + int rawValue = input.readEnum(); + + mode_ = rawValue; + break; + } + case 24: { + int rawValue = input.readEnum(); + + type_ = rawValue; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_fieldAccessorTable + .ensureFieldAccessorsInitialized( + SubscriptionItem.class, Builder.class); + } + + /** + * Protobuf enum {@code eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode} + */ + public enum SubscriptionMode + implements com.google.protobuf.ProtocolMessageEnum { + /** + * CLUSTERING = 0; + */ + CLUSTERING(0), + /** + * BROADCASTING = 1; + */ + BROADCASTING(1), + UNRECOGNIZED(-1), + ; + + /** + * CLUSTERING = 0; + */ + public static final int CLUSTERING_VALUE = 0; + /** + * BROADCASTING = 1; + */ + public static final int BROADCASTING_VALUE = 1; + + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @deprecated Use {@link #forNumber(int)} instead. + */ + @Deprecated + public static SubscriptionMode valueOf(int value) { + return forNumber(value); + } + + public static SubscriptionMode forNumber(int value) { + switch (value) { + case 0: return CLUSTERING; + case 1: return BROADCASTING; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + SubscriptionMode> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public SubscriptionMode findValueByNumber(int number) { + return SubscriptionMode.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return SubscriptionItem.getDescriptor().getEnumTypes().get(0); + } + + private static final SubscriptionMode[] VALUES = values(); + + public static SubscriptionMode valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private SubscriptionMode(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode) + } + + /** + * Protobuf enum {@code eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType} + */ + public enum SubscriptionType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * ASYNC = 0; + */ + ASYNC(0), + /** + * SYNC = 1; + */ + SYNC(1), + UNRECOGNIZED(-1), + ; + + /** + * ASYNC = 0; + */ + public static final int ASYNC_VALUE = 0; + /** + * SYNC = 1; + */ + public static final int SYNC_VALUE = 1; + + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @deprecated Use {@link #forNumber(int)} instead. + */ + @Deprecated + public static SubscriptionType valueOf(int value) { + return forNumber(value); + } + + public static SubscriptionType forNumber(int value) { + switch (value) { + case 0: return ASYNC; + case 1: return SYNC; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + SubscriptionType> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public SubscriptionType findValueByNumber(int number) { + return SubscriptionType.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return SubscriptionItem.getDescriptor().getEnumTypes().get(1); + } + + private static final SubscriptionType[] VALUES = values(); + + public static SubscriptionType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private SubscriptionType(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType) + } + + public static final int TOPIC_FIELD_NUMBER = 1; + private volatile Object topic_; + /** + * string topic = 1; + */ + public String getTopic() { + Object ref = topic_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } + } + /** + * string topic = 1; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int MODE_FIELD_NUMBER = 2; + private int mode_; + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + public int getModeValue() { + return mode_; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + public SubscriptionMode getMode() { + SubscriptionMode result = SubscriptionMode.valueOf(mode_); + return result == null ? SubscriptionMode.UNRECOGNIZED : result; + } + + public static final int TYPE_FIELD_NUMBER = 3; + private int type_; + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + public int getTypeValue() { + return type_; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + public SubscriptionType getType() { + SubscriptionType result = SubscriptionType.valueOf(type_); + return result == null ? SubscriptionType.UNRECOGNIZED : result; + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getTopicBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, topic_); + } + if (mode_ != SubscriptionMode.CLUSTERING.getNumber()) { + output.writeEnum(2, mode_); + } + if (type_ != SubscriptionType.ASYNC.getNumber()) { + output.writeEnum(3, type_); + } + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getTopicBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, topic_); + } + if (mode_ != SubscriptionMode.CLUSTERING.getNumber()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, mode_); + } + if (type_ != SubscriptionType.ASYNC.getNumber()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(3, type_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SubscriptionItem)) { + return super.equals(obj); + } + SubscriptionItem other = (SubscriptionItem) obj; + + boolean result = true; + result = result && getTopic() + .equals(other.getTopic()); + result = result && mode_ == other.mode_; + result = result && type_ == other.type_; + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + TOPIC_FIELD_NUMBER; + hash = (53 * hash) + getTopic().hashCode(); + hash = (37 * hash) + MODE_FIELD_NUMBER; + hash = (53 * hash) + mode_; + hash = (37 * hash) + TYPE_FIELD_NUMBER; + hash = (53 * hash) + type_; + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static SubscriptionItem parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static SubscriptionItem parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static SubscriptionItem parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static SubscriptionItem parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static SubscriptionItem parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static SubscriptionItem parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static SubscriptionItem parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static SubscriptionItem parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static SubscriptionItem parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static SubscriptionItem parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static SubscriptionItem parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static SubscriptionItem parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(SubscriptionItem prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Subscription.SubscriptionItem} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.Subscription.SubscriptionItem) + SubscriptionItemOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_fieldAccessorTable + .ensureFieldAccessorsInitialized( + SubscriptionItem.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + topic_ = ""; + + mode_ = 0; + + type_ = 0; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_SubscriptionItem_descriptor; + } + + public SubscriptionItem getDefaultInstanceForType() { + return SubscriptionItem.getDefaultInstance(); + } + + public SubscriptionItem build() { + SubscriptionItem result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public SubscriptionItem buildPartial() { + SubscriptionItem result = new SubscriptionItem(this); + result.topic_ = topic_; + result.mode_ = mode_; + result.type_ = type_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof SubscriptionItem) { + return mergeFrom((SubscriptionItem)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(SubscriptionItem other) { + if (other == SubscriptionItem.getDefaultInstance()) return this; + if (!other.getTopic().isEmpty()) { + topic_ = other.topic_; + onChanged(); + } + if (other.mode_ != 0) { + setModeValue(other.getModeValue()); + } + if (other.type_ != 0) { + setTypeValue(other.getTypeValue()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + SubscriptionItem parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (SubscriptionItem) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private Object topic_ = ""; + /** + * string topic = 1; + */ + public String getTopic() { + Object ref = topic_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string topic = 1; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string topic = 1; + */ + public Builder setTopic( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + topic_ = value; + onChanged(); + return this; + } + /** + * string topic = 1; + */ + public Builder clearTopic() { + + topic_ = getDefaultInstance().getTopic(); + onChanged(); + return this; + } + /** + * string topic = 1; + */ + public Builder setTopicBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + topic_ = value; + onChanged(); + return this; + } + + private int mode_ = 0; + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + public int getModeValue() { + return mode_; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + public Builder setModeValue(int value) { + mode_ = value; + onChanged(); + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + public SubscriptionMode getMode() { + SubscriptionMode result = SubscriptionMode.valueOf(mode_); + return result == null ? SubscriptionMode.UNRECOGNIZED : result; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + public Builder setMode(SubscriptionMode value) { + if (value == null) { + throw new NullPointerException(); + } + + mode_ = value.getNumber(); + onChanged(); + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode mode = 2; + */ + public Builder clearMode() { + + mode_ = 0; + onChanged(); + return this; + } + + private int type_ = 0; + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + public int getTypeValue() { + return type_; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + public Builder setTypeValue(int value) { + type_ = value; + onChanged(); + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + public SubscriptionType getType() { + SubscriptionType result = SubscriptionType.valueOf(type_); + return result == null ? SubscriptionType.UNRECOGNIZED : result; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + public Builder setType(SubscriptionType value) { + if (value == null) { + throw new NullPointerException(); + } + + type_ = value.getNumber(); + onChanged(); + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType type = 3; + */ + public Builder clearType() { + + type_ = 0; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.Subscription.SubscriptionItem) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.Subscription.SubscriptionItem) + private static final SubscriptionItem DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new SubscriptionItem(); + } + + public static SubscriptionItem getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public SubscriptionItem parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SubscriptionItem(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public SubscriptionItem getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.Subscription.Reply) + com.google.protobuf.MessageOrBuilder { + + /** + * string producerGroup = 1; + */ + String getProducerGroup(); + /** + * string producerGroup = 1; + */ + com.google.protobuf.ByteString + getProducerGroupBytes(); + + /** + * string topic = 2; + */ + String getTopic(); + /** + * string topic = 2; + */ + com.google.protobuf.ByteString + getTopicBytes(); + + /** + * string content = 3; + */ + String getContent(); + /** + * string content = 3; + */ + com.google.protobuf.ByteString + getContentBytes(); + + /** + * string ttl = 4; + */ + String getTtl(); + /** + * string ttl = 4; + */ + com.google.protobuf.ByteString + getTtlBytes(); + + /** + * string uniqueId = 5; + */ + String getUniqueId(); + /** + * string uniqueId = 5; + */ + com.google.protobuf.ByteString + getUniqueIdBytes(); + + /** + * string seqNum = 6; + */ + String getSeqNum(); + /** + * string seqNum = 6; + */ + com.google.protobuf.ByteString + getSeqNumBytes(); + + /** + * string tag = 7; + */ + String getTag(); + /** + * string tag = 7; + */ + com.google.protobuf.ByteString + getTagBytes(); + + /** + * map<string, string> properties = 8; + */ + int getPropertiesCount(); + /** + * map<string, string> properties = 8; + */ + boolean containsProperties( + String key); + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + java.util.Map + getProperties(); + /** + * map<string, string> properties = 8; + */ + java.util.Map + getPropertiesMap(); + /** + * map<string, string> properties = 8; + */ + + String getPropertiesOrDefault( + String key, + String defaultValue); + /** + * map<string, string> properties = 8; + */ + + String getPropertiesOrThrow( + String key); + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Subscription.Reply} + */ + public static final class Reply extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:eventmesh.common.protocol.grpc.Subscription.Reply) + ReplyOrBuilder { + private static final long serialVersionUID = 0L; + // Use Reply.newBuilder() to construct. + private Reply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Reply() { + producerGroup_ = ""; + topic_ = ""; + content_ = ""; + ttl_ = ""; + uniqueId_ = ""; + seqNum_ = ""; + tag_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Reply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + String s = input.readStringRequireUtf8(); + + producerGroup_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + topic_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + content_ = s; + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + ttl_ = s; + break; + } + case 42: { + String s = input.readStringRequireUtf8(); + + uniqueId_ = s; + break; + } + case 50: { + String s = input.readStringRequireUtf8(); + + seqNum_ = s; + break; + } + case 58: { + String s = input.readStringRequireUtf8(); + + tag_ = s; + break; + } + case 66: { + if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + properties_ = com.google.protobuf.MapField.newMapField( + PropertiesDefaultEntryHolder.defaultEntry); + mutable_bitField0_ |= 0x00000080; + } + com.google.protobuf.MapEntry + properties__ = input.readMessage( + PropertiesDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); + properties_.getMutableMap().put( + properties__.getKey(), properties__.getValue()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 8: + return internalGetProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Reply.class, Builder.class); + } + + private int bitField0_; + public static final int PRODUCERGROUP_FIELD_NUMBER = 1; + private volatile Object producerGroup_; + /** + * string producerGroup = 1; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } + } + /** + * string producerGroup = 1; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TOPIC_FIELD_NUMBER = 2; + private volatile Object topic_; + /** + * string topic = 2; + */ + public String getTopic() { + Object ref = topic_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } + } + /** + * string topic = 2; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CONTENT_FIELD_NUMBER = 3; + private volatile Object content_; + /** + * string content = 3; + */ + public String getContent() { + Object ref = content_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + content_ = s; + return s; + } + } + /** + * string content = 3; + */ + public com.google.protobuf.ByteString + getContentBytes() { + Object ref = content_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TTL_FIELD_NUMBER = 4; + private volatile Object ttl_; + /** + * string ttl = 4; + */ + public String getTtl() { + Object ref = ttl_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ttl_ = s; + return s; + } + } + /** + * string ttl = 4; + */ + public com.google.protobuf.ByteString + getTtlBytes() { + Object ref = ttl_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ttl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int UNIQUEID_FIELD_NUMBER = 5; + private volatile Object uniqueId_; + /** + * string uniqueId = 5; + */ + public String getUniqueId() { + Object ref = uniqueId_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + uniqueId_ = s; + return s; + } + } + /** + * string uniqueId = 5; + */ + public com.google.protobuf.ByteString + getUniqueIdBytes() { + Object ref = uniqueId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + uniqueId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SEQNUM_FIELD_NUMBER = 6; + private volatile Object seqNum_; + /** + * string seqNum = 6; + */ + public String getSeqNum() { + Object ref = seqNum_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + seqNum_ = s; + return s; + } + } + /** + * string seqNum = 6; + */ + public com.google.protobuf.ByteString + getSeqNumBytes() { + Object ref = seqNum_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + seqNum_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TAG_FIELD_NUMBER = 7; + private volatile Object tag_; + /** + * string tag = 7; + */ + public String getTag() { + Object ref = tag_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + tag_ = s; + return s; + } + } + /** + * string tag = 7; + */ + public com.google.protobuf.ByteString + getTagBytes() { + Object ref = tag_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + tag_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PROPERTIES_FIELD_NUMBER = 8; + private static final class PropertiesDefaultEntryHolder { + static final com.google.protobuf.MapEntry< + String, String> defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_PropertiesEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.STRING, + ""); + } + private com.google.protobuf.MapField< + String, String> properties_; + private com.google.protobuf.MapField + internalGetProperties() { + if (properties_ == null) { + return com.google.protobuf.MapField.emptyMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + return properties_; + } + + public int getPropertiesCount() { + return internalGetProperties().getMap().size(); + } + /** + * map<string, string> properties = 8; + */ + + public boolean containsProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetProperties().getMap().containsKey(key); + } + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + public java.util.Map getProperties() { + return getPropertiesMap(); + } + /** + * map<string, string> properties = 8; + */ + + public java.util.Map getPropertiesMap() { + return internalGetProperties().getMap(); + } + /** + * map<string, string> properties = 8; + */ + + public String getPropertiesOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> properties = 8; + */ + + public String getPropertiesOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getProducerGroupBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, producerGroup_); + } + if (!getTopicBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, topic_); + } + if (!getContentBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, content_); + } + if (!getTtlBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, ttl_); + } + if (!getUniqueIdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, uniqueId_); + } + if (!getSeqNumBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, seqNum_); + } + if (!getTagBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 7, tag_); + } + com.google.protobuf.GeneratedMessageV3 + .serializeStringMapTo( + output, + internalGetProperties(), + PropertiesDefaultEntryHolder.defaultEntry, + 8); + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getProducerGroupBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, producerGroup_); + } + if (!getTopicBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, topic_); + } + if (!getContentBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, content_); + } + if (!getTtlBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, ttl_); + } + if (!getUniqueIdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, uniqueId_); + } + if (!getSeqNumBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, seqNum_); + } + if (!getTagBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, tag_); + } + for (java.util.Map.Entry entry + : internalGetProperties().getMap().entrySet()) { + com.google.protobuf.MapEntry + properties__ = PropertiesDefaultEntryHolder.defaultEntry.newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(8, properties__); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Reply)) { + return super.equals(obj); + } + Reply other = (Reply) obj; + + boolean result = true; + result = result && getProducerGroup() + .equals(other.getProducerGroup()); + result = result && getTopic() + .equals(other.getTopic()); + result = result && getContent() + .equals(other.getContent()); + result = result && getTtl() + .equals(other.getTtl()); + result = result && getUniqueId() + .equals(other.getUniqueId()); + result = result && getSeqNum() + .equals(other.getSeqNum()); + result = result && getTag() + .equals(other.getTag()); + result = result && internalGetProperties().equals( + other.internalGetProperties()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + PRODUCERGROUP_FIELD_NUMBER; + hash = (53 * hash) + getProducerGroup().hashCode(); + hash = (37 * hash) + TOPIC_FIELD_NUMBER; + hash = (53 * hash) + getTopic().hashCode(); + hash = (37 * hash) + CONTENT_FIELD_NUMBER; + hash = (53 * hash) + getContent().hashCode(); + hash = (37 * hash) + TTL_FIELD_NUMBER; + hash = (53 * hash) + getTtl().hashCode(); + hash = (37 * hash) + UNIQUEID_FIELD_NUMBER; + hash = (53 * hash) + getUniqueId().hashCode(); + hash = (37 * hash) + SEQNUM_FIELD_NUMBER; + hash = (53 * hash) + getSeqNum().hashCode(); + hash = (37 * hash) + TAG_FIELD_NUMBER; + hash = (53 * hash) + getTag().hashCode(); + if (!internalGetProperties().getMap().isEmpty()) { + hash = (37 * hash) + PROPERTIES_FIELD_NUMBER; + hash = (53 * hash) + internalGetProperties().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static Reply parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Reply parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Reply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Reply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Reply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Reply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Reply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Reply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static Reply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static Reply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static Reply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Reply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(Reply prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Subscription.Reply} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.Subscription.Reply) + ReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 8: + return internalGetProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMutableMapField( + int number) { + switch (number) { + case 8: + return internalGetMutableProperties(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Reply.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.Subscription.Reply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + producerGroup_ = ""; + + topic_ = ""; + + content_ = ""; + + ttl_ = ""; + + uniqueId_ = ""; + + seqNum_ = ""; + + tag_ = ""; + + internalGetMutableProperties().clear(); + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_Reply_descriptor; + } + + public Reply getDefaultInstanceForType() { + return Reply.getDefaultInstance(); + } + + public Reply build() { + Reply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public Reply buildPartial() { + Reply result = new Reply(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + result.producerGroup_ = producerGroup_; + result.topic_ = topic_; + result.content_ = content_; + result.ttl_ = ttl_; + result.uniqueId_ = uniqueId_; + result.seqNum_ = seqNum_; + result.tag_ = tag_; + result.properties_ = internalGetProperties(); + result.properties_.makeImmutable(); + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof Reply) { + return mergeFrom((Reply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(Reply other) { + if (other == Reply.getDefaultInstance()) return this; + if (!other.getProducerGroup().isEmpty()) { + producerGroup_ = other.producerGroup_; + onChanged(); + } + if (!other.getTopic().isEmpty()) { + topic_ = other.topic_; + onChanged(); + } + if (!other.getContent().isEmpty()) { + content_ = other.content_; + onChanged(); + } + if (!other.getTtl().isEmpty()) { + ttl_ = other.ttl_; + onChanged(); + } + if (!other.getUniqueId().isEmpty()) { + uniqueId_ = other.uniqueId_; + onChanged(); + } + if (!other.getSeqNum().isEmpty()) { + seqNum_ = other.seqNum_; + onChanged(); + } + if (!other.getTag().isEmpty()) { + tag_ = other.tag_; + onChanged(); + } + internalGetMutableProperties().mergeFrom( + other.internalGetProperties()); + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Reply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (Reply) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private Object producerGroup_ = ""; + /** + * string producerGroup = 1; + */ + public String getProducerGroup() { + Object ref = producerGroup_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + producerGroup_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string producerGroup = 1; + */ + public com.google.protobuf.ByteString + getProducerGroupBytes() { + Object ref = producerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + producerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string producerGroup = 1; + */ + public Builder setProducerGroup( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + producerGroup_ = value; + onChanged(); + return this; + } + /** + * string producerGroup = 1; + */ + public Builder clearProducerGroup() { + + producerGroup_ = getDefaultInstance().getProducerGroup(); + onChanged(); + return this; + } + /** + * string producerGroup = 1; + */ + public Builder setProducerGroupBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + producerGroup_ = value; + onChanged(); + return this; + } + + private Object topic_ = ""; + /** + * string topic = 2; + */ + public String getTopic() { + Object ref = topic_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + topic_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string topic = 2; + */ + public com.google.protobuf.ByteString + getTopicBytes() { + Object ref = topic_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + topic_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string topic = 2; + */ + public Builder setTopic( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + topic_ = value; + onChanged(); + return this; + } + /** + * string topic = 2; + */ + public Builder clearTopic() { + + topic_ = getDefaultInstance().getTopic(); + onChanged(); + return this; + } + /** + * string topic = 2; + */ + public Builder setTopicBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + topic_ = value; + onChanged(); + return this; + } + + private Object content_ = ""; + /** + * string content = 3; + */ + public String getContent() { + Object ref = content_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + content_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string content = 3; + */ + public com.google.protobuf.ByteString + getContentBytes() { + Object ref = content_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + content_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string content = 3; + */ + public Builder setContent( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + content_ = value; + onChanged(); + return this; + } + /** + * string content = 3; + */ + public Builder clearContent() { + + content_ = getDefaultInstance().getContent(); + onChanged(); + return this; + } + /** + * string content = 3; + */ + public Builder setContentBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + content_ = value; + onChanged(); + return this; + } + + private Object ttl_ = ""; + /** + * string ttl = 4; + */ + public String getTtl() { + Object ref = ttl_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + ttl_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string ttl = 4; + */ + public com.google.protobuf.ByteString + getTtlBytes() { + Object ref = ttl_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + ttl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string ttl = 4; + */ + public Builder setTtl( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + ttl_ = value; + onChanged(); + return this; + } + /** + * string ttl = 4; + */ + public Builder clearTtl() { + + ttl_ = getDefaultInstance().getTtl(); + onChanged(); + return this; + } + /** + * string ttl = 4; + */ + public Builder setTtlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + ttl_ = value; + onChanged(); + return this; + } + + private Object uniqueId_ = ""; + /** + * string uniqueId = 5; + */ + public String getUniqueId() { + Object ref = uniqueId_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + uniqueId_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string uniqueId = 5; + */ + public com.google.protobuf.ByteString + getUniqueIdBytes() { + Object ref = uniqueId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + uniqueId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string uniqueId = 5; + */ + public Builder setUniqueId( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + uniqueId_ = value; + onChanged(); + return this; + } + /** + * string uniqueId = 5; + */ + public Builder clearUniqueId() { + + uniqueId_ = getDefaultInstance().getUniqueId(); + onChanged(); + return this; + } + /** + * string uniqueId = 5; + */ + public Builder setUniqueIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + uniqueId_ = value; + onChanged(); + return this; + } + + private Object seqNum_ = ""; + /** + * string seqNum = 6; + */ + public String getSeqNum() { + Object ref = seqNum_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + seqNum_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string seqNum = 6; + */ + public com.google.protobuf.ByteString + getSeqNumBytes() { + Object ref = seqNum_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + seqNum_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string seqNum = 6; + */ + public Builder setSeqNum( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + seqNum_ = value; + onChanged(); + return this; + } + /** + * string seqNum = 6; + */ + public Builder clearSeqNum() { + + seqNum_ = getDefaultInstance().getSeqNum(); + onChanged(); + return this; + } + /** + * string seqNum = 6; + */ + public Builder setSeqNumBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + seqNum_ = value; + onChanged(); + return this; + } + + private Object tag_ = ""; + /** + * string tag = 7; + */ + public String getTag() { + Object ref = tag_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + tag_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string tag = 7; + */ + public com.google.protobuf.ByteString + getTagBytes() { + Object ref = tag_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + tag_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string tag = 7; + */ + public Builder setTag( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + tag_ = value; + onChanged(); + return this; + } + /** + * string tag = 7; + */ + public Builder clearTag() { + + tag_ = getDefaultInstance().getTag(); + onChanged(); + return this; + } + /** + * string tag = 7; + */ + public Builder setTagBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + tag_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.MapField< + String, String> properties_; + private com.google.protobuf.MapField + internalGetProperties() { + if (properties_ == null) { + return com.google.protobuf.MapField.emptyMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + return properties_; + } + private com.google.protobuf.MapField + internalGetMutableProperties() { + onChanged();; + if (properties_ == null) { + properties_ = com.google.protobuf.MapField.newMapField( + PropertiesDefaultEntryHolder.defaultEntry); + } + if (!properties_.isMutable()) { + properties_ = properties_.copy(); + } + return properties_; + } + + public int getPropertiesCount() { + return internalGetProperties().getMap().size(); + } + /** + * map<string, string> properties = 8; + */ + + public boolean containsProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetProperties().getMap().containsKey(key); + } + /** + * Use {@link #getPropertiesMap()} instead. + */ + @Deprecated + public java.util.Map getProperties() { + return getPropertiesMap(); + } + /** + * map<string, string> properties = 8; + */ + + public java.util.Map getPropertiesMap() { + return internalGetProperties().getMap(); + } + /** + * map<string, string> properties = 8; + */ + + public String getPropertiesOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> properties = 8; + */ + + public String getPropertiesOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetProperties().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + public Builder clearProperties() { + internalGetMutableProperties().getMutableMap() + .clear(); + return this; + } + /** + * map<string, string> properties = 8; + */ + + public Builder removeProperties( + String key) { + if (key == null) { throw new NullPointerException(); } + internalGetMutableProperties().getMutableMap() + .remove(key); + return this; + } + /** + * Use alternate mutation accessors instead. + */ + @Deprecated + public java.util.Map + getMutableProperties() { + return internalGetMutableProperties().getMutableMap(); + } + /** + * map<string, string> properties = 8; + */ + public Builder putProperties( + String key, + String value) { + if (key == null) { throw new NullPointerException(); } + if (value == null) { throw new NullPointerException(); } + internalGetMutableProperties().getMutableMap() + .put(key, value); + return this; + } + /** + * map<string, string> properties = 8; + */ + + public Builder putAllProperties( + java.util.Map values) { + internalGetMutableProperties().getMutableMap() + .putAll(values); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.Subscription.Reply) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.Subscription.Reply) + private static final Reply DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new Reply(); + } + + public static Reply getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public Reply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Reply(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public Reply getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private int bitField0_; + public static final int HEADER_FIELD_NUMBER = 1; + private RequestHeader header_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + return getHeader(); + } + + public static final int CONSUMERGROUP_FIELD_NUMBER = 2; + private volatile Object consumerGroup_; + /** + * string consumerGroup = 2; + */ + public String getConsumerGroup() { + Object ref = consumerGroup_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + consumerGroup_ = s; + return s; + } + } + /** + * string consumerGroup = 2; + */ + public com.google.protobuf.ByteString + getConsumerGroupBytes() { + Object ref = consumerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + consumerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SUBSCRIPTIONITEMS_FIELD_NUMBER = 3; + private java.util.List subscriptionItems_; + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public java.util.List getSubscriptionItemsList() { + return subscriptionItems_; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public java.util.List + getSubscriptionItemsOrBuilderList() { + return subscriptionItems_; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public int getSubscriptionItemsCount() { + return subscriptionItems_.size(); + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public SubscriptionItem getSubscriptionItems(int index) { + return subscriptionItems_.get(index); + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public SubscriptionItemOrBuilder getSubscriptionItemsOrBuilder( + int index) { + return subscriptionItems_.get(index); + } + + public static final int URL_FIELD_NUMBER = 4; + private volatile Object url_; + /** + * string url = 4; + */ + public String getUrl() { + Object ref = url_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + url_ = s; + return s; + } + } + /** + * string url = 4; + */ + public com.google.protobuf.ByteString + getUrlBytes() { + Object ref = url_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int REPLY_FIELD_NUMBER = 5; + private Reply reply_; + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public boolean hasReply() { + return reply_ != null; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public Reply getReply() { + return reply_ == null ? Reply.getDefaultInstance() : reply_; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public ReplyOrBuilder getReplyOrBuilder() { + return getReply(); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (header_ != null) { + output.writeMessage(1, getHeader()); + } + if (!getConsumerGroupBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, consumerGroup_); + } + for (int i = 0; i < subscriptionItems_.size(); i++) { + output.writeMessage(3, subscriptionItems_.get(i)); + } + if (!getUrlBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, url_); + } + if (reply_ != null) { + output.writeMessage(5, getReply()); + } + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (header_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getHeader()); + } + if (!getConsumerGroupBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, consumerGroup_); + } + for (int i = 0; i < subscriptionItems_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, subscriptionItems_.get(i)); + } + if (!getUrlBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, url_); + } + if (reply_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, getReply()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Subscription)) { + return super.equals(obj); + } + Subscription other = (Subscription) obj; + + boolean result = true; + result = result && (hasHeader() == other.hasHeader()); + if (hasHeader()) { + result = result && getHeader() + .equals(other.getHeader()); + } + result = result && getConsumerGroup() + .equals(other.getConsumerGroup()); + result = result && getSubscriptionItemsList() + .equals(other.getSubscriptionItemsList()); + result = result && getUrl() + .equals(other.getUrl()); + result = result && (hasReply() == other.hasReply()); + if (hasReply()) { + result = result && getReply() + .equals(other.getReply()); + } + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasHeader()) { + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + } + hash = (37 * hash) + CONSUMERGROUP_FIELD_NUMBER; + hash = (53 * hash) + getConsumerGroup().hashCode(); + if (getSubscriptionItemsCount() > 0) { + hash = (37 * hash) + SUBSCRIPTIONITEMS_FIELD_NUMBER; + hash = (53 * hash) + getSubscriptionItemsList().hashCode(); + } + hash = (37 * hash) + URL_FIELD_NUMBER; + hash = (53 * hash) + getUrl().hashCode(); + if (hasReply()) { + hash = (37 * hash) + REPLY_FIELD_NUMBER; + hash = (53 * hash) + getReply().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static Subscription parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Subscription parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Subscription parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Subscription parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Subscription parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static Subscription parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static Subscription parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Subscription parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static Subscription parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static Subscription parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static Subscription parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static Subscription parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(Subscription prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code eventmesh.common.protocol.grpc.Subscription} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:eventmesh.common.protocol.grpc.Subscription) + SubscriptionOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor; + } + + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_fieldAccessorTable + .ensureFieldAccessorsInitialized( + Subscription.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.protos.Subscription.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getSubscriptionItemsFieldBuilder(); + } + } + public Builder clear() { + super.clear(); + if (headerBuilder_ == null) { + header_ = null; + } else { + header_ = null; + headerBuilder_ = null; + } + consumerGroup_ = ""; + + if (subscriptionItemsBuilder_ == null) { + subscriptionItems_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + } else { + subscriptionItemsBuilder_.clear(); + } + url_ = ""; + + if (replyBuilder_ == null) { + reply_ = null; + } else { + reply_ = null; + replyBuilder_ = null; + } + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventmeshGrpc.internal_static_eventmesh_common_protocol_grpc_Subscription_descriptor; + } + + public Subscription getDefaultInstanceForType() { + return Subscription.getDefaultInstance(); + } + + public Subscription build() { + Subscription result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public Subscription buildPartial() { + Subscription result = new Subscription(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (headerBuilder_ == null) { + result.header_ = header_; + } else { + result.header_ = headerBuilder_.build(); + } + result.consumerGroup_ = consumerGroup_; + if (subscriptionItemsBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004)) { + subscriptionItems_ = java.util.Collections.unmodifiableList(subscriptionItems_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.subscriptionItems_ = subscriptionItems_; + } else { + result.subscriptionItems_ = subscriptionItemsBuilder_.build(); + } + result.url_ = url_; + if (replyBuilder_ == null) { + result.reply_ = reply_; + } else { + result.reply_ = replyBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof Subscription) { + return mergeFrom((Subscription)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(Subscription other) { + if (other == Subscription.getDefaultInstance()) return this; + if (other.hasHeader()) { + mergeHeader(other.getHeader()); + } + if (!other.getConsumerGroup().isEmpty()) { + consumerGroup_ = other.consumerGroup_; + onChanged(); + } + if (subscriptionItemsBuilder_ == null) { + if (!other.subscriptionItems_.isEmpty()) { + if (subscriptionItems_.isEmpty()) { + subscriptionItems_ = other.subscriptionItems_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.addAll(other.subscriptionItems_); + } + onChanged(); + } + } else { + if (!other.subscriptionItems_.isEmpty()) { + if (subscriptionItemsBuilder_.isEmpty()) { + subscriptionItemsBuilder_.dispose(); + subscriptionItemsBuilder_ = null; + subscriptionItems_ = other.subscriptionItems_; + bitField0_ = (bitField0_ & ~0x00000004); + subscriptionItemsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getSubscriptionItemsFieldBuilder() : null; + } else { + subscriptionItemsBuilder_.addAllMessages(other.subscriptionItems_); + } + } + } + if (!other.getUrl().isEmpty()) { + url_ = other.url_; + onChanged(); + } + if (other.hasReply()) { + mergeReply(other.getReply()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + Subscription parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (Subscription) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private RequestHeader header_ = null; + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> headerBuilder_; + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public boolean hasHeader() { + return headerBuilder_ != null || header_ != null; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader getHeader() { + if (headerBuilder_ == null) { + return header_ == null ? RequestHeader.getDefaultInstance() : header_; + } else { + return headerBuilder_.getMessage(); + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + header_ = value; + onChanged(); + } else { + headerBuilder_.setMessage(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder setHeader( + RequestHeader.Builder builderForValue) { + if (headerBuilder_ == null) { + header_ = builderForValue.build(); + onChanged(); + } else { + headerBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder mergeHeader(RequestHeader value) { + if (headerBuilder_ == null) { + if (header_ != null) { + header_ = + RequestHeader.newBuilder(header_).mergeFrom(value).buildPartial(); + } else { + header_ = value; + } + onChanged(); + } else { + headerBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public Builder clearHeader() { + if (headerBuilder_ == null) { + header_ = null; + onChanged(); + } else { + header_ = null; + headerBuilder_ = null; + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeader.Builder getHeaderBuilder() { + + onChanged(); + return getHeaderFieldBuilder().getBuilder(); + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + public RequestHeaderOrBuilder getHeaderOrBuilder() { + if (headerBuilder_ != null) { + return headerBuilder_.getMessageOrBuilder(); + } else { + return header_ == null ? + RequestHeader.getDefaultInstance() : header_; + } + } + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder> + getHeaderFieldBuilder() { + if (headerBuilder_ == null) { + headerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + RequestHeader, RequestHeader.Builder, RequestHeaderOrBuilder>( + getHeader(), + getParentForChildren(), + isClean()); + header_ = null; + } + return headerBuilder_; + } + + private Object consumerGroup_ = ""; + /** + * string consumerGroup = 2; + */ + public String getConsumerGroup() { + Object ref = consumerGroup_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + consumerGroup_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string consumerGroup = 2; + */ + public com.google.protobuf.ByteString + getConsumerGroupBytes() { + Object ref = consumerGroup_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + consumerGroup_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string consumerGroup = 2; + */ + public Builder setConsumerGroup( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + consumerGroup_ = value; + onChanged(); + return this; + } + /** + * string consumerGroup = 2; + */ + public Builder clearConsumerGroup() { + + consumerGroup_ = getDefaultInstance().getConsumerGroup(); + onChanged(); + return this; + } + /** + * string consumerGroup = 2; + */ + public Builder setConsumerGroupBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + consumerGroup_ = value; + onChanged(); + return this; + } + + private java.util.List subscriptionItems_ = + java.util.Collections.emptyList(); + private void ensureSubscriptionItemsIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + subscriptionItems_ = new java.util.ArrayList(subscriptionItems_); + bitField0_ |= 0x00000004; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + SubscriptionItem, SubscriptionItem.Builder, SubscriptionItemOrBuilder> subscriptionItemsBuilder_; + + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public java.util.List getSubscriptionItemsList() { + if (subscriptionItemsBuilder_ == null) { + return java.util.Collections.unmodifiableList(subscriptionItems_); + } else { + return subscriptionItemsBuilder_.getMessageList(); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public int getSubscriptionItemsCount() { + if (subscriptionItemsBuilder_ == null) { + return subscriptionItems_.size(); + } else { + return subscriptionItemsBuilder_.getCount(); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public SubscriptionItem getSubscriptionItems(int index) { + if (subscriptionItemsBuilder_ == null) { + return subscriptionItems_.get(index); + } else { + return subscriptionItemsBuilder_.getMessage(index); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder setSubscriptionItems( + int index, SubscriptionItem value) { + if (subscriptionItemsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.set(index, value); + onChanged(); + } else { + subscriptionItemsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder setSubscriptionItems( + int index, SubscriptionItem.Builder builderForValue) { + if (subscriptionItemsBuilder_ == null) { + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.set(index, builderForValue.build()); + onChanged(); + } else { + subscriptionItemsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder addSubscriptionItems(SubscriptionItem value) { + if (subscriptionItemsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.add(value); + onChanged(); + } else { + subscriptionItemsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder addSubscriptionItems( + int index, SubscriptionItem value) { + if (subscriptionItemsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.add(index, value); + onChanged(); + } else { + subscriptionItemsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder addSubscriptionItems( + SubscriptionItem.Builder builderForValue) { + if (subscriptionItemsBuilder_ == null) { + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.add(builderForValue.build()); + onChanged(); + } else { + subscriptionItemsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder addSubscriptionItems( + int index, SubscriptionItem.Builder builderForValue) { + if (subscriptionItemsBuilder_ == null) { + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.add(index, builderForValue.build()); + onChanged(); + } else { + subscriptionItemsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder addAllSubscriptionItems( + Iterable values) { + if (subscriptionItemsBuilder_ == null) { + ensureSubscriptionItemsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, subscriptionItems_); + onChanged(); + } else { + subscriptionItemsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder clearSubscriptionItems() { + if (subscriptionItemsBuilder_ == null) { + subscriptionItems_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + } else { + subscriptionItemsBuilder_.clear(); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public Builder removeSubscriptionItems(int index) { + if (subscriptionItemsBuilder_ == null) { + ensureSubscriptionItemsIsMutable(); + subscriptionItems_.remove(index); + onChanged(); + } else { + subscriptionItemsBuilder_.remove(index); + } + return this; + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public SubscriptionItem.Builder getSubscriptionItemsBuilder( + int index) { + return getSubscriptionItemsFieldBuilder().getBuilder(index); + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public SubscriptionItemOrBuilder getSubscriptionItemsOrBuilder( + int index) { + if (subscriptionItemsBuilder_ == null) { + return subscriptionItems_.get(index); } else { + return subscriptionItemsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public java.util.List + getSubscriptionItemsOrBuilderList() { + if (subscriptionItemsBuilder_ != null) { + return subscriptionItemsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(subscriptionItems_); + } + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public SubscriptionItem.Builder addSubscriptionItemsBuilder() { + return getSubscriptionItemsFieldBuilder().addBuilder( + SubscriptionItem.getDefaultInstance()); + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public SubscriptionItem.Builder addSubscriptionItemsBuilder( + int index) { + return getSubscriptionItemsFieldBuilder().addBuilder( + index, SubscriptionItem.getDefaultInstance()); + } + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + public java.util.List + getSubscriptionItemsBuilderList() { + return getSubscriptionItemsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + SubscriptionItem, SubscriptionItem.Builder, SubscriptionItemOrBuilder> + getSubscriptionItemsFieldBuilder() { + if (subscriptionItemsBuilder_ == null) { + subscriptionItemsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + SubscriptionItem, SubscriptionItem.Builder, SubscriptionItemOrBuilder>( + subscriptionItems_, + ((bitField0_ & 0x00000004) == 0x00000004), + getParentForChildren(), + isClean()); + subscriptionItems_ = null; + } + return subscriptionItemsBuilder_; + } + + private Object url_ = ""; + /** + * string url = 4; + */ + public String getUrl() { + Object ref = url_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + url_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string url = 4; + */ + public com.google.protobuf.ByteString + getUrlBytes() { + Object ref = url_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string url = 4; + */ + public Builder setUrl( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + url_ = value; + onChanged(); + return this; + } + /** + * string url = 4; + */ + public Builder clearUrl() { + + url_ = getDefaultInstance().getUrl(); + onChanged(); + return this; + } + /** + * string url = 4; + */ + public Builder setUrlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + url_ = value; + onChanged(); + return this; + } + + private Reply reply_ = null; + private com.google.protobuf.SingleFieldBuilderV3< + Reply, Reply.Builder, ReplyOrBuilder> replyBuilder_; + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public boolean hasReply() { + return replyBuilder_ != null || reply_ != null; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public Reply getReply() { + if (replyBuilder_ == null) { + return reply_ == null ? Reply.getDefaultInstance() : reply_; + } else { + return replyBuilder_.getMessage(); + } + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public Builder setReply(Reply value) { + if (replyBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + reply_ = value; + onChanged(); + } else { + replyBuilder_.setMessage(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public Builder setReply( + Reply.Builder builderForValue) { + if (replyBuilder_ == null) { + reply_ = builderForValue.build(); + onChanged(); + } else { + replyBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public Builder mergeReply(Reply value) { + if (replyBuilder_ == null) { + if (reply_ != null) { + reply_ = + Reply.newBuilder(reply_).mergeFrom(value).buildPartial(); + } else { + reply_ = value; + } + onChanged(); + } else { + replyBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public Builder clearReply() { + if (replyBuilder_ == null) { + reply_ = null; + onChanged(); + } else { + reply_ = null; + replyBuilder_ = null; + } + + return this; + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public Reply.Builder getReplyBuilder() { + + onChanged(); + return getReplyFieldBuilder().getBuilder(); + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + public ReplyOrBuilder getReplyOrBuilder() { + if (replyBuilder_ != null) { + return replyBuilder_.getMessageOrBuilder(); + } else { + return reply_ == null ? + Reply.getDefaultInstance() : reply_; + } + } + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + private com.google.protobuf.SingleFieldBuilderV3< + Reply, Reply.Builder, ReplyOrBuilder> + getReplyFieldBuilder() { + if (replyBuilder_ == null) { + replyBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + Reply, Reply.Builder, ReplyOrBuilder>( + getReply(), + getParentForChildren(), + isClean()); + reply_ = null; + } + return replyBuilder_; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:eventmesh.common.protocol.grpc.Subscription) + } + + // @@protoc_insertion_point(class_scope:eventmesh.common.protocol.grpc.Subscription) + private static final Subscription DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new Subscription(); + } + + public static Subscription getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public Subscription parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Subscription(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public Subscription getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SubscriptionOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SubscriptionOrBuilder.java new file mode 100644 index 0000000000..4adff7d4fc --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SubscriptionOrBuilder.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-client.proto + +package org.apache.eventmesh.common.protocol.grpc.protos; + +@SuppressWarnings({"all"}) +public interface SubscriptionOrBuilder extends + // @@protoc_insertion_point(interface_extends:eventmesh.common.protocol.grpc.Subscription) + com.google.protobuf.MessageOrBuilder { + + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + boolean hasHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeader getHeader(); + /** + * .eventmesh.common.protocol.grpc.RequestHeader header = 1; + */ + RequestHeaderOrBuilder getHeaderOrBuilder(); + + /** + * string consumerGroup = 2; + */ + String getConsumerGroup(); + /** + * string consumerGroup = 2; + */ + com.google.protobuf.ByteString + getConsumerGroupBytes(); + + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + java.util.List + getSubscriptionItemsList(); + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + Subscription.SubscriptionItem getSubscriptionItems(int index); + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + int getSubscriptionItemsCount(); + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + java.util.List + getSubscriptionItemsOrBuilderList(); + /** + * repeated .eventmesh.common.protocol.grpc.Subscription.SubscriptionItem subscriptionItems = 3; + */ + Subscription.SubscriptionItemOrBuilder getSubscriptionItemsOrBuilder( + int index); + + /** + * string url = 4; + */ + String getUrl(); + /** + * string url = 4; + */ + com.google.protobuf.ByteString + getUrlBytes(); + + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + boolean hasReply(); + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + Subscription.Reply getReply(); + /** + * .eventmesh.common.protocol.grpc.Subscription.Reply reply = 5; + */ + Subscription.ReplyOrBuilder getReplyOrBuilder(); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/HttpCommand.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/HttpCommand.java new file mode 100644 index 0000000000..11ad66aa18 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/HttpCommand.java @@ -0,0 +1,249 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.body.BaseResponseBody; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.header.BaseResponseHeader; +import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Optional; +import java.util.concurrent.atomic.AtomicLong; + +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +public class HttpCommand implements ProtocolTransportObject { + + private static final AtomicLong requestId = new AtomicLong(0); + + private long opaque; + + private String requestCode; + + public String httpMethod; + + public String httpVersion; + + public Header header; + + public Body body; + + //Command request time + public long reqTime; + + //Command response time + public long resTime; + + public CmdType cmdType = CmdType.REQ; + + public HttpCommand() { + this(null, null, null); + } + + public HttpCommand(String httpMethod, String httpVersion, String requestCode) { + this.httpMethod = httpMethod; + this.httpVersion = httpVersion; + this.reqTime = System.currentTimeMillis(); + this.requestCode = requestCode; + this.opaque = requestId.incrementAndGet(); + } + + public HttpCommand createHttpCommandResponse(Header header, Body body) { + if (StringUtils.isBlank(requestCode)) { + return null; + } + HttpCommand response = new HttpCommand(this.httpMethod, this.httpVersion, this.requestCode); + response.setOpaque(this.opaque); + response.setReqTime(this.reqTime); + response.setHeader(header); + response.setBody(body); + response.setCmdType(CmdType.RES); + response.setResTime(System.currentTimeMillis()); + return response; + } + + public HttpCommand createHttpCommandResponse(EventMeshRetCode eventMeshRetCode) { + if (StringUtils.isBlank(requestCode)) { + return null; + } + HttpCommand response = new HttpCommand(this.httpMethod, this.httpVersion, this.requestCode); + response.setOpaque(this.opaque); + response.setReqTime(this.reqTime); + BaseResponseHeader baseResponseHeader = new BaseResponseHeader(); + baseResponseHeader.setCode(requestCode); + response.setHeader(baseResponseHeader); + BaseResponseBody baseResponseBody = new BaseResponseBody(); + baseResponseBody.setRetCode(eventMeshRetCode.getRetCode()); + baseResponseBody.setRetMsg(eventMeshRetCode.getErrMsg()); + response.setBody(baseResponseBody); + response.setCmdType(CmdType.RES); + response.setResTime(System.currentTimeMillis()); + return response; + } + + public long getReqTime() { + return reqTime; + } + + public void setReqTime(long reqTime) { + this.reqTime = reqTime; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public long getOpaque() { + return opaque; + } + + public void setOpaque(long opaque) { + this.opaque = opaque; + } + + public CmdType getCmdType() { + return cmdType; + } + + public void setCmdType(CmdType cmdType) { + this.cmdType = cmdType; + } + + public String getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(String httpMethod) { + this.httpMethod = httpMethod; + } + + public String getHttpVersion() { + return httpVersion; + } + + public void setHttpVersion(String httpVersion) { + this.httpVersion = httpVersion; + } + + public String getRequestCode() { + return requestCode; + } + + public void setRequestCode(String requestCode) { + this.requestCode = requestCode; + } + + public Header getHeader() { + return header; + } + + public void setHeader(Header header) { + this.header = header; + } + + public Body getBody() { + return body; + } + + public void setBody(Body body) { + this.body = body; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("httpCommand={") + .append(cmdType).append(",") + .append(httpMethod).append("/").append(httpVersion).append(",") + .append("requestCode=").append(requestCode).append(",") + .append("opaque=").append(opaque).append(","); + + if (cmdType == CmdType.RES) { + sb.append("cost=").append(resTime - reqTime).append(","); + } + + sb.append("header=").append(header).append(",") + .append("body=").append(body) + .append("}"); + + return sb.toString(); + } + + public String abstractDesc() { + StringBuilder sb = new StringBuilder(); + sb.append("httpCommand={") + .append(cmdType).append(",") + .append(httpMethod).append("/").append(httpVersion).append(",") + .append("requestCode=").append(requestCode).append(",") + .append("opaque=").append(opaque).append(","); + + if (cmdType == CmdType.RES) { + sb.append("cost=").append(resTime - reqTime).append(","); + } + + sb.append("header=").append(header).append(",") + .append("bodySize=").append(body.toString().length()).append("}"); + + return sb.toString(); + } + + public String simpleDesc() { + StringBuilder sb = new StringBuilder(); + sb.append("httpCommand={") + .append(cmdType).append(",") + .append(httpMethod).append("/").append(httpVersion).append(",") + .append("requestCode=").append(requestCode).append("}"); + + return sb.toString(); + } + + public DefaultFullHttpResponse httpResponse() throws Exception { + if (cmdType == CmdType.REQ) { + return null; + } + DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, + Unpooled.wrappedBuffer(JsonUtils.serialize(this.getBody()).getBytes(Constants.DEFAULT_CHARSET))); + HttpHeaders headers = response.headers(); + headers.add(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=" + Constants.DEFAULT_CHARSET); + headers.add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); + headers.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); + Optional.of(this.getHeader().toMap()).ifPresent(customerHeader -> customerHeader.forEach(headers::add)); + return response; + } + + public enum CmdType { + REQ, + RES + } +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/HttpEventWrapper.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/HttpEventWrapper.java new file mode 100644 index 0000000000..81a98b579d --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/HttpEventWrapper.java @@ -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 org.apache.eventmesh.common.protocol.http; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + + +public class HttpEventWrapper implements ProtocolTransportObject { + + + private Map headerMap = new HashMap<>(); + + private Map sysHeaderMap = new HashMap<>(); + + private byte[] body; + + private String requestURI; + + public String httpMethod; + + public String httpVersion; + + //Command request time + public long reqTime; + + //Command response time + public long resTime; + + public HttpEventWrapper() { + this(null, null, null); + } + + public HttpEventWrapper(String httpMethod, String httpVersion, String requestURI) { + this.httpMethod = httpMethod; + this.httpVersion = httpVersion; + this.reqTime = System.currentTimeMillis(); + this.requestURI = requestURI; + } + + public HttpEventWrapper createHttpResponse(Map responseHeaderMap, Map responseBodyMap) { + if (StringUtils.isBlank(requestURI)) { + return null; + } + HttpEventWrapper response = new HttpEventWrapper(this.httpMethod, this.httpVersion, this.requestURI); + response.setReqTime(this.reqTime); + response.setHeaderMap(responseHeaderMap); + response.setBody(JsonUtils.serialize(responseBodyMap).getBytes(StandardCharsets.UTF_8)); + response.setResTime(System.currentTimeMillis()); + return response; + } + + public HttpEventWrapper createHttpResponse(EventMeshRetCode eventMeshRetCode) { + if (StringUtils.isBlank(requestURI)) { + return null; + } + HttpEventWrapper response = new HttpEventWrapper(this.httpMethod, this.httpVersion, this.requestURI); + response.setReqTime(this.reqTime); + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put("requestURI", response.requestURI); + response.setHeaderMap(responseHeaderMap); + Map responseBodyMap = new HashMap<>(); + responseBodyMap.put("retCode", eventMeshRetCode.getRetCode()); + responseBodyMap.put("retMessage", eventMeshRetCode.getErrMsg()); + response.setBody(JsonUtils.serialize(responseBodyMap).getBytes(StandardCharsets.UTF_8)); + response.setResTime(System.currentTimeMillis()); + return response; + } + + public long getReqTime() { + return reqTime; + } + + public void setReqTime(long reqTime) { + this.reqTime = reqTime; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public String getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(String httpMethod) { + this.httpMethod = httpMethod; + } + + public String getHttpVersion() { + return httpVersion; + } + + public void setHttpVersion(String httpVersion) { + this.httpVersion = httpVersion; + } + + public String getRequestURI() { + return requestURI; + } + + public void setRequestURI(String requestURI) { + this.requestURI = requestURI; + } + + public Map getHeaderMap() { + return headerMap; + } + + public void setHeaderMap(Map headerMap) { + this.headerMap = headerMap; + } + + public Map getSysHeaderMap() { + return sysHeaderMap; + } + + public void setSysHeaderMap(Map sysHeaderMap) { + this.sysHeaderMap = sysHeaderMap; + } + + public byte[] getBody() { + return body; + } + + public void setBody(byte[] body) { + this.body = body; + } + + public DefaultFullHttpResponse httpResponse() throws Exception { + DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, + Unpooled.wrappedBuffer(this.body)); + HttpHeaders headers = response.headers(); + headers.add(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=" + Constants.DEFAULT_CHARSET); + headers.add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); + headers.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); + Optional.of(this.headerMap).ifPresent(customerHeader -> customerHeader.forEach(headers::add)); + return response; + } + + public void buildSysHeaderForClient() { + // sys attributes + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV, headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.ENV, "env")); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC, headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.IDC, "idc")); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.IP, IPUtils.getLocalAddress())); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.PID, headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.PID, ThreadUtils.getPID())); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS, headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.SYS, "1234")); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.USERNAME, headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.USERNAME, "eventmesh")); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.PASSWD, headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.PASSWD, "pass")); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP, + headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.PRODUCERGROUP, "em-http-producer")); + sysHeaderMap.put(ProtocolKey.ClientInstanceKey.CONSUMERGROUP, + headerMap.getOrDefault(ProtocolKey.ClientInstanceKey.CONSUMERGROUP, "em-http-consumer")); + sysHeaderMap.put(ProtocolKey.PROTOCOL_TYPE, "http"); + sysHeaderMap.put(ProtocolKey.PROTOCOL_DESC, "http"); + } + + public void buildSysHeaderForCE() { + // for cloudevents + sysHeaderMap.put(ProtocolKey.CloudEventsKey.ID, UUID.randomUUID().toString()); + sysHeaderMap.put(ProtocolKey.CloudEventsKey.SOURCE, headerMap.getOrDefault("source", URI.create("/"))); + sysHeaderMap.put(ProtocolKey.CloudEventsKey.TYPE, headerMap.getOrDefault("type", "http_request")); + + String topic = headerMap.getOrDefault("subject", "").toString(); + + if (requestURI.startsWith(RequestURI.PUBLISH.getRequestURI())) { + topic = requestURI.substring(RequestURI.PUBLISH.getRequestURI().length() + 1); + } + + if (StringUtils.isEmpty(topic)) { + topic = "TEST-HTTP-TOPIC"; + } + sysHeaderMap.put(ProtocolKey.CloudEventsKey.SUBJECT, topic); + } + +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/WebhookProtocolTransportObject.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/WebhookProtocolTransportObject.java new file mode 100644 index 0000000000..f47d7851b3 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/WebhookProtocolTransportObject.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; + +import lombok.Builder; +import lombok.Data; + + +@Data +@Builder +public class WebhookProtocolTransportObject implements ProtocolTransportObject { + + private static final long serialVersionUID = -7247618154228090320L; + + private String cloudEventId; + + private String eventType; + + private String cloudEventName; + + private String cloudEventSource; + + private String dataContentType; + + private byte[] body; +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseRequestBody.java new file mode 100644 index 0000000000..a8d77c8e8f --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseRequestBody.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body; + +import java.util.HashMap; +import java.util.Map; + +public class BaseRequestBody extends Body { + + public static BaseRequestBody buildBody(Map bodyParam) { + return new BaseRequestBody(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBody.java new file mode 100644 index 0000000000..aefa711840 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBody.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import java.util.HashMap; +import java.util.Map; + +public class BaseResponseBody extends Body { + + private Integer retCode; + + private String retMsg; + + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/Body.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/Body.java new file mode 100644 index 0000000000..3dc8e6c272 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/Body.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body; + + +import org.apache.eventmesh.common.protocol.http.body.client.HeartbeatRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.RegRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.SubscribeRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.UnRegRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.UnSubscribeRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.PushMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.ReplyMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchV2RequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; + +import java.util.Map; + +public abstract class Body { + + public abstract Map toMap(); + + public static Body buildBody(String requestCode, Map originalMap) throws Exception { + if (String.valueOf(RequestCode.MSG_BATCH_SEND.getRequestCode()).equals(requestCode)) { + return SendMessageBatchRequestBody.buildBody(originalMap); + } + if (String.valueOf(RequestCode.MSG_BATCH_SEND_V2.getRequestCode()).equals(requestCode)) { + return SendMessageBatchV2RequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.MSG_SEND_ASYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.MSG_SEND_SYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.HTTP_PUSH_CLIENT_ASYNC.getRequestCode()).equals(requestCode)) { + return PushMessageRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.HTTP_PUSH_CLIENT_SYNC.getRequestCode()).equals(requestCode)) { + return PushMessageRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.REGISTER.getRequestCode()).equals(requestCode)) { + return RegRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.UNREGISTER.getRequestCode()).equals(requestCode)) { + return UnRegRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.SUBSCRIBE.getRequestCode()).equals(requestCode)) { + return SubscribeRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.UNSUBSCRIBE.getRequestCode()).equals(requestCode)) { + return UnSubscribeRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.HEARTBEAT.getRequestCode()).equals(requestCode)) { + return HeartbeatRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.REPLY_MESSAGE.getRequestCode()).equals(requestCode)) { + return ReplyMessageRequestBody.buildBody(originalMap); + } else if (String.valueOf(RequestCode.ADMIN_SHUTDOWN.getRequestCode()).equals(requestCode)) { + return BaseRequestBody.buildBody(originalMap); + } else { + throw new Exception(); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/HeartbeatRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/HeartbeatRequestBody.java new file mode 100644 index 0000000000..a26ed2d1dd --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/HeartbeatRequestBody.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class HeartbeatRequestBody extends Body { + + public static final String CLIENTTYPE = "clientType"; + public static final String HEARTBEATENTITIES = "heartbeatEntities"; + public static final String CONSUMERGROUP = "consumerGroup"; + + private String consumerGroup; + + private String clientType; + + private List heartbeatEntities; + + public String getClientType() { + return clientType; + } + + public void setClientType(String clientType) { + this.clientType = clientType; + } + + public List getHeartbeatEntities() { + return heartbeatEntities; + } + + public void setHeartbeatEntities(List heartbeatEntities) { + this.heartbeatEntities = heartbeatEntities; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public static HeartbeatRequestBody buildBody(Map bodyParam) { + HeartbeatRequestBody body = new HeartbeatRequestBody(); + body.setClientType(MapUtils.getString(bodyParam, CLIENTTYPE)); + body.setConsumerGroup(MapUtils.getString(bodyParam, CONSUMERGROUP)); + body.setHeartbeatEntities(JsonUtils + .deserialize(MapUtils.getString(bodyParam, HEARTBEATENTITIES), + new TypeReference>() { + })); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(CLIENTTYPE, clientType); + map.put(CONSUMERGROUP, consumerGroup); + map.put(HEARTBEATENTITIES, JsonUtils.serialize(heartbeatEntities)); + return map; + } + + public static class HeartbeatEntity { + public String topic; + public String serviceId; + public String url; + public String instanceId; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("heartbeatEntity={") + .append("topic=").append(topic).append(",") + .append("serviceId=").append(serviceId).append(",") + .append("instanceId=").append(instanceId).append(",") + .append("url=").append(url).append("}"); + return sb.toString(); + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("heartbeatRequestBody={") + .append("consumerGroup=").append(consumerGroup).append(",") + .append("clientType=").append(clientType).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/HeartbeatResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/HeartbeatResponseBody.java new file mode 100644 index 0000000000..c9151dc658 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/HeartbeatResponseBody.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class HeartbeatResponseBody extends Body { + + //return code + private Integer retCode; + + //response message + private String retMsg; + + //response time + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static HeartbeatResponseBody buildBody(Integer retCode, String retMsg) throws Exception { + HeartbeatResponseBody heartbeatResponseBody = new HeartbeatResponseBody(); + heartbeatResponseBody.setRetMsg(retMsg); + heartbeatResponseBody.setResTime(System.currentTimeMillis()); + heartbeatResponseBody.setRetCode(retCode); + return heartbeatResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("heartbeatResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/RegRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/RegRequestBody.java new file mode 100644 index 0000000000..affffdce09 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/RegRequestBody.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class RegRequestBody extends Body { + + public static final String CLIENTTYPE = "clientType"; + + public static final String TOPICS = "topics"; + + public static final String ENDPOINT = "endpoint"; + + private String clientType; + + private String endPoint; + + private List topics; + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public String getClientType() { + return clientType; + } + + public void setClientType(String clientType) { + this.clientType = clientType; + } + + public String getEndPoint() { + return endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public static RegRequestBody buildBody(Map bodyParam) { + RegRequestBody body = new RegRequestBody(); + body.setClientType(MapUtils.getString(bodyParam, CLIENTTYPE)); + body.setEndPoint(MapUtils.getString(bodyParam, ENDPOINT)); + body.setTopics(JsonUtils.deserialize(MapUtils.getString(bodyParam, TOPICS), + new TypeReference>() { + })); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(CLIENTTYPE, clientType); + map.put(ENDPOINT, endPoint); + map.put(TOPICS, JsonUtils.serialize(topics)); + return map; + } + + @Override + public String toString() { + return "regRequestBody{" + + "clientType='" + clientType + '\'' + + ", endPoint='" + endPoint + '\'' + + ", topics=" + topics + + '}'; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/RegResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/RegResponseBody.java new file mode 100644 index 0000000000..aeb3288538 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/RegResponseBody.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class RegResponseBody extends Body { + private Integer retCode; + private String retMsg; + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static RegResponseBody buildBody(Integer retCode, String retMsg) throws Exception { + RegResponseBody regResponseBody = new RegResponseBody(); + regResponseBody.setRetMsg(retMsg); + regResponseBody.setResTime(System.currentTimeMillis()); + regResponseBody.setRetCode(retCode); + return regResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("regResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/SubscribeRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/SubscribeRequestBody.java new file mode 100644 index 0000000000..df413c1c33 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/SubscribeRequestBody.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class SubscribeRequestBody extends Body { + + public static final String TOPIC = "topic"; + + public static final String URL = "url"; + + public static final String CONSUMERGROUP = "consumerGroup"; + + private List topics; + + private String url; + + private String consumerGroup; + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public static SubscribeRequestBody buildBody(Map bodyParam) { + SubscribeRequestBody body = new SubscribeRequestBody(); + body.setUrl(MapUtils.getString(bodyParam, URL)); + body.setTopics(JsonUtils.deserialize(MapUtils.getString(bodyParam, TOPIC), + new TypeReference>() { + })); + body.setConsumerGroup(MapUtils.getString(bodyParam, CONSUMERGROUP)); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(URL, url); + map.put(TOPIC, JsonUtils.serialize(topics)); + map.put(CONSUMERGROUP, consumerGroup); + return map; + } + + @Override + public String toString() { + return "subscribeBody{" + + "consumerGroup='" + consumerGroup + '\'' + + ", url='" + url + '\'' + + ", topics=" + topics + + '}'; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/SubscribeResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/SubscribeResponseBody.java new file mode 100644 index 0000000000..0b2f6cb3ab --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/SubscribeResponseBody.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SubscribeResponseBody extends Body { + private Integer retCode; + private String retMsg; + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static SubscribeResponseBody buildBody(Integer retCode, String retMsg) throws Exception { + SubscribeResponseBody regResponseBody = new SubscribeResponseBody(); + regResponseBody.setRetMsg(retMsg); + regResponseBody.setResTime(System.currentTimeMillis()); + regResponseBody.setRetCode(retCode); + return regResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("regResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnRegRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnRegRequestBody.java new file mode 100644 index 0000000000..6fa82bda7c --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnRegRequestBody.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class UnRegRequestBody extends Body { + + public static final String CLIENTTYPE = "clientType"; + + public static final String TOPICS = "topics"; + + private String clientType; + + private List topics; + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public String getClientType() { + return clientType; + } + + public void setClientType(String clientType) { + this.clientType = clientType; + } + + public static UnRegRequestBody buildBody(Map bodyParam) { + UnRegRequestBody body = new UnRegRequestBody(); + body.setClientType(MapUtils.getString(bodyParam, CLIENTTYPE)); + body.setTopics(JsonUtils.deserialize(MapUtils.getString(bodyParam, TOPICS), + new TypeReference>() { + })); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(CLIENTTYPE, clientType); + map.put(TOPICS, JsonUtils.serialize(topics)); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("regRequestBody={") + .append("clientType=").append(clientType) + .append("topics=").append(topics) + .append("}"); + return sb.toString(); + } + + public static class UnRegTopicEntity { + public String topic; + public String serviceId; + public String instanceId; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("unRegTopicEntity={") + .append("topic=").append(topic).append(",") + .append("serviceId=").append(serviceId).append(",") + .append("instanceId=").append(instanceId).append("}"); + return sb.toString(); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnRegResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnRegResponseBody.java new file mode 100644 index 0000000000..975cb35a54 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnRegResponseBody.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class UnRegResponseBody extends Body { + private Integer retCode; + private String retMsg; + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static UnRegResponseBody buildBody(Integer retCode, String retMsg) throws Exception { + UnRegResponseBody regResponseBody = new UnRegResponseBody(); + regResponseBody.setRetMsg(retMsg); + regResponseBody.setResTime(System.currentTimeMillis()); + regResponseBody.setRetCode(retCode); + return regResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("regResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnSubscribeRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnSubscribeRequestBody.java new file mode 100644 index 0000000000..ca9db6210e --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnSubscribeRequestBody.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class UnSubscribeRequestBody extends Body { + + public static final String TOPIC = "topic"; + + public static final String URL = "url"; + + public static final String CONSUMERGROUP = "consumerGroup"; + + private List topics; + + private String url; + + private String consumerGroup; + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public static UnSubscribeRequestBody buildBody(Map bodyParam) { + UnSubscribeRequestBody body = new UnSubscribeRequestBody(); + body.setUrl(MapUtils.getString(bodyParam, URL)); + body.setTopics(JsonUtils + .deserialize(MapUtils.getString(bodyParam, TOPIC), new TypeReference>() { + })); + body.setConsumerGroup(MapUtils.getString(bodyParam, CONSUMERGROUP)); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(URL, url); + map.put(TOPIC, JsonUtils.serialize(topics)); + map.put(CONSUMERGROUP, consumerGroup); + return map; + } + + @Override + public String toString() { + return "unSubscribeRequestBody{" + + "consumerGroup='" + consumerGroup + '\'' + + ", url='" + url + '\'' + + ", topics=" + topics + + '}'; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnSubscribeResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnSubscribeResponseBody.java new file mode 100644 index 0000000000..d1eeb77db5 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/client/UnSubscribeResponseBody.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class UnSubscribeResponseBody extends Body { + + private Integer retCode; + private String retMsg; + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static UnSubscribeResponseBody buildBody(Integer retCode, String retMsg) throws Exception { + UnSubscribeResponseBody regResponseBody = new UnSubscribeResponseBody(); + regResponseBody.setRetMsg(retMsg); + regResponseBody.setResTime(System.currentTimeMillis()); + regResponseBody.setRetCode(retCode); + return regResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("regResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/PushMessageRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/PushMessageRequestBody.java new file mode 100644 index 0000000000..4a8feeb818 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/PushMessageRequestBody.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class PushMessageRequestBody extends Body { + + public static final String RANDOMNO = "randomNo"; + public static final String TOPIC = "topic"; + public static final String BIZSEQNO = "bizseqno"; + public static final String UNIQUEID = "uniqueId"; + public static final String CONTENT = "content"; + public static final String EXTFIELDS = "extFields"; + + private String randomNo; + + private String topic; + + private String content; + + private String bizSeqNo; + + private String uniqueId; + + private HashMap extFields; + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getRandomNo() { + return randomNo; + } + + public void setRandomNo(String randomNo) { + this.randomNo = randomNo; + } + + public String getBizSeqNo() { + return bizSeqNo; + } + + public void setBizSeqNo(String bizSeqNo) { + this.bizSeqNo = bizSeqNo; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public HashMap getExtFields() { + return extFields; + } + + public void setExtFields(HashMap extFields) { + this.extFields = extFields; + } + + public static PushMessageRequestBody buildBody(final Map bodyParam) { + PushMessageRequestBody pushMessageRequestBody = new PushMessageRequestBody(); + pushMessageRequestBody.setContent(MapUtils.getString(bodyParam, CONTENT)); + pushMessageRequestBody.setBizSeqNo(MapUtils.getString(bodyParam, BIZSEQNO)); + pushMessageRequestBody.setTopic(MapUtils.getString(bodyParam, TOPIC)); + pushMessageRequestBody.setUniqueId(MapUtils.getString(bodyParam, UNIQUEID)); + pushMessageRequestBody.setRandomNo(MapUtils.getString(bodyParam, RANDOMNO)); + String extFields = MapUtils.getString(bodyParam, EXTFIELDS); + + if (StringUtils.isNotBlank(extFields)) { + pushMessageRequestBody.setExtFields( + JsonUtils.deserialize(extFields, new TypeReference>() { + })); + } + return pushMessageRequestBody; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(RANDOMNO, randomNo); + map.put(TOPIC, topic); + map.put(CONTENT, content); + map.put(BIZSEQNO, bizSeqNo); + map.put(UNIQUEID, uniqueId); + map.put(EXTFIELDS, JsonUtils.serialize(extFields)); + + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("pushMessageRequestBody={") + .append("randomNo=").append(randomNo).append(",") + .append("topic=").append(topic).append(",") + .append("bizSeqNo=").append(bizSeqNo).append(",") + .append("uniqueId=").append(uniqueId).append(",") + .append("content=").append(content).append(",") + .append("extFields=").append(extFields).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/PushMessageResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/PushMessageResponseBody.java new file mode 100644 index 0000000000..01000b0d0f --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/PushMessageResponseBody.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class PushMessageResponseBody extends Body { + + private Integer retCode; + + private String retMsg; + + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static PushMessageResponseBody buildBody(Integer retCode, String retMsg) { + PushMessageResponseBody pushMessageResponseBody = new PushMessageResponseBody(); + pushMessageResponseBody.setResTime(System.currentTimeMillis()); + pushMessageResponseBody.setRetCode(retCode); + pushMessageResponseBody.setRetMsg(retMsg); + return pushMessageResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("pushMessageResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/ReplyMessageRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/ReplyMessageRequestBody.java new file mode 100644 index 0000000000..0814204e4c --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/ReplyMessageRequestBody.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class ReplyMessageRequestBody extends Body { + + public static final String ORIGTOPIC = "origtopic"; + public static final String BIZSEQNO = "bizseqno"; + public static final String UNIQUEID = "uniqueid"; + public static final String CONTENT = "content"; + public static final String EXTFIELDS = "extFields"; + public static final String PRODUCERGROUP = "producergroup"; + + private String bizSeqNo; + + private String uniqueId; + + private String content; + + private String origTopic; + + private HashMap extFields; + + private String producerGroup; + + public String getOrigTopic() { + return origTopic; + } + + public void setOrigTopic(String origTopic) { + this.origTopic = origTopic; + } + + public String getBizSeqNo() { + return bizSeqNo; + } + + public void setBizSeqNo(String bizSeqNo) { + this.bizSeqNo = bizSeqNo; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public HashMap getExtFields() { + return extFields; + } + + public void setExtFields(HashMap extFields) { + this.extFields = extFields; + } + + public String getProducerGroup() { + return producerGroup; + } + + public void setProducerGroup(String producerGroup) { + this.producerGroup = producerGroup; + } + + public static ReplyMessageRequestBody buildBody(Map bodyParam) { + ReplyMessageRequestBody body = new ReplyMessageRequestBody(); + body.setBizSeqNo(MapUtils.getString(bodyParam, BIZSEQNO)); + body.setUniqueId(MapUtils.getString(bodyParam, UNIQUEID)); + body.setContent(MapUtils.getString(bodyParam, CONTENT)); + body.setOrigTopic(MapUtils.getString(bodyParam, ORIGTOPIC)); + String extFields = MapUtils.getString(bodyParam, EXTFIELDS); + if (StringUtils.isNotBlank(extFields)) { + body.setExtFields( + JsonUtils.deserialize(extFields, new TypeReference>() { + })); + } + body.setProducerGroup(MapUtils.getString(bodyParam, PRODUCERGROUP)); + return body; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("replyMessageRequestBody={") + .append("bizSeqNo=").append(bizSeqNo).append(",") + .append("uniqueId=").append(uniqueId).append(",") + .append("origTopic=").append(origTopic).append(",") + .append("content=").append(content).append(",") + .append("producerGroup=").append(producerGroup).append(",") + .append("extFields=").append(extFields).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(BIZSEQNO, bizSeqNo); + map.put(ORIGTOPIC, origTopic); + map.put(UNIQUEID, uniqueId); + map.put(CONTENT, content); + map.put(EXTFIELDS, JsonUtils.serialize(extFields)); + map.put(PRODUCERGROUP, producerGroup); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/ReplyMessageResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/ReplyMessageResponseBody.java new file mode 100644 index 0000000000..342f151c0a --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/ReplyMessageResponseBody.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class ReplyMessageResponseBody extends Body { + + //return code + private Integer retCode; + + //response message + private String retMsg; + + //response time + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static ReplyMessageResponseBody buildBody(Integer retCode, String retMsg) { + ReplyMessageResponseBody replyMessageResponseBody = new ReplyMessageResponseBody(); + replyMessageResponseBody.setRetMsg(retMsg); + replyMessageResponseBody.setResTime(System.currentTimeMillis()); + replyMessageResponseBody.setRetCode(retCode); + return replyMessageResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("replyMessageResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchRequestBody.java new file mode 100644 index 0000000000..da77955333 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchRequestBody.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class SendMessageBatchRequestBody extends Body { + + public static final String BATCHID = "batchId"; + public static final String CONTENTS = "contents"; + public static final String SIZE = "size"; + public static final String PRODUCERGROUP = "producerGroup"; + + private String batchId; + + private List contents; + + private String size; + + private String producerGroup; + + public SendMessageBatchRequestBody() { + } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public List getContents() { + return contents; + } + + public void setContents(List contents) { + this.contents = contents; + } + + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public String getProducerGroup() { + return producerGroup; + } + + public void setProducerGroup(String producerGroup) { + this.producerGroup = producerGroup; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageBatchRequestBody={") + .append("batchId=").append(batchId).append(",") + .append("size=").append(size).append(",") + .append("producerGroup=").append(producerGroup).append(",") + .append("contents=").append(JsonUtils.serialize(contents)).append("}"); + return sb.toString(); + } + + public static class BatchMessageEntity { + public String bizSeqNo; + public String topic; + public String msg; + public String tag; + public String ttl; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("batchMessageEntity={") + .append("bizSeqNo=").append(bizSeqNo).append(",") + .append("topic=").append(topic).append(",") + .append("msg=").append(msg).append(",") + .append("ttl=").append(ttl).append(",") + .append("tag=").append(tag).append("}"); + return sb.toString(); + } + } + + public static SendMessageBatchRequestBody buildBody(final Map bodyParam) { + String batchId = MapUtils.getString(bodyParam, + BATCHID); + String size = StringUtils.isBlank(MapUtils.getString(bodyParam, + SIZE)) ? "1" : MapUtils.getString(bodyParam, + SIZE); + String contents = MapUtils.getString(bodyParam, + CONTENTS, null); + SendMessageBatchRequestBody body = new SendMessageBatchRequestBody(); + body.setBatchId(batchId); + if (StringUtils.isNotBlank(contents)) { + body.setContents( + JsonUtils.deserialize(contents, new TypeReference>() { + })); + } + body.setSize(size); + body.setProducerGroup(MapUtils.getString(bodyParam, PRODUCERGROUP)); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(BATCHID, batchId); + map.put(SIZE, size); + map.put(CONTENTS, contents); + map.put(PRODUCERGROUP, producerGroup); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchResponseBody.java new file mode 100644 index 0000000000..f504473673 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchResponseBody.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageBatchResponseBody extends Body { + + //return code + private Integer retCode; + + //response message + private String retMsg; + + //response time + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static SendMessageBatchResponseBody buildBody(Integer retCode, String retMsg) { + SendMessageBatchResponseBody sendMessageBatchResponseBody = new SendMessageBatchResponseBody(); + sendMessageBatchResponseBody.setRetMsg(retMsg); + sendMessageBatchResponseBody.setRetCode(retCode); + sendMessageBatchResponseBody.setResTime(System.currentTimeMillis()); + return sendMessageBatchResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageBatchResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchV2RequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchV2RequestBody.java new file mode 100644 index 0000000000..5abd7bc0cf --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchV2RequestBody.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.protocol.http.body.Body; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageBatchV2RequestBody extends Body { + + public static final String BIZSEQNO = "bizseqno"; + public static final String TOPIC = "topic"; + public static final String MSG = "msg"; + public static final String TAG = "tag"; + public static final String TTL = "ttl"; + public static final String PRODUCERGROUP = "producergroup"; + + private String bizSeqNo; + + private String topic; + + private String msg; + + private String tag; + + private String ttl; + + private String producerGroup; + + public String getBizSeqNo() { + return bizSeqNo; + } + + public void setBizSeqNo(String bizSeqNo) { + this.bizSeqNo = bizSeqNo; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public String getTtl() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } + + public String getProducerGroup() { + return producerGroup; + } + + public void setProducerGroup(String producerGroup) { + this.producerGroup = producerGroup; + } + + public static SendMessageBatchV2RequestBody buildBody(final Map bodyParam) { + String bizSeqno = MapUtils.getString(bodyParam, + BIZSEQNO); + String topic = MapUtils.getString(bodyParam, + TOPIC); + String tag = MapUtils.getString(bodyParam, + TAG); + String msg = MapUtils.getString(bodyParam, + MSG); + String ttl = MapUtils.getString(bodyParam, + TTL); + SendMessageBatchV2RequestBody body = new SendMessageBatchV2RequestBody(); + body.setBizSeqNo(bizSeqno); + body.setMsg(msg); + body.setTag(tag); + body.setTtl(ttl); + body.setTopic(topic); + body.setProducerGroup(MapUtils.getString(bodyParam, PRODUCERGROUP)); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(BIZSEQNO, bizSeqNo); + map.put(TOPIC, topic); + map.put(MSG, msg); + map.put(TAG, tag); + map.put(TTL, ttl); + map.put(PRODUCERGROUP, producerGroup); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SendMessageBatchV2RequestBody={") + .append("bizSeqNo=").append(bizSeqNo).append(",") + .append("topic=").append(topic).append(",") + .append("tag=").append(tag).append(",") + .append("ttl=").append(ttl).append(",") + .append("producerGroup=").append(producerGroup).append(",") + .append("msg=").append(msg).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchV2ResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchV2ResponseBody.java new file mode 100644 index 0000000000..26cc08202c --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageBatchV2ResponseBody.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageBatchV2ResponseBody extends Body { + + //return code + private Integer retCode; + + //response message + private String retMsg; + + //response time + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static SendMessageBatchV2ResponseBody buildBody(Integer retCode, String retMsg) { + SendMessageBatchV2ResponseBody sendMessageBatchV2ResponseBody = new SendMessageBatchV2ResponseBody(); + sendMessageBatchV2ResponseBody.setRetMsg(retMsg); + sendMessageBatchV2ResponseBody.setRetCode(retCode); + sendMessageBatchV2ResponseBody.setResTime(System.currentTimeMillis()); + return sendMessageBatchV2ResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageBatchV2ResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageRequestBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageRequestBody.java new file mode 100644 index 0000000000..e14d230a56 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageRequestBody.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class SendMessageRequestBody extends Body { + + public static final String TOPIC = "topic"; + public static final String BIZSEQNO = "bizseqno"; + public static final String UNIQUEID = "uniqueid"; + public static final String CONTENT = "content"; + public static final String TTL = "ttl"; + public static final String TAG = "tag"; + public static final String EXTFIELDS = "extFields"; + public static final String PRODUCERGROUP = "producergroup"; + + private String topic; + + private String bizSeqNo; + + private String uniqueId; + + private String ttl; + + private String content; + + private String tag; + + private HashMap extFields; + + private String producerGroup; + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getBizSeqNo() { + return bizSeqNo; + } + + public void setBizSeqNo(String bizSeqNo) { + this.bizSeqNo = bizSeqNo; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public HashMap getExtFields() { + return extFields; + } + + public void setExtFields(HashMap extFields) { + this.extFields = extFields; + } + + public String getTtl() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public String getProducerGroup() { + return producerGroup; + } + + public void setProducerGroup(String producerGroup) { + this.producerGroup = producerGroup; + } + + public static SendMessageRequestBody buildBody(Map bodyParam) { + SendMessageRequestBody body = new SendMessageRequestBody(); + body.setTopic(MapUtils.getString(bodyParam, TOPIC)); + body.setBizSeqNo(MapUtils.getString(bodyParam, BIZSEQNO)); + body.setUniqueId(MapUtils.getString(bodyParam, UNIQUEID)); + body.setTtl(MapUtils.getString(bodyParam, TTL)); + body.setTag(MapUtils.getString(bodyParam, TAG, "")); + body.setContent(MapUtils.getString(bodyParam, CONTENT)); + String extFields = MapUtils.getString(bodyParam, EXTFIELDS); + if (StringUtils.isNotBlank(extFields)) { + body.setExtFields( + JsonUtils.deserialize(extFields, new TypeReference>() { + })); + } + body.setProducerGroup(MapUtils.getString(bodyParam, PRODUCERGROUP)); + return body; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(TOPIC, topic); + map.put(BIZSEQNO, bizSeqNo); + map.put(UNIQUEID, uniqueId); + map.put(TTL, ttl); + map.put(TAG, tag); + map.put(CONTENT, content); + map.put(EXTFIELDS, extFields); + map.put(PRODUCERGROUP, producerGroup); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageRequestBody={") + .append("topic=").append(topic).append(",") + .append("bizSeqNo=").append(bizSeqNo).append(",") + .append("uniqueId=").append(uniqueId).append(",") + .append("content=").append(content).append(",") + .append("ttl=").append(ttl).append(",") + .append("tag=").append(tag).append(",") + .append("producerGroup=").append(producerGroup).append(",") + .append("extFields=").append(extFields).append("}"); + return sb.toString(); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageResponseBody.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageResponseBody.java new file mode 100644 index 0000000000..e4e9eaa120 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/body/message/SendMessageResponseBody.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.Map; + +import lombok.Builder; +import lombok.Data; + +public class SendMessageResponseBody extends Body { + + private Integer retCode; + + private String retMsg; + + private long resTime = System.currentTimeMillis(); + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public static SendMessageResponseBody buildBody(Integer retCode, String retMsg) { + SendMessageResponseBody sendMessageResponseBody = new SendMessageResponseBody(); + sendMessageResponseBody.setRetMsg(retMsg); + sendMessageResponseBody.setResTime(System.currentTimeMillis()); + sendMessageResponseBody.setRetCode(retCode); + return sendMessageResponseBody; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageResponseBody={") + .append("retCode=").append(retCode).append(",") + .append("retMsg=").append(retMsg).append(",") + .append("resTime=").append(DateFormatUtils.format(resTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.RETCODE, retCode); + map.put(ProtocolKey.RETMSG, retMsg); + map.put(ProtocolKey.RESTIME, resTime); + return map; + } + + @Data + @Builder + public static class ReplyMessage { + public String topic; + public String body; + public Map properties; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ClientRetCode.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ClientRetCode.java new file mode 100644 index 0000000000..ceaf05cef2 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ClientRetCode.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.common; + +public enum ClientRetCode { + + /** + * The "RETRY" means:when the client finds the delivered message and it does not listen, tell EventMesh to send + * next, try again several times to achieve grayscale, reserve + */ + + REMOTE_OK(0, "REMOTE Process OK"), + OK(1, "OK. SDK returns."), + RETRY(2, "RETRY. SDK returns. Retry at most max(default, config) times."), + FAIL(3, "FAIL. SDK returns."), + NOLISTEN(5, "NOLISTEN. SDK returns. It can be used for grayscale publishing. Need to try all URLs in this case."); + + ClientRetCode(Integer retCode, String errMsg) { + this.retCode = retCode; + this.errMsg = errMsg; + } + + public static boolean contains(Integer clientRetCode) { + boolean flag = false; + for (ClientRetCode itr : ClientRetCode.values()) { + if (itr.retCode.intValue() == clientRetCode.intValue()) { + flag = true; + break; + } + } + return flag; + } + + public static ClientRetCode get(Integer clientRetCode) { + ClientRetCode ret = null; + for (ClientRetCode itr : ClientRetCode.values()) { + if (itr.retCode.intValue() == clientRetCode.intValue()) { + ret = itr; + break; + } + } + return ret; + } + + private Integer retCode; + + private String errMsg; + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getErrMsg() { + return errMsg; + } + + public void setErrMsg(String errMsg) { + this.errMsg = errMsg; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ClientType.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ClientType.java new file mode 100644 index 0000000000..c935da6cc4 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ClientType.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.common; + +public enum ClientType { + + PUB(1, "Client for publishing"), + + SUB(2, "Client for subscribing"); + + private Integer type; + + private String desc; + + ClientType(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + public static ClientType get(Integer type) { + if (PUB.type.intValue() == type.intValue()) { + return PUB; + } else if (SUB.type.intValue() == type.intValue()) { + return SUB; + } else { + return null; + } + } + + public static boolean contains(Integer clientType) { + boolean flag = false; + for (ClientType ct : ClientType.values()) { + if (ct.type == clientType.intValue()) { + flag = true; + break; + } + } + return flag; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/EventMeshRetCode.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/EventMeshRetCode.java new file mode 100644 index 0000000000..831eaaca6a --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/EventMeshRetCode.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.common; + +public enum EventMeshRetCode { + + SUCCESS(0, "success"), + OVERLOAD(1, "eventMesh overload, try later, "), + EVENTMESH_REQUESTCODE_INVALID(2, "requestCode can't be null, or must be number, "), + EVENTMESH_SEND_SYNC_MSG_ERR(3, "eventMesh send rr msg err, "), + EVENTMESH_WAITING_RR_MSG_ERR(4, "eventMesh waiting rr msg err, "), + EVENTMESH_PROTOCOL_HEADER_ERR(6, "eventMesh protocol[header] err, "), + EVENTMESH_PROTOCOL_BODY_ERR(7, "eventMesh protocol[body] err, "), + EVENTMESH_PROTOCOL_BODY_SIZE_ERR(8, "event size exceeds the limit, "), + EVENTMESH_STOP(9, "eventMesh will stop or had stopped, "), + EVENTMESH_REJECT_BY_PROCESSOR_ERROR(10, "eventMesh reject by processor error, "), + EVENTMESH_BATCH_PRODUCER_STOPED_ERR(11, "eventMesh batch msg producer stopped, "), + EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR(12, "eventMesh batch msg speed over the limit, "), + EVENTMESH_PACKAGE_MSG_ERR(13, "eventMesh package msg err, "), + EVENTMESH_GROUP_PRODUCER_STOPED_ERR(14, "eventMesh group producer stopped, "), + EVENTMESH_SEND_ASYNC_MSG_ERR(15, "eventMesh send async msg err, "), + EVENTMESH_REPLY_MSG_ERR(16, "eventMesh reply msg err, "), + EVENTMESH_SEND_BATCHLOG_MSG_ERR(17, "eventMesh send batchlog msg err, "), + EVENTMESH_RUNTIME_ERR(18, "eventMesh runtime err, "), + EVENTMESH_SUBSCRIBE_ERR(19, "eventMesh subscribe err"), + EVENTMESH_UNSUBSCRIBE_ERR(20, "eventMesh unsubscribe err"), + EVENTMESH_HEARTBEAT_ERR(21, "eventMesh heartbeat err"), + EVENTMESH_ACL_ERR(22, "eventMesh acl err"), + EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR(23, "eventMesh http msg send over the limit, "); + + private Integer retCode; + + private String errMsg; + + EventMeshRetCode(Integer retCode, String errMsg) { + this.retCode = retCode; + this.errMsg = errMsg; + } + + public Integer getRetCode() { + return retCode; + } + + public void setRetCode(Integer retCode) { + this.retCode = retCode; + } + + public String getErrMsg() { + return errMsg; + } + + public void setErrMsg(String errMsg) { + this.errMsg = errMsg; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ProtocolKey.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ProtocolKey.java new file mode 100644 index 0000000000..19a836ae3a --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ProtocolKey.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.common; + +public class ProtocolKey { + + public static final String REQUEST_CODE = "code"; + public static final String REQUEST_URI = "uri"; + public static final String LANGUAGE = "language"; + public static final String VERSION = "version"; + + public static final String PROTOCOL_TYPE = "protocoltype"; + + public static final String PROTOCOL_VERSION = "protocolversion"; + + public static final String PROTOCOL_DESC = "protocoldesc"; + + public static final String CONTENT_TYPE = "contenttype"; + + public static class ClientInstanceKey { + ////////////////////////////////////Protocol layer requester description/////////// + public static final String ENV = "env"; + public static final String IDC = "idc"; + public static final String SYS = "sys"; + public static final String PID = "pid"; + public static final String IP = "ip"; + public static final String USERNAME = "username"; + public static final String PASSWD = "passwd"; + public static final String BIZSEQNO = "bizseqno"; + public static final String UNIQUEID = "uniqueid"; + public static final String PRODUCERGROUP = "producergroup"; + public static final String CONSUMERGROUP = "consumergroup"; + } + + + public static class EventMeshInstanceKey { + ///////////////////////////////////////////////Protocol layer EventMesh description + public static final String EVENTMESHCLUSTER = "eventmeshcluster"; + public static final String EVENTMESHIP = "eventmeship"; + public static final String EVENTMESHENV = "eventmeshenv"; + public static final String EVENTMESHIDC = "eventmeshidc"; + } + + public static class CloudEventsKey { + public static final String ID = "id"; + public static final String SOURCE = "source"; + public static final String SUBJECT = "subject"; + public static final String TYPE = "type"; + } + + + //return of CLIENT <-> EventMesh + public static final String RETCODE = "retCode"; + public static final String RETMSG = "retMsg"; + public static final String RESTIME = "resTime"; +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ProtocolVersion.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ProtocolVersion.java new file mode 100644 index 0000000000..acfd655246 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/ProtocolVersion.java @@ -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 org.apache.eventmesh.common.protocol.http.common; + +public enum ProtocolVersion { + + V1("1.0"), + V2("2.0"); + + private String version; + + ProtocolVersion(String version) { + this.version = version; + } + + public static ProtocolVersion get(String version) { + if (V1.version.equals(version)) { + return V1; + } else if (V2.version.equals(version)) { + return V2; + } else { + return null; + } + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public static boolean contains(String version) { + boolean flag = false; + for (ProtocolVersion itr : ProtocolVersion.values()) { + if (itr.version.equals(version)) { + flag = true; + break; + } + } + return flag; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/RequestCode.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/RequestCode.java new file mode 100644 index 0000000000..32e1b7fbcc --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/RequestCode.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.common; + +public enum RequestCode { + + MSG_BATCH_SEND(102, "SEND BATCH MSG"), + + MSG_BATCH_SEND_V2(107, "SEND BATCH MSG V2"), + + MSG_SEND_SYNC(101, "SEND SINGLE MSG SYNC"), + + MSG_SEND_ASYNC(104, "SEND SINGLE MSG ASYNC"), + + HTTP_PUSH_CLIENT_ASYNC(105, "PUSH CLIENT BY HTTP POST"), + + HTTP_PUSH_CLIENT_SYNC(106, "PUSH CLIENT BY HTTP POST"), + + REGISTER(201, "REGISTER"), + + UNREGISTER(202, "UNREGISTER"), + + HEARTBEAT(203, "HEARTBEAT"), + + SUBSCRIBE(206, "SUBSCRIBE"), + + UNSUBSCRIBE(207, "UNSUBSCRIBE"), + + REPLY_MESSAGE(301, "REPLY MESSAGE"), + + ADMIN_METRICS(603, "ADMIN METRICS"), + + ADMIN_SHUTDOWN(601, "ADMIN SHUTDOWN"); + + private Integer requestCode; + + private String desc; + + RequestCode(Integer requestCode, String desc) { + this.requestCode = requestCode; + this.desc = desc; + } + + public static boolean contains(Integer requestCode) { + boolean flag = false; + for (RequestCode itr : RequestCode.values()) { + if (itr.requestCode.intValue() == requestCode.intValue()) { + flag = true; + break; + } + } + return flag; + } + + public static RequestCode get(Integer requestCode) { + RequestCode ret = null; + for (RequestCode itr : RequestCode.values()) { + if (itr.requestCode.intValue() == requestCode.intValue()) { + ret = itr; + break; + } + } + return ret; + } + + public Integer getRequestCode() { + return requestCode; + } + + public void setRequestCode(Integer requestCode) { + this.requestCode = requestCode; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/RequestURI.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/RequestURI.java new file mode 100644 index 0000000000..ff295c30a6 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/RequestURI.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.common; + +public enum RequestURI { + + PUBLISH("/eventmesh/publish", "PUBLISH SINGLE EVENT"), + + PUBLISH_BRIDGE("/eventmesh/bridge/publish", "PUBLISH REMOTE SINGLE EVENT"), + + PUBLISH_BATCH("/eventmesh/publish/batch", "PUBLISH BATCH EVENTS"), + + SUBSCRIBE_LOCAL("/eventmesh/subscribe/local", "SUBSCRIBE LOCAL"), + + SUBSCRIBE_REMOTE("/eventmesh/subscribe/remote", "SUBSCRIBE REMOTE"), + + UNSUBSCRIBE_LOCAL("/eventmesh/unsubscribe/local", "SUBSCRIBE LOCAL"), + + UNSUBSCRIBE_REMOTE("/eventmesh/unsubscribe/remote", "SUBSCRIBE REMOTE"); + + + private String requestURI; + + private String desc; + + RequestURI(String requestURI, String desc) { + this.requestURI = requestURI; + this.desc = desc; + } + + public static boolean contains(String requestURI) { + boolean flag = false; + for (RequestURI itr : RequestURI.values()) { + if (itr.requestURI.equals(requestURI)) { + flag = true; + break; + } + } + return flag; + } + + public static RequestURI get(String requestURI) { + RequestURI ret = null; + for (RequestURI itr : RequestURI.values()) { + if (itr.requestURI.equals(requestURI)) { + ret = itr; + break; + } + } + return ret; + } + + public String getRequestURI() { + return requestURI; + } + + public void setRequestURI(String requestURI) { + this.requestURI = requestURI; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/BaseRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/BaseRequestHeader.java new file mode 100644 index 0000000000..f34f915418 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/BaseRequestHeader.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.Map; + +public class BaseRequestHeader extends Header { + private String code; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public static BaseRequestHeader buildHeader(Map headerParam) { + BaseRequestHeader header = new BaseRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + return header; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("baseRequestHeader={code=") + .append(code).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/BaseResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/BaseResponseHeader.java new file mode 100644 index 0000000000..2a2e2c7665 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/BaseResponseHeader.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import java.util.HashMap; +import java.util.Map; + +public class BaseResponseHeader extends Header { + + private String code; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public static BaseResponseHeader buildHeader(String code) { + BaseResponseHeader baseResponseHeader = new BaseResponseHeader(); + baseResponseHeader.setCode(code); + return baseResponseHeader; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(ProtocolKey.REQUEST_CODE, code); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/Header.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/Header.java new file mode 100644 index 0000000000..9a432202a1 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/Header.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header; + + +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.client.HeartbeatRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.client.RegRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.client.SubscribeRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.client.UnRegRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.client.UnSubscribeRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.PushMessageRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchV2RequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageRequestHeader; + +import java.util.Map; + +public abstract class Header { + + public abstract Map toMap(); + + public static Header buildHeader(String requestCode, Map originalMap) throws Exception { + if (String.valueOf(RequestCode.MSG_BATCH_SEND.getRequestCode()).equals(requestCode)) { + return SendMessageBatchRequestHeader.buildHeader(originalMap); + } + if (String.valueOf(RequestCode.MSG_BATCH_SEND_V2.getRequestCode()).equals(requestCode)) { + return SendMessageBatchV2RequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.MSG_SEND_SYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.MSG_SEND_ASYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.HTTP_PUSH_CLIENT_ASYNC.getRequestCode()).equals(requestCode)) { + return PushMessageRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.HTTP_PUSH_CLIENT_SYNC.getRequestCode()).equals(requestCode)) { + return PushMessageRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.REGISTER.getRequestCode()).equals(requestCode)) { + return RegRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.UNREGISTER.getRequestCode()).equals(requestCode)) { + return UnRegRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.SUBSCRIBE.getRequestCode()).equals(requestCode)) { + return SubscribeRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.UNSUBSCRIBE.getRequestCode()).equals(requestCode)) { + return UnSubscribeRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.HEARTBEAT.getRequestCode()).equals(requestCode)) { + return HeartbeatRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.REPLY_MESSAGE.getRequestCode()).equals(requestCode)) { + return ReplyMessageRequestHeader.buildHeader(originalMap); + } else if (String.valueOf(RequestCode.ADMIN_SHUTDOWN.getRequestCode()).equals(requestCode)) { + return BaseRequestHeader.buildHeader(originalMap); + } else { + throw new Exception(); + } + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatRequestHeader.java new file mode 100644 index 0000000000..85fceb6945 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatRequestHeader.java @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class HeartbeatRequestHeader extends Header { + + //request code + private String code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + //the environment number of the requester + private String env; + + //the IDC of the requester + private String idc; + + //subsystem of the requester + private String sys; + + //PID of the requester + private String pid; + + //IP of the requester + private String ip; + + private String producerGroup; + + //USERNAME of the requester + private String username = "username"; + + //PASSWD of the requester + private String passwd = "user@123"; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("heartbeatRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } + + public static HeartbeatRequestHeader buildHeader(Map headerParam) { + HeartbeatRequestHeader header = new HeartbeatRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatResponseHeader.java new file mode 100644 index 0000000000..c1c35c47d1 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatResponseHeader.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class HeartbeatResponseHeader extends Header { + + private int code; + + private String eventMeshCluster; + + private String eventMeshIp; + + private String eventMeshEnv; + + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static HeartbeatResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, + String eventMeshIDC) { + HeartbeatResponseHeader heartbeatResponseHeader = new HeartbeatResponseHeader(); + heartbeatResponseHeader.setCode(requestCode); + heartbeatResponseHeader.setEventMeshCluster(eventMeshCluster); + heartbeatResponseHeader.setEventMeshIp(eventMeshIp); + heartbeatResponseHeader.setEventMeshEnv(eventMeshEnv); + heartbeatResponseHeader.setEventMeshIdc(eventMeshIDC); + return heartbeatResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("heartbeatResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/RegRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/RegRequestHeader.java new file mode 100644 index 0000000000..3d88dbf312 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/RegRequestHeader.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class RegRequestHeader extends Header { + + private String code; + + private String language; + + private ProtocolVersion version; + + private String env; + + private String idc; + + private String sys; + + private String pid; + + private String ip; + + private String username; + + private String passwd; + + public static RegRequestHeader buildHeader(Map headerParam) { + RegRequestHeader header = new RegRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("regRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/RegResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/RegResponseHeader.java new file mode 100644 index 0000000000..b928b79fd0 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/RegResponseHeader.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class RegResponseHeader extends Header { + + //response code, as same as the request code + private int code; + + //The cluster name of the EventMesh that processes the request + private String eventMeshCluster; + + //IP of the EventMesh that processes the request + private String eventMeshIp; + + //Environment number of the EventMesh that processes the request + private String eventMeshEnv; + + //IDC of the EventMesh that processes the request + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static RegResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, String eventMeshIDC) { + RegResponseHeader regResponseHeader = new RegResponseHeader(); + regResponseHeader.setCode(requestCode); + regResponseHeader.setEventMeshCluster(eventMeshCluster); + regResponseHeader.setEventMeshIp(eventMeshIp); + regResponseHeader.setEventMeshEnv(eventMeshEnv); + regResponseHeader.setEventMeshIdc(eventMeshIDC); + return regResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("regResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeRequestHeader.java new file mode 100644 index 0000000000..adef902d93 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeRequestHeader.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SubscribeRequestHeader extends Header { + + private String code; + + private String language; + + private ProtocolVersion version; + + private String env; + + private String idc; + + private String sys; + + private String pid; + + private String ip; + + private String username; + + private String passwd; + + public static SubscribeRequestHeader buildHeader(Map headerParam) { + SubscribeRequestHeader header = new SubscribeRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("subscribeRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeResponseHeader.java new file mode 100644 index 0000000000..d16fb4e6aa --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeResponseHeader.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class SubscribeResponseHeader extends Header { + + private int code; + + private String eventMeshCluster; + + private String eventMeshIp; + + private String eventMeshEnv; + + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static SubscribeResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, + String eventMeshIDC) { + SubscribeResponseHeader subscribeResponseHeader = new SubscribeResponseHeader(); + subscribeResponseHeader.setCode(requestCode); + subscribeResponseHeader.setEventMeshCluster(eventMeshCluster); + subscribeResponseHeader.setEventMeshIp(eventMeshIp); + subscribeResponseHeader.setEventMeshEnv(eventMeshEnv); + subscribeResponseHeader.setEventMeshIdc(eventMeshIDC); + return subscribeResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("subscribeResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegRequestHeader.java new file mode 100644 index 0000000000..639d696476 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegRequestHeader.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class UnRegRequestHeader extends Header { + + //request code + private String code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + //the environment number of the requester + private String env; + + //the IDC of the requester + private String idc; + + //subsystem of the requester + private String sys; + + //PID of the requester + private String pid; + + //IP of the requester + private String ip; + + //USERNAME of the requester + private String username = "username"; + + //PASSWD of the requester + private String passwd = "user@123"; + + public static UnRegRequestHeader buildHeader(Map headerParam) { + UnRegRequestHeader header = new UnRegRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("unRegRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegResponseHeader.java new file mode 100644 index 0000000000..550e796be7 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegResponseHeader.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class UnRegResponseHeader extends Header { + + private int code; + + private String eventMeshCluster; + + private String eventMeshIp; + + private String eventMeshEnv; + + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static UnRegResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, String eventMeshIDC) { + UnRegResponseHeader regResponseHeader = new UnRegResponseHeader(); + regResponseHeader.setCode(requestCode); + regResponseHeader.setEventMeshCluster(eventMeshCluster); + regResponseHeader.setEventMeshIp(eventMeshIp); + regResponseHeader.setEventMeshEnv(eventMeshEnv); + regResponseHeader.setEventMeshIdc(eventMeshIDC); + return regResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("nnRegResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeRequestHeader.java new file mode 100644 index 0000000000..452e278846 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeRequestHeader.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class UnSubscribeRequestHeader extends Header { + + private String code; + + private String language; + + private ProtocolVersion version; + + private String env; + + private String idc; + + private String sys; + + private String pid; + + private String ip; + + private String username; + + private String passwd; + + public static UnSubscribeRequestHeader buildHeader(Map headerParam) { + UnSubscribeRequestHeader header = new UnSubscribeRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("subscribeRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeResponseHeader.java new file mode 100644 index 0000000000..bb90b4bf75 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeResponseHeader.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class UnSubscribeResponseHeader extends Header { + + private int code; + + private String eventMeshCluster; + + private String eventMeshIp; + + private String eventMeshEnv; + + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static UnSubscribeResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, String eventMeshIDC) { + UnSubscribeResponseHeader unSubscribeResponseHeader = new UnSubscribeResponseHeader(); + unSubscribeResponseHeader.setCode(requestCode); + unSubscribeResponseHeader.setEventMeshCluster(eventMeshCluster); + unSubscribeResponseHeader.setEventMeshIp(eventMeshIp); + unSubscribeResponseHeader.setEventMeshEnv(eventMeshEnv); + unSubscribeResponseHeader.setEventMeshIdc(eventMeshIDC); + return unSubscribeResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("unSubscribeResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageRequestHeader.java new file mode 100644 index 0000000000..726c08a720 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageRequestHeader.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.Map; + +public class PushMessageRequestHeader extends Header { + + //request code + private int code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + private String eventMeshCluster; + + private String eventMeshIp; + + private String eventMeshEnv; + + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public static PushMessageRequestHeader buildHeader(final Map headerParam) { + PushMessageRequestHeader pushMessageRequestHeader = new PushMessageRequestHeader(); + pushMessageRequestHeader.setCode(MapUtils.getIntValue(headerParam, ProtocolKey.REQUEST_CODE)); + pushMessageRequestHeader.setLanguage(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA)); + pushMessageRequestHeader.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + pushMessageRequestHeader.setEventMeshCluster(MapUtils.getString(headerParam, ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER)); + pushMessageRequestHeader.setEventMeshIp(MapUtils.getString(headerParam, ProtocolKey.EventMeshInstanceKey.EVENTMESHIP)); + pushMessageRequestHeader.setEventMeshEnv(MapUtils.getString(headerParam, ProtocolKey.EventMeshInstanceKey.EVENTMESHENV)); + pushMessageRequestHeader.setEventMeshIdc(MapUtils.getString(headerParam, ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC)); + return pushMessageRequestHeader; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("pushMessageRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version.getVersion()).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageResponseHeader.java new file mode 100644 index 0000000000..c5b727111d --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageResponseHeader.java @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class PushMessageResponseHeader extends Header { + + //response code + private int code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + //the environment number of the requester + private String env; + + //the IDC of the requester + private String idc; + + //subsystem of the requester + private String sys; + + //PID of the requester + private String pid; + + //IP of the requester + private String ip; + + //USERNAME of the requester + private String username; + + //PASSWD of the requester + private String passwd; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public static PushMessageResponseHeader buildHeader(int requestCode, String clientEnv, String clientIDC, + String clientSysId, String clientPid, String clientIP) { + PushMessageResponseHeader pushMessageResponseHeader = new PushMessageResponseHeader(); + pushMessageResponseHeader.setCode(requestCode); + pushMessageResponseHeader.setVersion(ProtocolVersion.V1); + pushMessageResponseHeader.setLanguage(Constants.LANGUAGE_JAVA); + pushMessageResponseHeader.setEnv(clientEnv); + pushMessageResponseHeader.setIdc(clientIDC); + pushMessageResponseHeader.setSys(clientSysId); + pushMessageResponseHeader.setPid(clientPid); + pushMessageResponseHeader.setIp(clientIP); + return pushMessageResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("pushMessageResponseHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageRequestHeader.java new file mode 100644 index 0000000000..ad4a8ec24e --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageRequestHeader.java @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class ReplyMessageRequestHeader extends Header { + + //request code + private String code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + //protocol type, cloudevents or eventmeshMessage + private String protocolType; + + //protocol version, cloudevents:1.0 or 0.3 + private String protocolVersion; + + //protocol desc + private String protocolDesc; + + //the environment number of the requester + private String env; + + //the IDC of the requester + private String idc; + + //subsystem of the requester + private String sys; + + //PID of the requester + private String pid; + + //IP of the requester + private String ip; + + //USERNAME of the requester + private String username; + + //PASSWD of the requester + private String passwd; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } + + public String getProtocolVersion() { + return protocolVersion; + } + + public void setProtocolVersion(String protocolVersion) { + this.protocolVersion = protocolVersion; + } + + public String getProtocolDesc() { + return protocolDesc; + } + + public void setProtocolDesc(String protocolDesc) { + this.protocolDesc = protocolDesc; + } + + public static ReplyMessageRequestHeader buildHeader(Map headerParam) { + ReplyMessageRequestHeader header = new ReplyMessageRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + header.setProtocolType(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_TYPE)); + header.setProtocolVersion(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_VERSION)); + header.setProtocolDesc(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_DESC)); + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("replyMessageRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageResponseHeader.java new file mode 100644 index 0000000000..20d6f107e9 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageResponseHeader.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class ReplyMessageResponseHeader extends Header { + + //response code, as same as the request code + private int code; + + //The cluster name of the EventMesh that processes the request + private String eventMeshCluster; + + //IP of the EventMesh that processes the request + private String eventMeshIp; + + //Environment number of the EventMesh that processes the request + private String eventMeshEnv; + + //IDC of the EventMesh that processes the request + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static ReplyMessageResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, + String eventMeshIDC) { + ReplyMessageResponseHeader replyMessageResponseHeader = new ReplyMessageResponseHeader(); + replyMessageResponseHeader.setCode(requestCode); + replyMessageResponseHeader.setEventMeshCluster(eventMeshCluster); + replyMessageResponseHeader.setEventMeshIp(eventMeshIp); + replyMessageResponseHeader.setEventMeshEnv(eventMeshEnv); + replyMessageResponseHeader.setEventMeshIdc(eventMeshIDC); + return replyMessageResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("replyMessageResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchRequestHeader.java new file mode 100644 index 0000000000..9ee63f71b2 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchRequestHeader.java @@ -0,0 +1,230 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageBatchRequestHeader extends Header { + + //request code + private String code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + //protocol type, cloudevents or eventmeshMessage + private String protocolType; + + //protocol version, cloudevents:1.0 or 0.3 + private String protocolVersion; + + //protocol desc + private String protocolDesc; + + //the environment number of the requester + private String env; + + //the IDC of the requester + private String idc; + + //subsystem of the requester + private String sys; + + //PID of the requester + private String pid; + + //IP of the requester + private String ip; + + //USERNAME of the requester + private String username; + + //PASSWD of the requester + private String passwd; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } + + public String getProtocolVersion() { + return protocolVersion; + } + + public void setProtocolVersion(String protocolVersion) { + this.protocolVersion = protocolVersion; + } + + public String getProtocolDesc() { + return protocolDesc; + } + + public void setProtocolDesc(String protocolDesc) { + this.protocolDesc = protocolDesc; + } + + public static SendMessageBatchRequestHeader buildHeader(final Map headerParam) { + SendMessageBatchRequestHeader header = new SendMessageBatchRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + header.setProtocolType(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_TYPE)); + header.setProtocolVersion(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_VERSION)); + header.setProtocolDesc(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_DESC)); + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageBatchRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchResponseHeader.java new file mode 100644 index 0000000000..4ddfde68b8 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchResponseHeader.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageBatchResponseHeader extends Header { + + //response code, as same as the request code + private int code; + + //The cluster name of the EventMesh that processes the request + private String eventMeshCluster; + + //IP of the EventMesh that processes the request + private String eventMeshIp; + + //Environment number of the EventMesh that processes the request + private String eventMeshEnv; + + //IDC of the EventMesh that processes the request + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static SendMessageBatchResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, + String eventMeshIDC) { + SendMessageBatchResponseHeader sendMessageBatchResponseHeader = new SendMessageBatchResponseHeader(); + sendMessageBatchResponseHeader.setCode(requestCode); + sendMessageBatchResponseHeader.setEventMeshCluster(eventMeshCluster); + sendMessageBatchResponseHeader.setEventMeshEnv(eventMeshEnv); + sendMessageBatchResponseHeader.setEventMeshIdc(eventMeshIDC); + sendMessageBatchResponseHeader.setEventMeshIp(eventMeshIp); + return sendMessageBatchResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageBatchResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchV2RequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchV2RequestHeader.java new file mode 100644 index 0000000000..369d2c5460 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchV2RequestHeader.java @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageBatchV2RequestHeader extends Header { + + //request code + private String code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + //protocol type, cloudevents or eventmeshMessage + private String protocolType; + + //protocol version, cloudevents:1.0 or 0.3 + private String protocolVersion; + + //protocol desc + private String protocolDesc; + + //the environment number of the requester + private String env; + + //the IDC of the requester + private String idc; + + //subsystem of the requester + private String sys; + + //PID of the requester + private String pid; + + //IP of the requester + private String ip; + + //USERNAME of the requester + private String username; + + //PASSWD of the requester + private String passwd; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } + + public String getProtocolVersion() { + return protocolVersion; + } + + public void setProtocolVersion(String protocolVersion) { + this.protocolVersion = protocolVersion; + } + + public String getProtocolDesc() { + return protocolDesc; + } + + public void setProtocolDesc(String protocolDesc) { + this.protocolDesc = protocolDesc; + } + + public static SendMessageBatchV2RequestHeader buildHeader(final Map headerParam) { + SendMessageBatchV2RequestHeader header = new SendMessageBatchV2RequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + header.setProtocolType(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_TYPE)); + header.setProtocolVersion(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_VERSION)); + header.setProtocolDesc(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_DESC)); + + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageBatchV2RequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchV2ResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchV2ResponseHeader.java new file mode 100644 index 0000000000..a188c9713c --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageBatchV2ResponseHeader.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageBatchV2ResponseHeader extends Header { + + //response code, as same as the request code + private int code; + + //The cluster name of the EventMesh that processes the request + private String eventMeshCluster; + + //IP of the EventMesh that processes the request + private String eventMeshIp; + + //Environment number of the EventMesh that processes the request + private String eventMeshEnv; + + //IDC of the EventMesh that processes the request + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static SendMessageBatchV2ResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, + String eventMeshIDC) { + SendMessageBatchV2ResponseHeader header = new SendMessageBatchV2ResponseHeader(); + header.setCode(requestCode); + header.setEventMeshCluster(eventMeshCluster); + header.setEventMeshEnv(eventMeshEnv); + header.setEventMeshIdc(eventMeshIDC); + header.setEventMeshIp(eventMeshIp); + return header; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageBatchV2ResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageRequestHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageRequestHeader.java new file mode 100644 index 0000000000..19774280a4 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageRequestHeader.java @@ -0,0 +1,230 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageRequestHeader extends Header { + + //request code + private String code; + + //requester language description + private String language; + + //protocol version adopted by requester, default:1.0 + private ProtocolVersion version; + + //protocol type, cloudevents or eventmeshMessage + private String protocolType; + + //protocol version, cloudevents:1.0 or 0.3 + private String protocolVersion; + + //protocol desc + private String protocolDesc; + + //the environment number of the requester + private String env; + + //the IDC of the requester + private String idc; + + //subsystem of the requester + private String sys; + + //PID of the requester + private String pid; + + //IP of the requester + private String ip; + + //USERNAME of the requester + private String username; + + //PASSWD of the requester + private String passwd; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ProtocolVersion getVersion() { + return version; + } + + public void setVersion(ProtocolVersion version) { + this.version = version; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getIdc() { + return idc; + } + + public void setIdc(String idc) { + this.idc = idc; + } + + public String getSys() { + return sys; + } + + public void setSys(String sys) { + this.sys = sys; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } + + public String getProtocolVersion() { + return protocolVersion; + } + + public void setProtocolVersion(String protocolVersion) { + this.protocolVersion = protocolVersion; + } + + public String getProtocolDesc() { + return protocolDesc; + } + + public void setProtocolDesc(String protocolDesc) { + this.protocolDesc = protocolDesc; + } + + public static SendMessageRequestHeader buildHeader(Map headerParam) { + SendMessageRequestHeader header = new SendMessageRequestHeader(); + header.setCode(MapUtils.getString(headerParam, ProtocolKey.REQUEST_CODE)); + header.setVersion(ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION))); + header.setProtocolType(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_TYPE)); + header.setProtocolVersion(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_VERSION)); + header.setProtocolDesc(MapUtils.getString(headerParam, ProtocolKey.PROTOCOL_DESC)); + + String lan = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + header.setLanguage(lan); + header.setEnv(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.ENV)); + header.setIdc(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IDC)); + header.setSys(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.SYS)); + header.setPid(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PID)); + header.setIp(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.IP)); + header.setUsername(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.USERNAME)); + header.setPasswd(MapUtils.getString(headerParam, ProtocolKey.ClientInstanceKey.PASSWD)); + return header; + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.LANGUAGE, language); + map.put(ProtocolKey.VERSION, version); + map.put(ProtocolKey.ClientInstanceKey.ENV, env); + map.put(ProtocolKey.ClientInstanceKey.IDC, idc); + map.put(ProtocolKey.ClientInstanceKey.SYS, sys); + map.put(ProtocolKey.ClientInstanceKey.PID, pid); + map.put(ProtocolKey.ClientInstanceKey.IP, ip); + map.put(ProtocolKey.ClientInstanceKey.USERNAME, username); + map.put(ProtocolKey.ClientInstanceKey.PASSWD, passwd); + return map; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageRequestHeader={") + .append("code=").append(code).append(",") + .append("language=").append(language).append(",") + .append("version=").append(version).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("sys=").append(sys).append(",") + .append("pid=").append(pid).append(",") + .append("ip=").append(ip).append(",") + .append("username=").append(username).append(",") + .append("passwd=").append(passwd).append("}"); + return sb.toString(); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageResponseHeader.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageResponseHeader.java new file mode 100644 index 0000000000..a9db7ff587 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/header/message/SendMessageResponseHeader.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +public class SendMessageResponseHeader extends Header { + + //response code, as same as the request code + private int code; + + //The cluster name of the EventMesh that processes the request + private String eventMeshCluster; + + //IP of the EventMesh that processes the request + private String eventMeshIp; + + //Environment number of the EventMesh that processes the request + private String eventMeshEnv; + + //IDC of the EventMesh that processes the request + private String eventMeshIdc; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getEventMeshCluster() { + return eventMeshCluster; + } + + public void setEventMeshCluster(String eventMeshCluster) { + this.eventMeshCluster = eventMeshCluster; + } + + public String getEventMeshIp() { + return eventMeshIp; + } + + public void setEventMeshIp(String eventMeshIp) { + this.eventMeshIp = eventMeshIp; + } + + public String getEventMeshEnv() { + return eventMeshEnv; + } + + public void setEventMeshEnv(String eventMeshEnv) { + this.eventMeshEnv = eventMeshEnv; + } + + public String getEventMeshIdc() { + return eventMeshIdc; + } + + public void setEventMeshIdc(String eventMeshIdc) { + this.eventMeshIdc = eventMeshIdc; + } + + public static SendMessageResponseHeader buildHeader(Integer requestCode, String eventMeshCluster, + String eventMeshIp, String eventMeshEnv, + String eventMeshIDC) { + SendMessageResponseHeader sendMessageResponseHeader = new SendMessageResponseHeader(); + sendMessageResponseHeader.setCode(requestCode); + sendMessageResponseHeader.setEventMeshCluster(eventMeshCluster); + sendMessageResponseHeader.setEventMeshIp(eventMeshIp); + sendMessageResponseHeader.setEventMeshEnv(eventMeshEnv); + sendMessageResponseHeader.setEventMeshIdc(eventMeshIDC); + return sendMessageResponseHeader; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageResponseHeader={") + .append("code=").append(code).append(",") + .append("eventMeshEnv=").append(eventMeshEnv).append(",") + .append("eventMeshIdc=").append(eventMeshIdc).append(",") + .append("eventMeshCluster=").append(eventMeshCluster).append(",") + .append("eventMeshIp=").append(eventMeshIp).append("}"); + return sb.toString(); + } + + @Override + public Map toMap() { + Map map = new HashMap(); + map.put(ProtocolKey.REQUEST_CODE, code); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshCluster); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshIp); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshEnv); + map.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshIdc); + return map; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Command.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Command.java new file mode 100644 index 0000000000..6381f29413 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Command.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + +public enum Command { + + //heartbeat + HEARTBEAT_REQUEST(0), //client send heartbeat packet to server + HEARTBEAT_RESPONSE(1), //server response heartbeat packet of client + + //handshake + HELLO_REQUEST(2), //client send handshake request to server + HELLO_RESPONSE(3), //server response handshake request of client + + //disconnection + CLIENT_GOODBYE_REQUEST(4), //Notify server when client actively disconnects + CLIENT_GOODBYE_RESPONSE(5), //Server replies to client's active disconnection notification + SERVER_GOODBYE_REQUEST(6), //Notify client when server actively disconnects + SERVER_GOODBYE_RESPONSE(7), //Client replies to server's active disconnection notification + + //subscription management + SUBSCRIBE_REQUEST(8), //Subscription request sent by client to server + SUBSCRIBE_RESPONSE(9), //Server replies to client's subscription request + UNSUBSCRIBE_REQUEST(10), //Unsubscribe request from client to server + UNSUBSCRIBE_RESPONSE(11), //Server replies to client's unsubscribe request + + //monitor + LISTEN_REQUEST(12), //Request from client to server to start topic listening + LISTEN_RESPONSE(13), //The server replies to the client's listening request + + //RR + REQUEST_TO_SERVER(14), //The client sends the RR request to the server + REQUEST_TO_CLIENT(15), //The server pushes the RR request to the client + REQUEST_TO_CLIENT_ACK(16), //After receiving RR request, the client sends ACK to the server + RESPONSE_TO_SERVER(17), //The client sends the RR packet back to the server + RESPONSE_TO_CLIENT(18), //The server pushes the RR packet back to the client + RESPONSE_TO_CLIENT_ACK(19), //After receiving the return packet, the client sends ACK to the server + + //Asynchronous events + ASYNC_MESSAGE_TO_SERVER(20), //The client sends asynchronous events to the server + ASYNC_MESSAGE_TO_SERVER_ACK(21), //After receiving the asynchronous event, the server sends ack to the client + ASYNC_MESSAGE_TO_CLIENT(22), //The server pushes asynchronous events to the client + ASYNC_MESSAGE_TO_CLIENT_ACK(23), //After the client receives the asynchronous event, the ACK is sent to the server + + //radio broadcast + BROADCAST_MESSAGE_TO_SERVER(24), //The client sends the broadcast message to the server + BROADCAST_MESSAGE_TO_SERVER_ACK(25), //After receiving the broadcast message, the server sends ACK to the client + BROADCAST_MESSAGE_TO_CLIENT(26), //The server pushes the broadcast message to the client + BROADCAST_MESSAGE_TO_CLIENT_ACK(27), //After the client receives the broadcast message, the ACK is sent to the server + + //Log reporting + SYS_LOG_TO_LOGSERVER(28), //Business log reporting + + //RMB tracking log reporting + TRACE_LOG_TO_LOGSERVER(29), //RMB tracking log reporting + + //Redirecting instruction + REDIRECT_TO_CLIENT(30), //The server pushes the redirection instruction to the client + + //service register + REGISTER_REQUEST(31), //Client sends registration request to server + REGISTER_RESPONSE(32), //The server sends the registration result to the client + + //service unregister + UNREGISTER_REQUEST(33), //The client sends a de registration request to the server + UNREGISTER_RESPONSE(34), //The server will register the result to the client + + //The client asks which EventMesh to recommend + RECOMMEND_REQUEST(35), //Client sends recommendation request to server + RECOMMEND_RESPONSE(36); //The server will recommend the results to the client + + private final byte value; + + Command(int value) { + this.value = (byte) value; + } + + public byte value() { + return this.value; + } + + public static Command valueOf(int value) { + for (Command t : Command.values()) { + if (t.value == value) { + return t; + } + } + throw new IllegalArgumentException("No enum constant value=" + value); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/EventMeshMessage.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/EventMeshMessage.java new file mode 100644 index 0000000000..945824074c --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/EventMeshMessage.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EventMeshMessage { + + private String topic; + private Map properties = new ConcurrentHashMap<>(); + private String body; +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Header.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Header.java new file mode 100644 index 0000000000..9c9a2890bc --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Header.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + +import java.util.HashMap; +import java.util.Map; + +import lombok.Data; + +@Data +public class Header { + + private Command cmd; + private int code; + private String desc; + private String seq; + private Map properties = new HashMap<>(); + + public Header() { + } + + public Header(Command cmd, int code, String desc, String seq) { + this.cmd = cmd; + this.code = code; + this.desc = desc; + this.seq = seq; + } + + public Header(int code, String desc, String seq, Map properties) { + this.code = code; + this.desc = desc; + this.seq = seq; + this.properties = properties; + } + + + public void putProperty(final String name, final Object value) { + if (null == this.properties) { + this.properties = new HashMap<>(); + } + + this.properties.put(name, value); + } + + public Object getProperty(final String name) { + if (null == this.properties) { + return null; + } + return this.properties.get(name); + } + + public String getStringProperty(final String name) { + Object property = getProperty(name); + if (null == property) { + return null; + } + return property.toString(); + } + + public Command getCommand() { + return this.cmd; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/OPStatus.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/OPStatus.java new file mode 100644 index 0000000000..4ecfd04dbc --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/OPStatus.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + +public enum OPStatus { + + SUCCESS(0, "success"), + FAIL(1, "fail"), + ACL_FAIL(2, "aclFail"), + TPS_OVERLOAD(3, "tpsOverload"); + + OPStatus(Integer code, String desc) { + this.code = code; + this.desc = desc; + } + + private Integer code; + + private String desc; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Package.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Package.java new file mode 100644 index 0000000000..43c5d1a100 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Package.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Package implements ProtocolTransportObject { + + private Header header; + private Object body; + + public Package(Header header) { + this.header = header; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/RedirectInfo.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/RedirectInfo.java new file mode 100644 index 0000000000..8b552bfd20 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/RedirectInfo.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + +public class RedirectInfo { + private String ip; + private int port; + + public RedirectInfo() { + } + + public RedirectInfo(String ip, int port) { + this.ip = ip; + this.port = port; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + @Override + public String toString() { + return "RedirectInfo{" + + "ip='" + ip + + '\'' + + ", port=" + port + + '}'; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Subscription.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Subscription.java new file mode 100644 index 0000000000..ad9f269417 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/Subscription.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; + +import java.util.LinkedList; +import java.util.List; + +public class Subscription { + + private List topicList = new LinkedList<>(); + + public Subscription() { + } + + public Subscription(List topicList) { + this.topicList = topicList; + } + + public List getTopicList() { + return topicList; + } + + public void setTopicList(List topicList) { + this.topicList = topicList; + } + + @Override + public String toString() { + return "Subscription{" + + "topicList=" + topicList + + '}'; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/UserAgent.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/UserAgent.java new file mode 100644 index 0000000000..9e1d98b9b3 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/UserAgent.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp; + +import java.util.Objects; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class UserAgent { + + private String env; + private String subsystem; + private String path; + private int pid; + private String host; + private int port; + private String version; + private String username; + private String password; + private String idc; + private String group; + private String purpose; + @Builder.Default + private int unack = 0; + + public UserAgent() { + } + + public UserAgent(String env, String subsystem, String path, int pid, String host, int port, String version, + String username, String password, String idc, String group, String purpose, int unack) { + this.env = env; + this.subsystem = subsystem; + this.path = path; + this.pid = pid; + this.host = host; + this.port = port; + this.version = version; + this.username = username; + this.password = password; + this.idc = idc; + this.group = group; + this.purpose = purpose; + this.unack = unack; + } + + @Override + public String toString() { + return String.format( + "UserAgent{env='%s', subsystem='%s', group='%s', path='%s', pid=%d, host='%s'," + + " port=%d, version='%s', idc='%s', purpose='%s', unack='%d'}", + env, subsystem, group, path, pid, host, port, version, idc, purpose, unack); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + UserAgent userAgent = (UserAgent) o; + + if (pid != userAgent.pid) { + return false; + } + + if (port != userAgent.port) { + return false; + } + + if (unack != userAgent.unack) { + return false; + } + + if (!Objects.equals(subsystem, userAgent.subsystem)) { + return false; + } + + if (!Objects.equals(group, userAgent.group)) { + return false; + } + + + if (!Objects.equals(path, userAgent.path)) { + return false; + } + + if (!Objects.equals(host, userAgent.host)) { + return false; + } + + if (!Objects.equals(purpose, userAgent.purpose)) { + return false; + } + + if (!Objects.equals(version, userAgent.version)) { + return false; + } + + if (!Objects.equals(username, userAgent.username)) { + return false; + } + + if (!Objects.equals(password, userAgent.password)) { + return false; + } + + if (!Objects.equals(env, userAgent.env)) { + return false; + } + + return Objects.equals(idc, userAgent.idc); + } + + @Override + public int hashCode() { + int result = subsystem != null ? subsystem.hashCode() : 0; + result = 31 * result + (group != null ? group.hashCode() : 0); + result = 31 * result + (path != null ? path.hashCode() : 0); + result = 31 * result + pid; + result = 31 * result + (host != null ? host.hashCode() : 0); + result = 31 * result + (purpose != null ? purpose.hashCode() : 0); + result = 31 * result + port; + result = 31 * result + (version != null ? version.hashCode() : 0); + result = 31 * result + (username != null ? username.hashCode() : 0); + result = 31 * result + (password != null ? password.hashCode() : 0); + result = 31 * result + (idc != null ? idc.hashCode() : 0); + result = 31 * result + (env != null ? env.hashCode() : 0); + result = 31 * result + unack; + return result; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/codec/Codec.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/codec/Codec.java new file mode 100644 index 0000000000..c13e681afc --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/codec/Codec.java @@ -0,0 +1,245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp.codec; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.RedirectInfo; +import org.apache.eventmesh.common.protocol.tcp.Subscription; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.List; +import java.util.TimeZone; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.handler.codec.ReplayingDecoder; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class Codec { + + private static final int FRAME_MAX_LENGTH = 1024 * 1024 * 4; + private static final Charset DEFAULT_CHARSET = Charset.forName(Constants.DEFAULT_CHARSET); + + private static final byte[] CONSTANT_MAGIC_FLAG = serializeBytes("EventMesh"); + private static final byte[] VERSION = serializeBytes("0000"); + + // todo: move to constants + public static final String CLOUD_EVENTS_PROTOCOL_NAME = "cloudevents"; + public static final String EM_MESSAGE_PROTOCOL_NAME = "eventmeshmessage"; + public static final String OPEN_MESSAGE_PROTOCOL_NAME = "openmessage"; + + // todo: use json util + private static ObjectMapper OBJECT_MAPPER; + + static { + OBJECT_MAPPER = new ObjectMapper(); + OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + OBJECT_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + OBJECT_MAPPER.setTimeZone(TimeZone.getDefault()); + } + + public static class Encoder extends MessageToByteEncoder { + @Override + public void encode(ChannelHandlerContext ctx, Package pkg, ByteBuf out) throws Exception { + Preconditions.checkNotNull(pkg, "TcpPackage cannot be null"); + final Header header = pkg.getHeader(); + Preconditions.checkNotNull(header, "TcpPackage header cannot be null", header); + if (log.isDebugEnabled()) { + log.debug("Encoder pkg={}", JsonUtils.serialize(pkg)); + } + + final byte[] headerData = serializeBytes(OBJECT_MAPPER.writeValueAsString(header)); + final byte[] bodyData; + + if (StringUtils.equals(CLOUD_EVENTS_PROTOCOL_NAME, header.getStringProperty(Constants.PROTOCOL_TYPE))) { + bodyData = (byte[]) pkg.getBody(); + } else { + bodyData = serializeBytes(OBJECT_MAPPER.writeValueAsString(pkg.getBody())); + } + + int headerLength = ArrayUtils.getLength(headerData); + int bodyLength = ArrayUtils.getLength(bodyData); + + int length = 4 + 4 + headerLength + bodyLength; + + if (length > FRAME_MAX_LENGTH) { + throw new IllegalArgumentException("message size is exceed limit!"); + } + + out.writeBytes(CONSTANT_MAGIC_FLAG); + out.writeBytes(VERSION); + out.writeInt(length); + out.writeInt(headerLength); + if (headerData != null) { + out.writeBytes(headerData); + } + if (bodyData != null) { + out.writeBytes(bodyData); + } + } + } + + public static class Decoder extends ReplayingDecoder { + @Override + public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + try { + if (null == in) { + return; + } + + byte[] flagBytes = parseFlag(in); + byte[] versionBytes = parseVersion(in); + validateFlag(flagBytes, versionBytes, ctx); + + final int length = in.readInt(); + final int headerLength = in.readInt(); + final int bodyLength = length - 8 - headerLength; + Header header = parseHeader(in, headerLength); + Object body = parseBody(in, header, bodyLength); + + Package pkg = new Package(header, body); + out.add(pkg); + } catch (Exception e) { + log.error("decode error| receive: {}.", deserializeBytes(in.array())); + throw e; + } + } + + private byte[] parseFlag(ByteBuf in) { + final byte[] flagBytes = new byte[CONSTANT_MAGIC_FLAG.length]; + in.readBytes(flagBytes); + return flagBytes; + } + + private byte[] parseVersion(ByteBuf in) { + final byte[] versionBytes = new byte[VERSION.length]; + in.readBytes(versionBytes); + return versionBytes; + } + + private Header parseHeader(ByteBuf in, int headerLength) throws JsonProcessingException { + if (headerLength <= 0) { + return null; + } + final byte[] headerData = new byte[headerLength]; + in.readBytes(headerData); + if (log.isDebugEnabled()) { + log.debug("Decode headerJson={}", deserializeBytes(headerData)); + } + return OBJECT_MAPPER.readValue(deserializeBytes(headerData), Header.class); + } + + private Object parseBody(ByteBuf in, Header header, int bodyLength) throws JsonProcessingException { + if (bodyLength <= 0 || header == null) { + return null; + } + final byte[] bodyData = new byte[bodyLength]; + in.readBytes(bodyData); + if (log.isDebugEnabled()) { + log.debug("Decode bodyJson={}", deserializeBytes(bodyData)); + } + return deserializeBody(deserializeBytes(bodyData), header); + } + + private void validateFlag(byte[] flagBytes, byte[] versionBytes, ChannelHandlerContext ctx) { + if (!Arrays.equals(flagBytes, CONSTANT_MAGIC_FLAG) || !Arrays.equals(versionBytes, VERSION)) { + String errorMsg = String.format( + "invalid magic flag or version|flag=%s|version=%s|remoteAddress=%s", + deserializeBytes(flagBytes), deserializeBytes(versionBytes), ctx.channel().remoteAddress()); + throw new IllegalArgumentException(errorMsg); + } + } + } + + private static Object deserializeBody(String bodyJsonString, Header header) throws JsonProcessingException { + Command command = header.getCmd(); + switch (command) { + case HELLO_REQUEST: + case RECOMMEND_REQUEST: + return OBJECT_MAPPER.readValue(bodyJsonString, UserAgent.class); + case SUBSCRIBE_REQUEST: + case UNSUBSCRIBE_REQUEST: + return OBJECT_MAPPER.readValue(bodyJsonString, Subscription.class); + case REQUEST_TO_SERVER: + case RESPONSE_TO_SERVER: + case ASYNC_MESSAGE_TO_SERVER: + case BROADCAST_MESSAGE_TO_SERVER: + case REQUEST_TO_CLIENT: + case RESPONSE_TO_CLIENT: + case ASYNC_MESSAGE_TO_CLIENT: + case BROADCAST_MESSAGE_TO_CLIENT: + case REQUEST_TO_CLIENT_ACK: + case RESPONSE_TO_CLIENT_ACK: + case ASYNC_MESSAGE_TO_CLIENT_ACK: + case BROADCAST_MESSAGE_TO_CLIENT_ACK: + // The message string will be deserialized by protocol plugin, if the event is cloudevents, the body is + // just a string. + return bodyJsonString; + case REDIRECT_TO_CLIENT: + return OBJECT_MAPPER.readValue(bodyJsonString, RedirectInfo.class); + default: + log.warn("Invalidate TCP command: {}", command); + return null; + } + } + + /** + * Deserialize bytes to String. + * + * @param bytes + * @return + */ + private static String deserializeBytes(byte[] bytes) { + return new String(bytes, DEFAULT_CHARSET); + } + + /** + * Serialize String to bytes. + * + * @param str + * @return + */ + private static byte[] serializeBytes(String str) { + if (str == null) { + return null; + } + return str.getBytes(DEFAULT_CHARSET); + } + + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ConfigurationContextUtil.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ConfigurationContextUtil.java new file mode 100644 index 0000000000..7478970d17 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ConfigurationContextUtil.java @@ -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 org.apache.eventmesh.common.utils; + +import org.apache.eventmesh.common.config.CommonConfiguration; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +import com.google.common.collect.Lists; + +/** + * ConfigurationContextUtil. + */ +public class ConfigurationContextUtil { + + private static final ConcurrentHashMap CONFIGURATION_MAP = new ConcurrentHashMap<>(); + + public static final String HTTP = "HTTP"; + + public static final String TCP = "TCP"; + public static final String GRPC = "GRPC"; + + public static final List KEYS = Lists.newArrayList(HTTP, TCP, GRPC); + + + /** + * Save http, tcp, grpc configuration at startup for global use. + * + * @param key + * @param configuration + */ + public static void putIfAbsent(String key, CommonConfiguration configuration) { + if (Objects.isNull(configuration)) { + return; + } + CONFIGURATION_MAP.putIfAbsent(key, configuration); + } + + /** + * Get the configuration of the specified key mapping. + * + * @param key + * @return + */ + public static CommonConfiguration get(String key) { + return CONFIGURATION_MAP.get(key); + } + + + /** + * Removes all of the mappings from this map. + */ + public static void clear() { + CONFIGURATION_MAP.clear(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/IPUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/IPUtils.java new file mode 100644 index 0000000000..2ee98daed0 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/IPUtils.java @@ -0,0 +1,245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.utils; + +import org.apache.commons.lang3.StringUtils; + +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.NetworkInterface; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.Channel; + +import inet.ipaddr.HostName; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; + +public class IPUtils { + + private static final Logger logger = LoggerFactory.getLogger(IPUtils.class); + + public static String getLocalAddress() { + // if the progress works under docker environment + // return the host ip about this docker located from environment value + String dockerHostIp = System.getenv("docker_host_ip"); + if (dockerHostIp != null && !"".equals(dockerHostIp)) { + return dockerHostIp; + } + + //priority of networkInterface when generating client ip + String priority = System.getProperty("networkInterface.priority", "eth0 preferList = new ArrayList(); + for (String eth : priority.split("<")) { + preferList.add(eth); + } + NetworkInterface preferNetworkInterface = null; + + try { + Enumeration enumeration1 = NetworkInterface.getNetworkInterfaces(); + while (enumeration1.hasMoreElements()) { + final NetworkInterface networkInterface = enumeration1.nextElement(); + if (!preferList.contains(networkInterface.getName())) { + continue; + } else if (preferNetworkInterface == null) { + preferNetworkInterface = networkInterface; + } else if (preferList.indexOf(networkInterface.getName()) //get the networkInterface that has higher priority + > preferList.indexOf(preferNetworkInterface.getName())) { + preferNetworkInterface = networkInterface; + } + } + + // Traversal Network interface to get the first non-loopback and non-private address + ArrayList ipv4Result = new ArrayList(); + ArrayList ipv6Result = new ArrayList(); + + if (preferNetworkInterface != null) { + final Enumeration en = preferNetworkInterface.getInetAddresses(); + getIpResult(ipv4Result, ipv6Result, en); + } else { + Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); + while (enumeration.hasMoreElements()) { + final NetworkInterface networkInterface = enumeration.nextElement(); + final Enumeration en = networkInterface.getInetAddresses(); + getIpResult(ipv4Result, ipv6Result, en); + } + } + + // prefer ipv4 + if (!ipv4Result.isEmpty()) { + for (String ip : ipv4Result) { + if (ip.startsWith("127.0") || ip.startsWith("192.168") || !isValidIPV4Address(ip)) { + continue; + } + + return ip; + } + + return ipv4Result.get(ipv4Result.size() - 1); + } else if (!ipv6Result.isEmpty()) { + return ipv6Result.get(0); + } + //If failed to find,fall back to localhost + final InetAddress localHost = InetAddress.getLocalHost(); + return normalizeHostAddress(localHost); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + return null; + } + + public static boolean isValidIPV4Address(String ip) { + + // Regex for digit from 0 to 255. + String zeroTo255 + = "(\\d{1,2}|(0|1)\\" + + "d{2}|2[0-4]\\d|25[0-5])"; + + String regex + = zeroTo255 + "\\." + + zeroTo255 + "\\." + + zeroTo255 + "\\." + + zeroTo255; + + // Compile the ReGex + Pattern p = Pattern.compile(regex); + + // If the IP address is empty, return false + if (ip == null) { + return false; + } + + Matcher m = p.matcher(ip); + + // Return if the IP address matched the ReGex + return m.matches(); + } + + private static void getIpResult(ArrayList ipv4Result, ArrayList ipv6Result, + Enumeration en) { + while (en.hasMoreElements()) { + final InetAddress address = en.nextElement(); + if (!address.isLoopbackAddress()) { + if (address instanceof Inet6Address) { + ipv6Result.add(normalizeHostAddress(address)); + } else { + ipv4Result.add(normalizeHostAddress(address)); + } + } + } + } + + private static String normalizeHostAddress(final InetAddress localHost) { + if (localHost instanceof Inet6Address) { + return "[" + localHost.getHostAddress() + "]"; + } else { + return localHost.getHostAddress(); + } + } + + + public static String parseChannelRemoteAddr(final Channel channel) { + if (null == channel) { + return ""; + } + SocketAddress remote = channel.remoteAddress(); + final String addr = remote != null ? remote.toString() : ""; + + if (addr.length() > 0) { + int index = addr.lastIndexOf("/"); + if (index >= 0) { + return addr.substring(index + 1); + } + + return addr; + } + + return ""; + } + + public static boolean isValidDomainOrIp(String url, List ipV4ReservedAddrs, List ipV6ReservedAddrs) { + if (StringUtils.isBlank(url)) { + return false; + } + // Engine only need to verify DNS transformed result + if (isValidIp(url)) { + return true; + } + IPAddress ipAddress = domain2Ip(url); + if (ipAddress == null) { + return false; + } + if (ipAddress.isIPv4()) { + return !isReservedIp(ipAddress, ipV4ReservedAddrs); + } else { + return !isReservedIp(ipAddress, ipV6ReservedAddrs); + } + } + + public static boolean isValidIp(String url) { + try { + IPAddressString ipString = new IPAddressString(url); + if (!ipString.isValid()) { + return new IPAddressString(new URL(url).getHost()).isValid(); + } + } catch (Exception e) { + logger.warn("Invalid URL format url={}", url, e); + return false; + } + return true; + } + + public static IPAddress domain2Ip(String url) { + HostName hostName = new HostName(url); + if (hostName.isValid()) { + return hostName.getAddress(); + } + try { + String host = new URL(url).getHost(); + return new HostName(host).getAddress(); + } catch (MalformedURLException e) { + logger.error("Invalid URL format url={}", url, e); + return null; + } + } + + private static boolean isReservedIp(IPAddress ipAddress, List reservedIps) { + for (IPAddress address : reservedIps) { + if (address.contains(ipAddress)) { + return true; + } + } + return false; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java new file mode 100644 index 0000000000..a9c3fc1154 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonUtils.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.utils; + +import org.apache.eventmesh.common.exception.JsonException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * Json serialize or deserialize utils. + */ +public class JsonUtils { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + static { + OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + } + + /** + * Serialize object to json string. + * + * @param obj obj + * @return json string + */ + public static String serialize(Object obj) { + try { + return OBJECT_MAPPER.writeValueAsString(obj); + } catch (JsonProcessingException e) { + throw new JsonException("serialize to json error", e); + } + } + + /** + * Deserialize json string to object. + * + * @param str json string + * @param clz object class + * @param object type + * @return object + */ + public static T deserialize(String str, Class clz) { + try { + return OBJECT_MAPPER.readValue(str, clz); + } catch (JsonProcessingException e) { + throw new JsonException("deserialize json string to object error", e); + } + } + + /** + * Deserialize json string to object. + * + * @param str json string + * @param typeReference object type reference + * @param object type + * @return object + */ + public static T deserialize(String str, TypeReference typeReference) { + try { + return OBJECT_MAPPER.readValue(str, typeReference); + } catch (JsonProcessingException e) { + throw new JsonException("deserialize json string to object error", e); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/RandomStringUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/RandomStringUtils.java new file mode 100644 index 0000000000..bc14554196 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/RandomStringUtils.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.utils; + +import org.apache.commons.text.RandomStringGenerator; + +public class RandomStringUtils { + + private static final RandomStringGenerator RANDOM_NUM_GENERATOR = new RandomStringGenerator.Builder() + .withinRange('0', '9').build(); + + public static String generateNum(int length) { + return RANDOM_NUM_GENERATOR.generate(length); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ThreadUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ThreadUtils.java new file mode 100644 index 0000000000..af69f08508 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ThreadUtils.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.utils; + +import org.apache.logging.log4j.util.ProcessIdUtil; + +import java.util.concurrent.ThreadLocalRandom; + +public class ThreadUtils { + + private static volatile long currentPID = -1; + + public static void randomSleep(int min, int max) throws Exception { + // nextInt is normally exclusive of the top value, so add 1 to make it inclusive + int random = ThreadLocalRandom.current().nextInt(min, max + 1); + Thread.sleep(random); + + } + + public static void randomSleep(int max) throws Exception { + randomSleep(1, max); + } + + /** + * get current process id. + * + * @return process id + */ + public static long getPID() { + if (currentPID == -1) { + synchronized (ThreadUtils.class) { + if (currentPID == -1) { + currentPID = Long.parseLong(ProcessIdUtil.getProcessId()); + } + } + } + return currentPID; + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshMessageTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshMessageTest.java new file mode 100644 index 0000000000..b0df5405f3 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshMessageTest.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class EventMeshMessageTest { + + @Test + public void testGetProp() { + EventMeshMessage message = createLiteMessage(); + Assert.assertEquals(2L, message.getProp().size()); + } + + @Test + public void testSetProp() { + EventMeshMessage message = createLiteMessage(); + Map prop = new HashMap<>(); + prop.put("key3", "value3"); + message.setProp(prop); + Assert.assertEquals(1L, message.getProp().size()); + Assert.assertEquals("value3", message.getProp("key3")); + } + + @Test + public void testAddProp() { + EventMeshMessage message = createLiteMessage(); + message.addProp("key3", "value3"); + Assert.assertEquals(3L, message.getProp().size()); + Assert.assertEquals("value1", message.getProp("key1")); + } + + @Test + public void testGetPropKey() { + EventMeshMessage message = createLiteMessage(); + Assert.assertEquals("value1", message.getProp("key1")); + } + + @Test + public void testRemoveProp() { + EventMeshMessage message = createLiteMessage(); + message.removePropIfPresent("key1"); + Assert.assertEquals(1L, message.getProp().size()); + Assert.assertNull(message.getProp("key1")); + } + + private EventMeshMessage createLiteMessage() { + Map prop = new HashMap<>(); + prop.put("key1", "value1"); + prop.put("key2", "value2"); + return EventMeshMessage.builder() + .prop(prop) + .build(); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/CommonConfigurationTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/CommonConfigurationTest.java new file mode 100644 index 0000000000..68ee8659ca --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/CommonConfigurationTest.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config; + +import java.io.File; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class CommonConfigurationTest { + + private CommonConfiguration configuration; + + @Before + public void before() { + String file = ConfigurationWrapperTest.class.getResource("/configuration.properties").getFile(); + File f = new File(file); + ConfigurationWrapper wraper = new ConfigurationWrapper(f.getParent(), f.getName(), false); + configuration = new CommonConfiguration(wraper); + } + + @Test + public void testInit() { + configuration.init(); + Assert.assertEquals("value1", configuration.eventMeshEnv); + Assert.assertEquals("value2", configuration.eventMeshIDC); + Assert.assertEquals("3", configuration.sysID); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/ConfigurationWrapperTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/ConfigurationWrapperTest.java new file mode 100644 index 0000000000..73503dc1ea --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/ConfigurationWrapperTest.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config; + +import java.io.File; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ConfigurationWrapperTest { + + private ConfigurationWrapper wraper; + + @Before + public void before() { + String file = ConfigurationWrapperTest.class.getResource("/configuration.properties").getFile(); + File f = new File(file); + wraper = new ConfigurationWrapper(f.getParent(), f.getName(), false); + } + + @Test + public void testGetProp() { + Assert.assertEquals("value1", wraper.getProp("eventMesh.server.env")); + Assert.assertEquals("value2", wraper.getProp("eventMesh.server.idc")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/file/WatchFileManagerTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/file/WatchFileManagerTest.java new file mode 100644 index 0000000000..614138a4a3 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/file/WatchFileManagerTest.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.file; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Properties; + +import org.junit.Assert; +import org.junit.Test; + +public class WatchFileManagerTest { + + @Test + public void testWatchFile() throws IOException, InterruptedException { + String file = WatchFileManagerTest.class.getResource("/configuration.properties").getFile(); + File f = new File(file); + final FileChangeListener fileChangeListener = new FileChangeListener() { + @Override + public void onChanged(FileChangeContext changeContext) { + Assert.assertEquals(f.getName(), changeContext.getFileName()); + Assert.assertEquals(f.getParent(), changeContext.getDirectoryPath()); + } + + @Override + public boolean support(FileChangeContext changeContext) { + return changeContext.getWatchEvent().context().toString().contains(f.getName()); + } + }; + WatchFileManager.registerFileChangeListener(f.getParent(), fileChangeListener); + + Properties properties = new Properties(); + properties.load(new BufferedReader(new FileReader(file))); + properties.setProperty("eventMesh.server.newAdd", "newAdd"); + FileWriter fw = new FileWriter(file); + properties.store(fw, "newAdd"); + + Thread.sleep(500); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/RandomLoadBalanceSelectorTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/RandomLoadBalanceSelectorTest.java new file mode 100644 index 0000000000..728244117d --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/RandomLoadBalanceSelectorTest.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RandomLoadBalanceSelectorTest { + + private RandomLoadBalanceSelector randomLoadBalanceSelector; + + private Logger logger = LoggerFactory.getLogger(RandomLoadBalanceSelectorTest.class); + + @Before + public void befor() { + List address = new ArrayList<>(); + address.add("A"); + address.add("B"); + address.add("C"); + randomLoadBalanceSelector = new RandomLoadBalanceSelector<>(address); + } + + + @Test + public void testSelect() { + Map addressToNum = new HashMap<>(); + for (int i = 0; i < 100; i++) { + String select = randomLoadBalanceSelector.select(); + addressToNum.put(select, addressToNum.getOrDefault(select, 0) + 1); + } + addressToNum.forEach((key, value) -> logger.info("{} : {}", key, value)); + // just assert success if no exception + Assert.assertTrue(true); + } + + @Test + public void testGetType() { + Assert.assertEquals(LoadBalanceType.RANDOM, randomLoadBalanceSelector.getType()); + } +} \ No newline at end of file diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightRandomLoadBalanceSelectorTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightRandomLoadBalanceSelectorTest.java new file mode 100644 index 0000000000..beb5e659e1 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightRandomLoadBalanceSelectorTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.summingInt; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.IntStream; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WeightRandomLoadBalanceSelectorTest { + + private Logger logger = LoggerFactory.getLogger(WeightRandomLoadBalanceSelectorTest.class); + + @Test + public void testSelect() throws Exception { + List> weightList = new ArrayList<>(); + weightList.add(new Weight<>("192.168.0.1", 10)); + weightList.add(new Weight<>("192.168.0.2", 20)); + weightList.add(new Weight<>("192.168.0.3", 40)); + WeightRandomLoadBalanceSelector weightRandomLoadBalanceSelector = new WeightRandomLoadBalanceSelector<>(weightList); + Assert.assertEquals(LoadBalanceType.WEIGHT_RANDOM, weightRandomLoadBalanceSelector.getType()); + int testRange = 100_000; + Map addressToNum = IntStream.range(0, testRange) + .mapToObj(i -> weightRandomLoadBalanceSelector.select()) + .collect(groupingBy(Function.identity(), summingInt(i -> 1))); + + addressToNum.forEach((key, value) -> { + logger.info("{}: {}", key, value); + }); + System.out.printf(addressToNum.toString()); + // the error less than 5% + Assert.assertTrue(Math.abs(addressToNum.get("192.168.0.3") - addressToNum.get("192.168.0.2") * 2) < testRange / 20); + Assert.assertTrue(Math.abs(addressToNum.get("192.168.0.3") - addressToNum.get("192.168.0.1") * 4) < testRange / 20); + } + + @Test + public void testSameWeightSelect() throws Exception { + List> weightList = new ArrayList<>(); + weightList.add(new Weight<>("192.168.0.1", 10)); + weightList.add(new Weight<>("192.168.0.2", 10)); + weightList.add(new Weight<>("192.168.0.3", 10)); + WeightRandomLoadBalanceSelector weightRandomLoadBalanceSelector = new WeightRandomLoadBalanceSelector<>(weightList); + Assert.assertEquals(LoadBalanceType.WEIGHT_RANDOM, weightRandomLoadBalanceSelector.getType()); + + int testRange = 100_000; + Map addressToNum = IntStream.range(0, testRange) + .mapToObj(i -> weightRandomLoadBalanceSelector.select()) + .collect(groupingBy(Function.identity(), summingInt(i -> 1))); + + Field field = WeightRandomLoadBalanceSelector.class.getDeclaredField("sameWeightGroup"); + field.setAccessible(true); + boolean sameWeightGroup = (boolean) field.get(weightRandomLoadBalanceSelector); + Assert.assertTrue(sameWeightGroup); + + addressToNum.forEach((key, value) -> { + logger.info("{}: {}", key, value); + }); + // the error less than 5% + Assert.assertTrue(Math.abs(addressToNum.get("192.168.0.3") - addressToNum.get("192.168.0.2")) < testRange / 20); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightRoundRobinLoadBalanceSelectorTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightRoundRobinLoadBalanceSelectorTest.java new file mode 100644 index 0000000000..cf43ee48ef --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightRoundRobinLoadBalanceSelectorTest.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WeightRoundRobinLoadBalanceSelectorTest { + + private Logger logger = LoggerFactory.getLogger(WeightRoundRobinLoadBalanceSelectorTest.class); + + private WeightRoundRobinLoadBalanceSelector weightRoundRobinLoadBalanceSelector; + + @Before + public void before() { + List> weightList = new ArrayList<>(); + weightList.add(new Weight<>("A", 10)); + weightList.add(new Weight<>("B", 20)); + weightList.add(new Weight<>("C", 30)); + weightRoundRobinLoadBalanceSelector = new WeightRoundRobinLoadBalanceSelector<>(weightList); + } + + @Test + public void testSelect() { + Map addressToNum = new HashMap<>(); + for (int i = 0; i < 100_000; i++) { + String select = weightRoundRobinLoadBalanceSelector.select(); + addressToNum.put(select, addressToNum.getOrDefault(select, 0) + 1); + } + addressToNum.forEach((key, value) -> { + logger.info("{}: {}", key, value); + }); + Assert.assertTrue(addressToNum.get("B") > addressToNum.get("A")); + Assert.assertTrue(addressToNum.get("C") > addressToNum.get("B")); + } + + @Test + public void testGetType() { + Assert.assertEquals(LoadBalanceType.WEIGHT_ROUND_ROBIN, weightRoundRobinLoadBalanceSelector.getType()); + } +} \ No newline at end of file diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightTest.java new file mode 100644 index 0000000000..bdf7a845f2 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/loadbalance/WeightTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.loadbalance; + +import org.junit.Assert; +import org.junit.Test; + +public class WeightTest { + + @Test + public void testDecreaseTotal() { + Weight weight = new Weight(null, 0); + weight.decreaseTotal(1); + Assert.assertEquals(-1, weight.getCurrentWeight().get()); + } + + @Test + public void testIncreaseCurrentWeight() { + Weight weight = new Weight(null, 10); + weight.increaseCurrentWeight(); + Assert.assertEquals(10, weight.getCurrentWeight().get()); + } + + @Test + public void testGetCurrentWeight() { + Weight weight = new Weight(null, 0); + Assert.assertEquals(0, weight.getCurrentWeight().get()); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/HttpCommandTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/HttpCommandTest.java new file mode 100644 index 0000000000..962d6c7a79 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/HttpCommandTest.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http; + +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; + +@RunWith(MockitoJUnitRunner.class) +public class HttpCommandTest { + + @Mock + private Header header; + + @Mock + private Body body; + + private HttpCommand httpCommand; + + @Before + public void before() { + httpCommand = new HttpCommand("POST", "1.1", "200"); + } + + @Test + public void testCreateHttpCommandResponseWithHeaderAndBody() { + HttpCommand command = httpCommand.createHttpCommandResponse(header, body); + Map headerMap = new HashMap<>(); + headerMap.put("key1", "value1"); + when(header.toMap()).thenReturn(headerMap); + Assert.assertEquals("1.1", command.getHttpVersion()); + Assert.assertEquals("POST", command.getHttpMethod()); + Assert.assertEquals("200", command.getRequestCode()); + Assert.assertEquals("value1", command.getHeader().toMap().get("key1")); + } + + @Test + public void testAbstractDesc() { + HttpCommand command = httpCommand.createHttpCommandResponse(header, body); + String desc = command.abstractDesc(); + Assert.assertTrue(desc.startsWith("httpCommand")); + } + + @Test + public void testSimpleDesc() { + HttpCommand command = httpCommand.createHttpCommandResponse(header, body); + String desc = command.simpleDesc(); + Assert.assertTrue(desc.startsWith("httpCommand")); + } + + @Test + public void testHttpResponse() throws Exception { + HttpCommand command = httpCommand.createHttpCommandResponse(header, body); + DefaultFullHttpResponse response = command.httpResponse(); + Assert.assertEquals("keep-alive", response.headers().get(HttpHeaderNames.CONNECTION)); + } + + @Test + public void testHttpResponseWithREQCmdType() throws Exception { + DefaultFullHttpResponse response = httpCommand.httpResponse(); + Assert.assertNull(response); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBodyTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBodyTest.java new file mode 100644 index 0000000000..4a8850ba09 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/body/BaseResponseBodyTest.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.body; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.junit.Assert; +import org.junit.Test; + +public class BaseResponseBodyTest { + + @Test + public void testToMap() { + BaseResponseBody body = new BaseResponseBody(); + body.setRetCode(200); + body.setRetMsg("SUCCESS"); + Assert.assertTrue(body.toMap().containsKey(ProtocolKey.RETCODE)); + Assert.assertTrue(body.toMap().containsKey(ProtocolKey.RETMSG)); + Assert.assertTrue(body.toMap().containsKey(ProtocolKey.RESTIME)); + Assert.assertThat(body.toMap().get(ProtocolKey.RETCODE), is(200)); + Assert.assertThat(body.toMap().get(ProtocolKey.RETMSG), is("SUCCESS")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/BaseRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/BaseRequestHeaderTest.java new file mode 100644 index 0000000000..4768963908 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/BaseRequestHeaderTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header; + + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class BaseRequestHeaderTest { + + @Test + public void testToMap() { + Map headerParam = new HashMap<>(); + headerParam.put(ProtocolKey.REQUEST_CODE, "200"); + BaseRequestHeader header = BaseRequestHeader.buildHeader(headerParam); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is("200")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/BaseResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/BaseResponseHeaderTest.java new file mode 100644 index 0000000000..23dc6540be --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/BaseResponseHeaderTest.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.junit.Assert; +import org.junit.Test; + +public class BaseResponseHeaderTest { + + @Test + public void testToMap() { + BaseResponseHeader header = BaseResponseHeader.buildHeader("200"); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is("200")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/AbstractRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/AbstractRequestHeaderTest.java new file mode 100644 index 0000000000..0726e6f07f --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/AbstractRequestHeaderTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.junit.Assert; + +public class AbstractRequestHeaderTest { + + public void assertMapContent(Header header) { + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.LANGUAGE)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.VERSION)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.ENV)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.IDC)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.SYS)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.PID)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.IP)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.USERNAME)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.PASSWD)); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/AbstractResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/AbstractResponseHeaderTest.java new file mode 100644 index 0000000000..54e1f0c35d --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/AbstractResponseHeaderTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import org.junit.Assert; + +public class AbstractResponseHeaderTest { + + public void assertMapContent(Header header) { + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV)); + Assert.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC)); + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is(200)); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER), is("CLUSTER")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP), is("127.0.0.1")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV), is("DEV")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC), is("IDC")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatRequestHeaderTest.java new file mode 100644 index 0000000000..c09359e3f5 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatRequestHeaderTest.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + + +import java.util.HashMap; + +import org.junit.Test; + +public class HeartbeatRequestHeaderTest extends AbstractRequestHeaderTest { + + @Test + public void testToMap() { + HeartbeatRequestHeader header = HeartbeatRequestHeader.buildHeader(new HashMap<>()); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatResponseHeaderTest.java new file mode 100644 index 0000000000..a437b8f707 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/HeartbeatResponseHeaderTest.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.junit.Test; + +public class HeartbeatResponseHeaderTest extends AbstractResponseHeaderTest { + + @Test + public void testToMap() { + HeartbeatResponseHeader header = HeartbeatResponseHeader.buildHeader(200, + "CLUSTER", "127.0.0.1", "DEV", "IDC"); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/RegRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/RegRequestHeaderTest.java new file mode 100644 index 0000000000..24f7eb3855 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/RegRequestHeaderTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import java.util.HashMap; + +import org.junit.Test; + +public class RegRequestHeaderTest extends AbstractRequestHeaderTest { + + @Test + public void testToMap() { + RegRequestHeader header = RegRequestHeader.buildHeader(new HashMap<>()); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/RegResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/RegResponseHeaderTest.java new file mode 100644 index 0000000000..503c6425ed --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/RegResponseHeaderTest.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.junit.Test; + +public class RegResponseHeaderTest extends AbstractResponseHeaderTest { + + @Test + public void testToMap() { + RegResponseHeader header = RegResponseHeader.buildHeader(200, + "CLUSTER", "127.0.0.1", "DEV", "IDC"); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeRequestHeaderTest.java new file mode 100644 index 0000000000..af79ff03fe --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeRequestHeaderTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import java.util.HashMap; + +import org.junit.Test; + +public class SubscribeRequestHeaderTest extends AbstractRequestHeaderTest { + + @Test + public void testToMap() { + SubscribeRequestHeader header = SubscribeRequestHeader.buildHeader(new HashMap<>()); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeResponseHeaderTest.java new file mode 100644 index 0000000000..9d646338dd --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/SubscribeResponseHeaderTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + + +import org.junit.Test; + +public class SubscribeResponseHeaderTest extends AbstractResponseHeaderTest { + + @Test + public void testToMap() { + SubscribeResponseHeader header = SubscribeResponseHeader.buildHeader(200, + "CLUSTER", "127.0.0.1", "DEV", "IDC"); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegRequestHeaderTest.java new file mode 100644 index 0000000000..50b8e8d6ea --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegRequestHeaderTest.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + + +import java.util.HashMap; + +import org.junit.Test; + +public class UnRegRequestHeaderTest extends AbstractRequestHeaderTest { + + @Test + public void testToMap() { + UnRegRequestHeader header = UnRegRequestHeader.buildHeader(new HashMap<>()); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegResponseHeaderTest.java new file mode 100644 index 0000000000..0c7b016417 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnRegResponseHeaderTest.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import org.junit.Test; + +public class UnRegResponseHeaderTest extends AbstractResponseHeaderTest { + + @Test + public void testToMap() { + UnRegResponseHeader header = UnRegResponseHeader.buildHeader(200, + "CLUSTER", "127.0.0.1", "DEV", "IDC"); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeRequestHeaderTest.java new file mode 100644 index 0000000000..562d92d83d --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeRequestHeaderTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + +import java.util.HashMap; + +import org.junit.Test; + +public class UnSubscribeRequestHeaderTest extends AbstractRequestHeaderTest { + + @Test + public void testToMap() { + UnSubscribeRequestHeader header = UnSubscribeRequestHeader.buildHeader(new HashMap<>()); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeResponseHeaderTest.java new file mode 100644 index 0000000000..3e8cb70ed4 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/client/UnSubscribeResponseHeaderTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.client; + + +import org.junit.Test; + +public class UnSubscribeResponseHeaderTest extends AbstractResponseHeaderTest { + + @Test + public void testToMap() { + UnSubscribeResponseHeader header = UnSubscribeResponseHeader.buildHeader(200, + "CLUSTER", "127.0.0.1", "DEV", "IDC"); + assertMapContent(header); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageRequestHeaderTest.java new file mode 100644 index 0000000000..d683789578 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageRequestHeaderTest.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class PushMessageRequestHeaderTest { + + private PushMessageRequestHeader header; + + @Before + public void before() { + Map headerParam = new HashMap<>(); + headerParam.put(ProtocolKey.REQUEST_CODE, 200); + headerParam.put(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA); + headerParam.put(ProtocolKey.VERSION, "1.0"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, "default cluster"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, "127.0.0.1"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, "DEV"); + headerParam.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, "IDC"); + header = PushMessageRequestHeader.buildHeader(headerParam); + } + + @Test + public void testToMap() { + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is(200)); + Assert.assertThat(header.toMap().get(ProtocolKey.LANGUAGE), is(Constants.LANGUAGE_JAVA)); + Assert.assertThat(header.toMap().get(ProtocolKey.VERSION), is(ProtocolVersion.V1)); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER), is("default cluster")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP), is("127.0.0.1")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV), is("DEV")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC), is("IDC")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageResponseHeaderTest.java new file mode 100644 index 0000000000..3446ef0e2d --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/PushMessageResponseHeaderTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; + +import org.junit.Assert; +import org.junit.Test; + +public class PushMessageResponseHeaderTest { + + @Test + public void testToMap() { + PushMessageResponseHeader header = PushMessageResponseHeader.buildHeader(100, "DEV", + "IDC", "SYSID", "PID", "127.0.0.1"); + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is(100)); + Assert.assertThat(header.toMap().get(ProtocolKey.LANGUAGE), is(Constants.LANGUAGE_JAVA)); + Assert.assertThat(header.toMap().get(ProtocolKey.VERSION), is(ProtocolVersion.V1)); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.ENV), is("DEV")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.IDC), is("IDC")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.SYS), is("SYSID")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.PID), is("PID")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.IP), is("127.0.0.1")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageRequestHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageRequestHeaderTest.java new file mode 100644 index 0000000000..eec5d1854d --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageRequestHeaderTest.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ReplyMessageRequestHeaderTest { + + private ReplyMessageRequestHeader header; + + @Before + public void before() { + Map headerParam = new HashMap<>(); + headerParam.put(ProtocolKey.REQUEST_CODE, "200"); + headerParam.put(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA); + headerParam.put(ProtocolKey.VERSION, "1.0"); + headerParam.put(ProtocolKey.ClientInstanceKey.ENV, "DEV"); + headerParam.put(ProtocolKey.ClientInstanceKey.IDC, "IDC"); + headerParam.put(ProtocolKey.ClientInstanceKey.SYS, "SYS"); + headerParam.put(ProtocolKey.ClientInstanceKey.PID, "PID"); + headerParam.put(ProtocolKey.ClientInstanceKey.IP, "127.0.0.1"); + header = ReplyMessageRequestHeader.buildHeader(headerParam); + } + + @Test + public void testToMap() { + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is("200")); + Assert.assertThat(header.toMap().get(ProtocolKey.LANGUAGE), is(Constants.LANGUAGE_JAVA)); + Assert.assertThat(header.toMap().get(ProtocolKey.VERSION), is(ProtocolVersion.V1)); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.ENV), is("DEV")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.IDC), is("IDC")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.SYS), is("SYS")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.PID), is("PID")); + Assert.assertThat(header.toMap().get(ProtocolKey.ClientInstanceKey.IP), is("127.0.0.1")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageResponseHeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageResponseHeaderTest.java new file mode 100644 index 0000000000..a6714a885b --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/message/ReplyMessageResponseHeaderTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.http.header.message; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; + +import org.junit.Assert; +import org.junit.Test; + +public class ReplyMessageResponseHeaderTest { + + @Test + public void testToMap() { + ReplyMessageResponseHeader header = ReplyMessageResponseHeader.buildHeader(100, + "Cluster", "127.0.0.1", "DEV", "IDC"); + Assert.assertThat(header.toMap().get(ProtocolKey.REQUEST_CODE), is(100)); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER), is("Cluster")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP), is("127.0.0.1")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV), is("DEV")); + Assert.assertThat(header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC), is("IDC")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/tcp/codec/CodecTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/tcp/codec/CodecTest.java new file mode 100644 index 0000000000..bb66e5c04b --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/tcp/codec/CodecTest.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.protocol.tcp.codec; + +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import java.util.ArrayList; + +import org.junit.Assert; +import org.junit.Test; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +public class CodecTest { + + @Test + public void testCodec() throws Exception { + Header header = new Header(); + header.setCmd(Command.HELLO_REQUEST); + Package testP = new Package(header); + testP.setBody(new Object()); + Codec.Encoder ce = new Codec.Encoder(); + ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(); + ce.encode(null, testP, buf); + Codec.Decoder cd = new Codec.Decoder(); + ArrayList result = new ArrayList<>(); + cd.decode(null, buf, result); + Assert.assertNotNull(result.get(0)); + Assert.assertEquals(testP.getHeader(), ((Package) result.get(0)).getHeader()); + } + +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/IPUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/IPUtilsTest.java new file mode 100644 index 0000000000..4adff4475d --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/IPUtilsTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.utils; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.contrib.java.lang.system.EnvironmentVariables; + +public class IPUtilsTest { + + @Test + public void testDockerIP() { + EnvironmentVariables environmentVariables = new EnvironmentVariables(); + environmentVariables.set("docker_host_ip", "dockHostIP"); + Assert.assertEquals("dockHostIP", IPUtils.getLocalAddress()); + } + + @Test + public void testLocalhostIP() { + Assert.assertNotNull(IPUtils.getLocalAddress()); + } + +} diff --git a/eventmesh-common/src/test/resources/configuration.properties b/eventmesh-common/src/test/resources/configuration.properties new file mode 100644 index 0000000000..fe3f749a1b --- /dev/null +++ b/eventmesh-common/src/test/resources/configuration.properties @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +eventMesh.server.env=value1 +eventMesh.server.idc=value2 +eventMesh.sysid=3 +eventMesh.server.cluster=value4 +eventMesh.server.name=value5 +eventMesh.server.hostIp=value6 +eventMesh.connector.plugin.type=rocketmq +eventMesh.security.plugin.type=acl +eventMesh.registry.plugin.type=namesrv +eventMesh.registry.plugin.server-addr=127.0.0.1:8848 +eventMesh.registry.plugin.username=nacos +eventMesh.registry.plugin.password=nacos +eventMesh.trace.plugin=zipkin \ No newline at end of file diff --git a/eventmesh-connector-plugin/build.gradle b/eventmesh-connector-plugin/build.gradle new file mode 100644 index 0000000000..d973dcedae --- /dev/null +++ b/eventmesh-connector-plugin/build.gradle @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/build.gradle b/eventmesh-connector-plugin/eventmesh-connector-api/build.gradle new file mode 100644 index 0000000000..8ccfa87825 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/build.gradle @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + api project(":eventmesh-spi") + implementation project(":eventmesh-common") + api 'io.cloudevents:cloudevents-core' + api 'io.dropwizard.metrics:metrics-core' + api "io.dropwizard.metrics:metrics-healthchecks" + api "io.dropwizard.metrics:metrics-annotation" + api "io.dropwizard.metrics:metrics-json" + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/gradle.properties b/eventmesh-connector-plugin/eventmesh-connector-api/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/AbstractContext.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/AbstractContext.java new file mode 100644 index 0000000000..4fa7bd2ecf --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/AbstractContext.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + +/** + * AbstractContext + */ +public interface AbstractContext { +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/AsyncConsumeContext.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/AsyncConsumeContext.java new file mode 100644 index 0000000000..7c1c739cd5 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/AsyncConsumeContext.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + + +public abstract class AsyncConsumeContext { + + public abstract void commit(EventMeshAction action); + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventListener.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventListener.java new file mode 100644 index 0000000000..eede41ca09 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventListener.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + + +import io.cloudevents.CloudEvent; + +/** + * Event listener, registered for consume messages by consumer. + * + *

+ * + * Thread safe requirements: this interface will be invoked by multi threads, + * so users should keep thread safe during the consume process. + * + *

+ */ +public interface EventListener { + + void consume(final CloudEvent cloudEvent, final AsyncConsumeContext context); + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventMeshAction.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventMeshAction.java new file mode 100644 index 0000000000..f783201086 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventMeshAction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + +public enum EventMeshAction { + CommitMessage, + + ReconsumeLater, + + ManualAck +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventMeshAsyncConsumeContext.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventMeshAsyncConsumeContext.java new file mode 100644 index 0000000000..633a5b712b --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/EventMeshAsyncConsumeContext.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + + +public abstract class EventMeshAsyncConsumeContext extends AsyncConsumeContext { + + private AbstractContext abstractContext; + + public AbstractContext getAbstractContext() { + return abstractContext; + } + + public void setAbstractContext(AbstractContext abstractContext) { + this.abstractContext = abstractContext; + } + + public abstract void commit(EventMeshAction action); + +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/LifeCycle.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/LifeCycle.java new file mode 100644 index 0000000000..f5d61de333 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/LifeCycle.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + +import org.apache.eventmesh.api.consumer.Consumer; +import org.apache.eventmesh.api.producer.Producer; + +/** + * The {@code LifeCycle} defines a lifecycle interface for a OMS related service endpoint, + * like {@link Producer}, {@link Consumer}, and so on. + */ +public interface LifeCycle { + + boolean isStarted(); + + boolean isClosed(); + + void start(); + + void shutdown(); +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/RequestReplyCallback.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/RequestReplyCallback.java new file mode 100644 index 0000000000..9fdfa666bf --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/RequestReplyCallback.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + +import io.cloudevents.CloudEvent; + +/** + * RequestReplyCallback + */ +public interface RequestReplyCallback { + + void onSuccess(CloudEvent event); + + void onException(Throwable e); +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/SendCallback.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/SendCallback.java new file mode 100644 index 0000000000..ddbe053d85 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/SendCallback.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.api.producer.Producer; + +import io.cloudevents.CloudEvent; + +/** + * Call back interface used in {@link Producer#publish(CloudEvent, SendCallback)}. + */ +public interface SendCallback { + + void onSuccess(final SendResult sendResult); + + void onException(final OnExceptionContext context); +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/SendResult.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/SendResult.java new file mode 100644 index 0000000000..1a68132c6b --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/SendResult.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api; + +public class SendResult { + private String messageId; + + private String topic; + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + @Override + public String toString() { + return "SendResult[topic=" + topic + ", messageId=" + messageId + ']'; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/connector/ConnectorResourceService.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/connector/ConnectorResourceService.java new file mode 100644 index 0000000000..8b6cff71ca --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/connector/ConnectorResourceService.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.connector; + +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * ConnectorResourceService + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.CONNECTOR) +public interface ConnectorResourceService { + + /** + * Resource initialization in connector,such as,some public threadpool if exist + * + * @throws Exception + */ + void init() throws Exception; + + /** + * Resource release in connector,such as,some public threadpool if exist + * + * @throws Exception + */ + void release() throws Exception; +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/consumer/Consumer.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/consumer/Consumer.java new file mode 100644 index 0000000000..52b1a93d64 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/consumer/Consumer.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.LifeCycle; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.List; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +/** + * Consumer Interface. + */ +@EventMeshSPI(isSingleton = false, eventMeshExtensionType = EventMeshExtensionType.CONNECTOR) +public interface Consumer extends LifeCycle { + + void init(Properties keyValue) throws Exception; + + void updateOffset(List cloudEvents, AbstractContext context); + + //void subscribe(String topic, final EventListener listener) throws Exception; + + void subscribe(String topic) throws Exception; + + void unsubscribe(String topic); + + void registerEventListener(EventListener listener); +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/exception/ConnectorRuntimeException.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/exception/ConnectorRuntimeException.java new file mode 100644 index 0000000000..0efe513652 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/exception/ConnectorRuntimeException.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.exception; + +public class ConnectorRuntimeException extends RuntimeException { + + public ConnectorRuntimeException() { + + } + + public ConnectorRuntimeException(String message) { + super(message); + } + + public ConnectorRuntimeException(Throwable throwable) { + super(throwable); + } + + public ConnectorRuntimeException(String message, Throwable throwable) { + super(message, throwable); + } + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/exception/OnExceptionContext.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/exception/OnExceptionContext.java new file mode 100644 index 0000000000..d51da7a0d1 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/exception/OnExceptionContext.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.exception; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class OnExceptionContext { + + private String messageId; + + private String topic; + + /** + * Detailed exception stack information. + */ + private ConnectorRuntimeException exception; +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/factory/ConnectorPluginFactory.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/factory/ConnectorPluginFactory.java new file mode 100644 index 0000000000..0793634771 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/factory/ConnectorPluginFactory.java @@ -0,0 +1,54 @@ +/* + * Licensed to Apache Software Foundation (ASF) under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.api.factory; + +import org.apache.eventmesh.api.consumer.Consumer; +import org.apache.eventmesh.api.producer.Producer; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +/** + * The factory to get connector {@link Producer} and {@link Consumer} + */ +public class ConnectorPluginFactory { + + /** + * Get MeshMQProducer instance by plugin name + * + * @param connectorPluginName plugin name + * @return MeshMQProducer instance + */ + public static Producer getMeshMQProducer(String connectorPluginName) { + return EventMeshExtensionFactory.getExtension(Producer.class, connectorPluginName); + } + + /** + * Get MeshMQPushConsumer instance by plugin name + * + * @param connectorPluginName plugin name + * @return MeshMQPushConsumer instance + */ + public static Consumer getMeshMQPushConsumer(String connectorPluginName) { + return EventMeshExtensionFactory.getExtension(Consumer.class, connectorPluginName); + } + + private static T getPlugin(Class pluginType, String pluginName) { + return EventMeshExtensionFactory.getExtension(pluginType, pluginName); + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/producer/Producer.java b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/producer/Producer.java new file mode 100644 index 0000000000..d8fd2b6a7f --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/producer/Producer.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.producer; + +import org.apache.eventmesh.api.LifeCycle; +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +/** + * Producer Interface. + */ +@EventMeshSPI(isSingleton = false, eventMeshExtensionType = EventMeshExtensionType.CONNECTOR) +public interface Producer extends LifeCycle { + + void init(Properties properties) throws Exception; + + void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception; + + void sendOneway(final CloudEvent cloudEvent); + + void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception; + + boolean reply(final CloudEvent cloudEvent, final SendCallback sendCallback) throws Exception; + + void checkTopicExist(String topic) throws Exception; + + void setExtFields(); +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/build.gradle b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/build.gradle new file mode 100644 index 0000000000..45e6bdd40c --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/build.gradle @@ -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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' +} + +List rocketmq = [ + "org.apache.rocketmq:rocketmq-client:$rocketmq_version", + "org.apache.rocketmq:rocketmq-broker:$rocketmq_version", + "org.apache.rocketmq:rocketmq-common:$rocketmq_version", + "org.apache.rocketmq:rocketmq-store:$rocketmq_version", + "org.apache.rocketmq:rocketmq-namesrv:$rocketmq_version", + "org.apache.rocketmq:rocketmq-tools:$rocketmq_version", + "org.apache.rocketmq:rocketmq-remoting:$rocketmq_version", + "org.apache.rocketmq:rocketmq-logging:$rocketmq_version", + "org.apache.rocketmq:rocketmq-test:$rocketmq_version", + "org.apache.rocketmq:rocketmq-srvutil:$rocketmq_version", + "org.apache.rocketmq:rocketmq-filter:$rocketmq_version", + "org.apache.rocketmq:rocketmq-acl:$rocketmq_version", + "org.apache.rocketmq:rocketmq-srvutil:$rocketmq_version", + +] + +dependencies { + implementation project(":eventmesh-common") + implementation project(":eventmesh-connector-plugin:eventmesh-connector-api") + implementation rocketmq + + testImplementation project(":eventmesh-connector-plugin:eventmesh-connector-api") + testImplementation project(":eventmesh-common") + + testImplementation "org.mockito:mockito-core" + testImplementation "org.powermock:powermock-module-junit4" + testImplementation "org.powermock:powermock-api-mockito2" + + testImplementation rocketmq + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/gradle.properties b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/gradle.properties new file mode 100644 index 0000000000..2138704df0 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/gradle.properties @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +rocketmq_version=4.9.3 + +pluginType=connector +pluginName=rocketmq \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/admin/command/Command.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/admin/command/Command.java new file mode 100644 index 0000000000..9f3b5e9e60 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/admin/command/Command.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.admin.command; + +import org.apache.eventmesh.connector.rocketmq.config.ClientConfiguration; + +import org.apache.rocketmq.acl.common.AclClientRPCHook; +import org.apache.rocketmq.acl.common.SessionCredentials; +import org.apache.rocketmq.remoting.RPCHook; +import org.apache.rocketmq.tools.admin.DefaultMQAdminExt; + +import java.util.UUID; + +public abstract class Command { + protected DefaultMQAdminExt adminExt; + + protected String nameServerAddr; + protected String clusterName; + + public void init() { + final ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.init(); + + nameServerAddr = clientConfiguration.namesrvAddr; + clusterName = clientConfiguration.clusterName; + String accessKey = clientConfiguration.accessKey; + String secretKey = clientConfiguration.secretKey; + + RPCHook rpcHook = new AclClientRPCHook(new SessionCredentials(accessKey, secretKey)); + adminExt = new DefaultMQAdminExt(rpcHook); + String groupId = UUID.randomUUID().toString(); + adminExt.setAdminExtGroup("admin_ext_group-" + groupId); + adminExt.setNamesrvAddr(nameServerAddr); + } + + public abstract void execute() throws Exception; +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/admin/command/CreateTopicCommand.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/admin/command/CreateTopicCommand.java new file mode 100644 index 0000000000..f1e325e552 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/admin/command/CreateTopicCommand.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.admin.command; + +import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.common.TopicConfig; +import org.apache.rocketmq.tools.command.CommandUtil; + +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CreateTopicCommand extends Command { + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private int numOfQueue = 4; + private int queuePermission = 6; + private String topicName = ""; + + @Override + public void execute() throws Exception { + if (StringUtils.isBlank(topicName)) { + logger.error("Topic name can not be blank."); + throw new Exception("Topic name can not be blank."); + } + try { + init(); + adminExt.start(); + Set brokersAddr = CommandUtil.fetchMasterAddrByClusterName( + adminExt, clusterName); + for (String masterAddr : brokersAddr) { + TopicConfig topicConfig = new TopicConfig(); + topicConfig.setTopicName(topicName); + topicConfig.setReadQueueNums(numOfQueue); + topicConfig.setWriteQueueNums(numOfQueue); + topicConfig.setPerm(queuePermission); + adminExt.createAndUpdateTopicConfig(masterAddr, topicConfig); + logger.info("Topic {} is created for RocketMQ broker {}", topicName, masterAddr); + } + } finally { + adminExt.shutdown(); + } + } + + public int getNumOfQueue() { + return numOfQueue; + } + + public int getQueuePermission() { + return queuePermission; + } + + public String getTopicName() { + return topicName; + } + + public void setTopicName(String topicName) { + this.topicName = topicName; + } + + public void setNumOfQueue(int numOfQueue) { + this.numOfQueue = numOfQueue; + } + + public void setQueuePermission(int permission) { + this.queuePermission = permission; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/RocketMQMessageFactory.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/RocketMQMessageFactory.java new file mode 100644 index 0000000000..24699ef9fe --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/RocketMQMessageFactory.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.cloudevent; + +import org.apache.eventmesh.connector.rocketmq.cloudevent.impl.RocketMQBinaryMessageReader; +import org.apache.eventmesh.connector.rocketmq.cloudevent.impl.RocketMQHeaders; +import org.apache.eventmesh.connector.rocketmq.cloudevent.impl.RocketMQMessageWriter; + +import org.apache.rocketmq.common.message.Message; + +import java.util.Map; + +import javax.annotation.ParametersAreNonnullByDefault; + +import io.cloudevents.core.message.MessageReader; +import io.cloudevents.core.message.MessageWriter; +import io.cloudevents.core.message.impl.MessageUtils; +import io.cloudevents.lang.Nullable; +import io.cloudevents.rw.CloudEventRWException; +import io.cloudevents.rw.CloudEventWriter; + + +@ParametersAreNonnullByDefault +public final class RocketMQMessageFactory { + + private RocketMQMessageFactory() { + // prevent instantiation + } + + public static MessageReader createReader(final Message message) throws CloudEventRWException { + return createReader(message.getProperties(), message.getBody()); + } + + + public static MessageReader createReader(final Map props, + @Nullable final byte[] body) + throws CloudEventRWException { + + return MessageUtils.parseStructuredOrBinaryMessage( + () -> null, + format -> null, + () -> props.get(RocketMQHeaders.SPEC_VERSION), + sv -> new RocketMQBinaryMessageReader(sv, props, body) + ); + } + + + public static MessageWriter, Message> createWriter(String topic) { + return new RocketMQMessageWriter<>(topic); + } + + public static MessageWriter, Message> createWriter(String topic, + String keys) { + return new RocketMQMessageWriter<>(topic, keys); + } + + public static MessageWriter, Message> createWriter(String topic, + String keys, + String tags) { + return new RocketMQMessageWriter<>(topic, keys, tags); + } + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQBinaryMessageReader.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQBinaryMessageReader.java new file mode 100644 index 0000000000..07888a6a72 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQBinaryMessageReader.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.cloudevent.impl; + +import java.util.Map; +import java.util.Objects; +import java.util.function.BiConsumer; + +import io.cloudevents.SpecVersion; +import io.cloudevents.core.data.BytesCloudEventData; +import io.cloudevents.core.message.impl.BaseGenericBinaryMessageReaderImpl; + +public class RocketMQBinaryMessageReader + extends BaseGenericBinaryMessageReaderImpl { + + private final Map headers; + + public RocketMQBinaryMessageReader(SpecVersion version, Map headers, + byte[] payload) { + super(version, + payload != null && payload.length > 0 ? BytesCloudEventData.wrap(payload) : null); + + Objects.requireNonNull(headers); + this.headers = headers; + } + + @Override + protected boolean isContentTypeHeader(String key) { + return key.equals(RocketMQHeaders.CONTENT_TYPE); + } + + @Override + protected boolean isCloudEventsHeader(String key) { + return true; + } + + @Override + protected String toCloudEventsKey(String key) { + return key.toLowerCase(); + } + + @Override + protected void forEachHeader(BiConsumer fn) { + this.headers.forEach((k, v) -> fn.accept(k, v)); + } + + @Override + protected String toCloudEventsValue(String value) { + return value; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQHeaders.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQHeaders.java new file mode 100644 index 0000000000..793092355d --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQHeaders.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.cloudevent.impl; + +import java.util.Map; + +import io.cloudevents.core.message.impl.MessageUtils; +import io.cloudevents.core.v1.CloudEventV1; + +public class RocketMQHeaders { + + public static final String CE_PREFIX = "CE_"; + + protected static final Map ATTRIBUTES_TO_HEADERS = + MessageUtils.generateAttributesToHeadersMapping(v -> v); + + public static final String CONTENT_TYPE = + ATTRIBUTES_TO_HEADERS.get(CloudEventV1.DATACONTENTTYPE); + + public static final String SPEC_VERSION = ATTRIBUTES_TO_HEADERS.get(CloudEventV1.SPECVERSION); + + +} + diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQMessageWriter.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQMessageWriter.java new file mode 100644 index 0000000000..6900c44cee --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/cloudevent/impl/RocketMQMessageWriter.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.cloudevent.impl; + +import org.apache.rocketmq.common.message.Message; + +import io.cloudevents.CloudEventData; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.message.MessageWriter; +import io.cloudevents.rw.CloudEventContextWriter; +import io.cloudevents.rw.CloudEventRWException; +import io.cloudevents.rw.CloudEventWriter; + + +public final class RocketMQMessageWriter + implements MessageWriter, Message>, CloudEventWriter { + + private Message message; + + + public RocketMQMessageWriter(String topic) { + message = new Message(); + message.setTopic(topic); + } + + public RocketMQMessageWriter(String topic, String keys) { + message = new Message(); + + message.setTopic(topic); + + if (keys != null && keys.length() > 0) { + message.setKeys(keys); + } + } + + public RocketMQMessageWriter(String topic, String keys, String tags) { + message = new Message(); + + message.setTopic(topic); + + if (tags != null && tags.length() > 0) { + message.setTags(tags); + } + + if (keys != null && keys.length() > 0) { + message.setKeys(keys); + } + } + + + @Override + public CloudEventContextWriter withContextAttribute(String name, String value) + throws CloudEventRWException { + message.putUserProperty(name, value); + return this; + } + + @Override + public RocketMQMessageWriter create(final SpecVersion version) { + message.putUserProperty(RocketMQHeaders.SPEC_VERSION, version.toString()); + return this; + } + + @Override + public Message setEvent(final EventFormat format, final byte[] value) + throws CloudEventRWException { + message.putUserProperty(RocketMQHeaders.CONTENT_TYPE, format.serializedContentType()); + message.setBody(value); + return message; + } + + @Override + public Message end(final CloudEventData data) throws CloudEventRWException { + message.setBody(data.toBytes()); + return message; + } + + @Override + public Message end() { + message.setBody(null); + return message; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/common/Constants.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/common/Constants.java new file mode 100644 index 0000000000..efbca5b997 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/common/Constants.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.common; + +public class Constants { + + public static final String BROADCAST_PREFIX = "broadcast-"; +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/common/EventMeshConstants.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/common/EventMeshConstants.java new file mode 100644 index 0000000000..1206ef9f33 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/common/EventMeshConstants.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.common; + +public class EventMeshConstants { + + public static final String EVENTMESH_CONF_FILE = "rocketmq-client.properties"; + + public static final int DEFAULT_TIMEOUT_IN_MILLISECONDS = 3000; + + public static final String STORE_TIMESTAMP = "storetime"; +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ClientConfig.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ClientConfig.java new file mode 100644 index 0000000000..f03a38a4a9 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ClientConfig.java @@ -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 org.apache.eventmesh.connector.rocketmq.config; + + +import org.apache.eventmesh.connector.rocketmq.domain.NonStandardKeys; + +public class ClientConfig implements NonStandardKeys { + private String driverImpl; + private String accessPoints; + private String namespace; + private String producerId; + private String consumerId; + private int operationTimeout = 5000; + private String region; + private String routingSource; + private String routingDestination; + private String routingExpression; + private String rmqConsumerGroup; + private String rmqProducerGroup = "__OMS_PRODUCER_DEFAULT_GROUP"; + private int rmqMaxRedeliveryTimes = 16; + private int rmqMessageConsumeTimeout = 15; //In minutes + private int rmqMaxConsumeThreadNums = 64; + private int rmqMinConsumeThreadNums = 20; + private String rmqMessageDestination; + private int rmqPullMessageBatchNums = 32; + private int rmqPullMessageCacheCapacity = 1000; + private String messageModel; + + public String getDriverImpl() { + return driverImpl; + } + + public void setDriverImpl(final String driverImpl) { + this.driverImpl = driverImpl; + } + + public String getAccessPoints() { + return accessPoints; + } + + public void setAccessPoints(final String accessPoints) { + this.accessPoints = accessPoints; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(final String namespace) { + this.namespace = namespace; + } + + public String getProducerId() { + return producerId; + } + + public void setProducerId(final String producerId) { + this.producerId = producerId; + } + + public String getConsumerId() { + return consumerId; + } + + public void setConsumerId(final String consumerId) { + this.consumerId = consumerId; + } + + public int getOperationTimeout() { + return operationTimeout; + } + + public void setOperationTimeout(final int operationTimeout) { + this.operationTimeout = operationTimeout; + } + + public String getRoutingSource() { + return routingSource; + } + + public void setRoutingSource(final String routingSource) { + this.routingSource = routingSource; + } + + public String getRmqConsumerGroup() { + return rmqConsumerGroup; + } + + public void setRmqConsumerGroup(final String rmqConsumerGroup) { + this.rmqConsumerGroup = rmqConsumerGroup; + } + + public String getRmqProducerGroup() { + return rmqProducerGroup; + } + + public void setRmqProducerGroup(final String rmqProducerGroup) { + this.rmqProducerGroup = rmqProducerGroup; + } + + public int getRmqMaxRedeliveryTimes() { + return rmqMaxRedeliveryTimes; + } + + public void setRmqMaxRedeliveryTimes(final int rmqMaxRedeliveryTimes) { + this.rmqMaxRedeliveryTimes = rmqMaxRedeliveryTimes; + } + + public int getRmqMessageConsumeTimeout() { + return rmqMessageConsumeTimeout; + } + + public void setRmqMessageConsumeTimeout(final int rmqMessageConsumeTimeout) { + this.rmqMessageConsumeTimeout = rmqMessageConsumeTimeout; + } + + public int getRmqMaxConsumeThreadNums() { + return rmqMaxConsumeThreadNums; + } + + public void setRmqMaxConsumeThreadNums(final int rmqMaxConsumeThreadNums) { + this.rmqMaxConsumeThreadNums = rmqMaxConsumeThreadNums; + } + + public int getRmqMinConsumeThreadNums() { + return rmqMinConsumeThreadNums; + } + + public void setRmqMinConsumeThreadNums(final int rmqMinConsumeThreadNums) { + this.rmqMinConsumeThreadNums = rmqMinConsumeThreadNums; + } + + public String getRmqMessageDestination() { + return rmqMessageDestination; + } + + public void setRmqMessageDestination(final String rmqMessageDestination) { + this.rmqMessageDestination = rmqMessageDestination; + } + + public int getRmqPullMessageBatchNums() { + return rmqPullMessageBatchNums; + } + + public void setRmqPullMessageBatchNums(final int rmqPullMessageBatchNums) { + this.rmqPullMessageBatchNums = rmqPullMessageBatchNums; + } + + public int getRmqPullMessageCacheCapacity() { + return rmqPullMessageCacheCapacity; + } + + public void setRmqPullMessageCacheCapacity(final int rmqPullMessageCacheCapacity) { + this.rmqPullMessageCacheCapacity = rmqPullMessageCacheCapacity; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getRoutingDestination() { + return routingDestination; + } + + public void setRoutingDestination(String routingDestination) { + this.routingDestination = routingDestination; + } + + public String getRoutingExpression() { + return routingExpression; + } + + public void setRoutingExpression(String routingExpression) { + this.routingExpression = routingExpression; + } + + public String getMessageModel() { + return messageModel; + } + + public void setMessageModel(String messageModel) { + this.messageModel = messageModel; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ClientConfiguration.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ClientConfiguration.java new file mode 100644 index 0000000000..53f7e5f2cf --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ClientConfiguration.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.config; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.base.Preconditions; + +public class ClientConfiguration { + + public String namesrvAddr = ""; + public String clientUserName = "username"; + public String clientPass = "password"; + public Integer consumeThreadMin = 2; + public Integer consumeThreadMax = 2; + public Integer consumeQueueSize = 10000; + public Integer pullBatchSize = 32; + public Integer ackWindow = 1000; + public Integer pubWindow = 100; + public long consumeTimeout = 0L; + public Integer pollNameServerInterval = 10 * 1000; + public Integer heartbeatBrokerInterval = 30 * 1000; + public Integer rebalanceInterval = 20 * 1000; + public String clusterName = ""; + public String accessKey = ""; + public String secretKey = ""; + + public void init() { + + String clientUserNameStr = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_USERNAME); + if (StringUtils.isNotBlank(clientUserNameStr)) { + clientUserName = StringUtils.trim(clientUserNameStr); + } + + String clientPassStr = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_PASSWORD); + if (StringUtils.isNotBlank(clientPassStr)) { + clientPass = StringUtils.trim(clientPassStr); + } + + String namesrvAddrStr = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_NAMESRV_ADDR); + Preconditions.checkState(StringUtils.isNotEmpty(namesrvAddrStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_NAMESRV_ADDR)); + namesrvAddr = StringUtils.trim(namesrvAddrStr); + + String consumeThreadPoolMinStr = + ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_MIN); + if (StringUtils.isNotEmpty(consumeThreadPoolMinStr)) { + Preconditions.checkState(StringUtils.isNumeric(consumeThreadPoolMinStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_MIN)); + consumeThreadMin = Integer.valueOf(consumeThreadPoolMinStr); + } + + String consumeThreadPoolMaxStr = + ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_MAX); + if (StringUtils.isNotEmpty(consumeThreadPoolMaxStr)) { + Preconditions.checkState(StringUtils.isNumeric(consumeThreadPoolMaxStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_MAX)); + consumeThreadMax = Integer.valueOf(consumeThreadPoolMaxStr); + } + + String consumerThreadPoolQueueSizeStr = + ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_QUEUESIZE); + if (StringUtils.isNotEmpty(consumerThreadPoolQueueSizeStr)) { + Preconditions.checkState(StringUtils.isNumeric(consumerThreadPoolQueueSizeStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_QUEUESIZE)); + consumeQueueSize = Integer.valueOf(consumerThreadPoolQueueSizeStr); + } + + String clientAckWindowStr = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_ACK_WINDOW); + if (StringUtils.isNotEmpty(clientAckWindowStr)) { + Preconditions.checkState(StringUtils.isNumeric(clientAckWindowStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_ACK_WINDOW)); + ackWindow = Integer.valueOf(clientAckWindowStr); + } + + String clientPubWindowStr = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_PUB_WINDOW); + if (StringUtils.isNotEmpty(clientPubWindowStr)) { + Preconditions.checkState(StringUtils.isNumeric(clientPubWindowStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_PUB_WINDOW)); + pubWindow = Integer.valueOf(clientPubWindowStr); + } + + String consumeTimeoutStr = + ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_CONSUME_TIMEOUT); + if (StringUtils.isNotBlank(consumeTimeoutStr)) { + Preconditions.checkState(StringUtils.isNumeric(consumeTimeoutStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_CONSUME_TIMEOUT)); + consumeTimeout = Long.parseLong(consumeTimeoutStr); + } + + String clientPullBatchSizeStr = + ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_PULL_BATCHSIZE); + if (StringUtils.isNotEmpty(clientPullBatchSizeStr)) { + Preconditions.checkState(StringUtils.isNumeric(clientPullBatchSizeStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_PULL_BATCHSIZE)); + pullBatchSize = Integer.valueOf(clientPullBatchSizeStr); + } + + String clientPollNamesrvIntervalStr = + ConfigurationWrapper.getProp( + ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_POLL_NAMESRV_INTERVAL); + if (StringUtils.isNotEmpty(clientPollNamesrvIntervalStr)) { + Preconditions.checkState(StringUtils.isNumeric(clientPollNamesrvIntervalStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_POLL_NAMESRV_INTERVAL)); + pollNameServerInterval = Integer.valueOf(clientPollNamesrvIntervalStr); + } + + String clientHeartbeatBrokerIntervalStr = + ConfigurationWrapper.getProp( + ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_HEARTBEAT_BROKER_INTERVAL); + if (StringUtils.isNotEmpty(clientHeartbeatBrokerIntervalStr)) { + Preconditions.checkState(StringUtils.isNumeric(clientHeartbeatBrokerIntervalStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_HEARTBEAT_BROKER_INTERVAL)); + heartbeatBrokerInterval = Integer.valueOf(clientHeartbeatBrokerIntervalStr); + } + + String clientRebalanceIntervalIntervalStr = + ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_REBALANCE_INTERVAL); + if (StringUtils.isNotEmpty(clientRebalanceIntervalIntervalStr)) { + Preconditions.checkState(StringUtils.isNumeric(clientRebalanceIntervalIntervalStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLIENT_REBALANCE_INTERVAL)); + rebalanceInterval = Integer.valueOf(clientRebalanceIntervalIntervalStr); + } + + String cluster = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_CLUSTER); + if (StringUtils.isNotBlank(cluster)) { + clusterName = cluster; + } + + String ak = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_ACCESS_KEY); + if (StringUtils.isNotBlank(ak)) { + accessKey = ak; + } + + String sk = ConfigurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ROCKETMQ_SECRET_KEY); + if (StringUtils.isNotBlank(sk)) { + secretKey = sk; + } + } + + static class ConfKeys { + + public static final String KEYS_EVENTMESH_ROCKETMQ_NAMESRV_ADDR = "eventMesh.server.rocketmq.namesrvAddr"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_USERNAME = "eventMesh.server.rocketmq.username"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_PASSWORD = "eventMesh.server.rocketmq.password"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_MIN = + "eventMesh.server.rocketmq.client.consumeThreadMin"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_MAX = + "eventMesh.server.rocketmq.client.consumeThreadMax"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CONSUME_THREADPOOL_QUEUESIZE = + "eventMesh.server.rocketmq.client.consumeThreadPoolQueueSize"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLIENT_ACK_WINDOW = "eventMesh.server.rocketmq.client.ackwindow"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLIENT_PUB_WINDOW = "eventMesh.server.rocketmq.client.pubwindow"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLIENT_CONSUME_TIMEOUT = + "eventMesh.server.rocketmq.client.comsumeTimeoutInMin"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLIENT_PULL_BATCHSIZE = + "eventMesh.server.rocketmq.client.pullBatchSize"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLIENT_POLL_NAMESRV_INTERVAL = + "eventMesh.server.rocketmq.client.pollNameServerInterval"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLIENT_HEARTBEAT_BROKER_INTERVAL = + "eventMesh.server.rocketmq.client.heartbeatBrokerInterval"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLIENT_REBALANCE_INTERVAL = + "eventMesh.server.rocketmq.client.rebalanceInterval"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_CLUSTER = "eventMesh.server.rocketmq.cluster"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_ACCESS_KEY = + "eventMesh.server.rocketmq.accessKey"; + + public static final String KEYS_EVENTMESH_ROCKETMQ_SECRET_KEY = + "eventMesh.server.rocketmq.secretKey"; + + } +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ConfigurationWrapper.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ConfigurationWrapper.java new file mode 100644 index 0000000000..83036bb36b --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/ConfigurationWrapper.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.config; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.rocketmq.common.EventMeshConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@UtilityClass +public class ConfigurationWrapper { + + private static final Properties properties = new Properties(); + + static { + loadProperties(); + } + + public String getProp(String key) { + return StringUtils.isEmpty(key) ? null : properties.getProperty(key, null); + } + + /** + * Load rocketmq properties file from classpath and conf home. + * The properties defined in conf home will override classpath. + */ + private void loadProperties() { + try (InputStream resourceAsStream = ConfigurationWrapper.class.getResourceAsStream( + "/" + EventMeshConstants.EVENTMESH_CONF_FILE)) { + if (resourceAsStream != null) { + properties.load(resourceAsStream); + } + } catch (IOException e) { + throw new RuntimeException(String.format("Load %s.properties file from classpath error", EventMeshConstants.EVENTMESH_CONF_FILE)); + } + try { + String configPath = Constants.EVENTMESH_CONF_HOME + File.separator + EventMeshConstants.EVENTMESH_CONF_FILE; + if (new File(configPath).exists()) { + properties.load(new BufferedReader(new FileReader(configPath))); + } + } catch (IOException e) { + throw new IllegalArgumentException(String.format("Cannot load %s file from conf", EventMeshConstants.EVENTMESH_CONF_FILE)); + } + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/connector/ConnectorResourceServiceRocketmqImpl.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/connector/ConnectorResourceServiceRocketmqImpl.java new file mode 100644 index 0000000000..f26747e9db --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/connector/ConnectorResourceServiceRocketmqImpl.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.connector; + +import org.apache.eventmesh.api.connector.ConnectorResourceService; + +public class ConnectorResourceServiceRocketmqImpl implements ConnectorResourceService { + @Override + public void init() throws Exception { + + } + + @Override + public void release() throws Exception { + + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/consumer/PushConsumerImpl.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/consumer/PushConsumerImpl.java new file mode 100644 index 0000000000..71f921fddb --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/consumer/PushConsumerImpl.java @@ -0,0 +1,312 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.AsyncConsumeContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.EventMeshAction; +import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; +import org.apache.eventmesh.api.exception.ConnectorRuntimeException; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.rocketmq.cloudevent.RocketMQMessageFactory; +import org.apache.eventmesh.connector.rocketmq.common.EventMeshConstants; +import org.apache.eventmesh.connector.rocketmq.config.ClientConfig; +import org.apache.eventmesh.connector.rocketmq.domain.NonStandardKeys; +import org.apache.eventmesh.connector.rocketmq.patch.EventMeshConsumeConcurrentlyContext; +import org.apache.eventmesh.connector.rocketmq.patch.EventMeshConsumeConcurrentlyStatus; +import org.apache.eventmesh.connector.rocketmq.patch.EventMeshMessageListenerConcurrently; +import org.apache.eventmesh.connector.rocketmq.utils.BeanUtils; +import org.apache.eventmesh.connector.rocketmq.utils.CloudEventUtils; +import org.apache.eventmesh.connector.rocketmq.utils.OMSUtil; + +import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.client.impl.consumer.ConsumeMessageConcurrentlyService; +import org.apache.rocketmq.client.impl.consumer.ConsumeMessageService; +import org.apache.rocketmq.common.message.MessageConst; +import org.apache.rocketmq.common.message.MessageExt; +import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; +import org.apache.rocketmq.remoting.protocol.LanguageCode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class PushConsumerImpl { + private final DefaultMQPushConsumer rocketmqPushConsumer; + private final Properties properties; + private AtomicBoolean started = new AtomicBoolean(false); + private EventListener eventListener; + private final ClientConfig clientConfig; + + public PushConsumerImpl(final Properties properties) { + this.rocketmqPushConsumer = new DefaultMQPushConsumer(); + this.properties = properties; + this.clientConfig = BeanUtils.populate(properties, ClientConfig.class); + + String accessPoints = clientConfig.getAccessPoints(); + if (accessPoints == null || accessPoints.isEmpty()) { + throw new ConnectorRuntimeException("OMS AccessPoints is null or empty."); + } + this.rocketmqPushConsumer.setNamesrvAddr(accessPoints.replace(',', ';')); + String consumerGroup = clientConfig.getConsumerId(); + if (null == consumerGroup || consumerGroup.isEmpty()) { + throw new ConnectorRuntimeException( + "Consumer Group is necessary for RocketMQ, please set it."); + } + this.rocketmqPushConsumer.setConsumerGroup(consumerGroup); + this.rocketmqPushConsumer.setMaxReconsumeTimes(clientConfig.getRmqMaxRedeliveryTimes()); + this.rocketmqPushConsumer.setConsumeTimeout(clientConfig.getRmqMessageConsumeTimeout()); + this.rocketmqPushConsumer.setConsumeThreadMax(clientConfig.getRmqMaxConsumeThreadNums()); + this.rocketmqPushConsumer.setConsumeThreadMin(clientConfig.getRmqMinConsumeThreadNums()); + this.rocketmqPushConsumer.setMessageModel( + MessageModel.valueOf(clientConfig.getMessageModel())); + + String consumerId = OMSUtil.buildInstanceName(); + //this.rocketmqPushConsumer.setInstanceName(consumerId); + this.rocketmqPushConsumer.setInstanceName(properties.getProperty("instanceName")); + properties.put("CONSUMER_ID", consumerId); + this.rocketmqPushConsumer.setLanguage(LanguageCode.OMS); + + if (clientConfig.getMessageModel().equalsIgnoreCase(MessageModel.BROADCASTING.name())) { + rocketmqPushConsumer.registerMessageListener(new BroadCastingMessageListener()); + } else { + rocketmqPushConsumer.registerMessageListener(new ClusteringMessageListener()); + } + } + + public Properties attributes() { + return properties; + } + + + public void start() { + if (this.started.compareAndSet(false, true)) { + try { + this.rocketmqPushConsumer.start(); + } catch (Exception e) { + throw new ConnectorRuntimeException(e.getMessage()); + } + } + } + + + public synchronized void shutdown() { + if (this.started.compareAndSet(true, false)) { + this.rocketmqPushConsumer.shutdown(); + } + } + + + public boolean isStarted() { + return this.started.get(); + } + + + public boolean isClosed() { + return !this.isStarted(); + } + + public DefaultMQPushConsumer getRocketmqPushConsumer() { + return rocketmqPushConsumer; + } + + public void subscribe(String topic, String subExpression) { + try { + this.rocketmqPushConsumer.subscribe(topic, subExpression); + } catch (MQClientException e) { + throw new ConnectorRuntimeException(String.format("RocketMQ push consumer can't attach to %s.", topic)); + } + } + + + public void unsubscribe(String topic) { + try { + this.rocketmqPushConsumer.unsubscribe(topic); + } catch (Exception e) { + throw new ConnectorRuntimeException(String.format("RocketMQ push consumer fails to unsubscribe topic: %s", topic)); + } + } + + public void updateOffset(List cloudEvents, AbstractContext context) { + ConsumeMessageService consumeMessageService = rocketmqPushConsumer + .getDefaultMQPushConsumerImpl().getConsumeMessageService(); + List msgExtList = new ArrayList<>(cloudEvents.size()); + for (CloudEvent msg : cloudEvents) { + msgExtList.add(CloudEventUtils.msgConvertExt( + RocketMQMessageFactory.createWriter(msg.getSubject()).writeBinary(msg))); + } + ((ConsumeMessageConcurrentlyService) consumeMessageService) + .updateOffset(msgExtList, (EventMeshConsumeConcurrentlyContext) context); + } + + + private class BroadCastingMessageListener extends EventMeshMessageListenerConcurrently { + + @Override + public EventMeshConsumeConcurrentlyStatus handleMessage(MessageExt msg, + EventMeshConsumeConcurrentlyContext context) { + if (msg == null) { + return EventMeshConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } + + msg.putUserProperty(Constants.PROPERTY_MESSAGE_BORN_TIMESTAMP, + String.valueOf(msg.getBornTimestamp())); + msg.putUserProperty(Constants.PROPERTY_MESSAGE_STORE_TIMESTAMP, + String.valueOf(msg.getStoreTimestamp())); + + //for rr request/reply + CloudEvent cloudEvent = + RocketMQMessageFactory.createReader(CloudEventUtils.msgConvert(msg)).toEvent(); + + CloudEventBuilder cloudEventBuilder = null; + for (String sysPropKey : MessageConst.STRING_HASH_SET) { + if (StringUtils.isNotEmpty(msg.getProperty(sysPropKey))) { + String prop = msg.getProperty(sysPropKey); + sysPropKey = sysPropKey.toLowerCase().replaceAll("_", Constants.MESSAGE_PROP_SEPARATOR); + cloudEventBuilder = CloudEventBuilder.from(cloudEvent).withExtension(sysPropKey, prop); + } + } + if (cloudEventBuilder != null) { + cloudEvent = cloudEventBuilder.build(); + } + + if (eventListener == null) { + throw new ConnectorRuntimeException(String.format("The topic/queue %s isn't attached to this consumer", + msg.getTopic())); + } + + final Properties contextProperties = new Properties(); + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name()); + EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = new EventMeshAsyncConsumeContext() { + @Override + public void commit(EventMeshAction action) { + switch (action) { + case CommitMessage: + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.CONSUME_SUCCESS.name()); + break; + case ReconsumeLater: + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name()); + break; + case ManualAck: + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.CONSUME_FINISH.name()); + break; + default: + break; + } + } + }; + + eventMeshAsyncConsumeContext.setAbstractContext(context); + + eventListener.consume(cloudEvent, eventMeshAsyncConsumeContext); + + return EventMeshConsumeConcurrentlyStatus.valueOf( + contextProperties.getProperty(NonStandardKeys.MESSAGE_CONSUME_STATUS)); + } + + + } + + private class ClusteringMessageListener extends EventMeshMessageListenerConcurrently { + + @Override + public EventMeshConsumeConcurrentlyStatus handleMessage(MessageExt msg, + EventMeshConsumeConcurrentlyContext context) { + if (msg == null) { + return EventMeshConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } + + msg.putUserProperty(Constants.PROPERTY_MESSAGE_BORN_TIMESTAMP, + String.valueOf(msg.getBornTimestamp())); + msg.putUserProperty(EventMeshConstants.STORE_TIMESTAMP, + String.valueOf(msg.getStoreTimestamp())); + + CloudEvent cloudEvent = + RocketMQMessageFactory.createReader(CloudEventUtils.msgConvert(msg)).toEvent(); + + CloudEventBuilder cloudEventBuilder = null; + + for (String sysPropKey : MessageConst.STRING_HASH_SET) { + if (StringUtils.isNotEmpty(msg.getProperty(sysPropKey))) { + String prop = msg.getProperty(sysPropKey); + sysPropKey = sysPropKey.toLowerCase().replaceAll("_", Constants.MESSAGE_PROP_SEPARATOR); + cloudEventBuilder = CloudEventBuilder.from(cloudEvent).withExtension(sysPropKey, prop); + } + } + if (cloudEventBuilder != null) { + cloudEvent = cloudEventBuilder.build(); + } + + if (eventListener == null) { + throw new ConnectorRuntimeException(String.format("The topic/queue %s isn't attached to this consumer", + msg.getTopic())); + } + + final Properties contextProperties = new Properties(); + + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name()); + + EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = new EventMeshAsyncConsumeContext() { + @Override + public void commit(EventMeshAction action) { + switch (action) { + case CommitMessage: + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.CONSUME_SUCCESS.name()); + break; + case ReconsumeLater: + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name()); + break; + case ManualAck: + contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, + EventMeshConsumeConcurrentlyStatus.CONSUME_FINISH.name()); + break; + default: + break; + } + } + }; + + eventMeshAsyncConsumeContext.setAbstractContext(context); + + eventListener.consume(cloudEvent, eventMeshAsyncConsumeContext); + + return EventMeshConsumeConcurrentlyStatus.valueOf( + contextProperties.getProperty(NonStandardKeys.MESSAGE_CONSUME_STATUS)); + } + } + + public void registerEventListener(EventListener listener) { + this.eventListener = listener; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/consumer/RocketMQConsumerImpl.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/consumer/RocketMQConsumerImpl.java new file mode 100644 index 0000000000..eaf2a42a2d --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/consumer/RocketMQConsumerImpl.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.consumer.Consumer; +import org.apache.eventmesh.connector.rocketmq.common.Constants; +import org.apache.eventmesh.connector.rocketmq.config.ClientConfiguration; + +import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; + +import java.util.List; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RocketMQConsumerImpl implements Consumer { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + private PushConsumerImpl pushConsumer; + + @Override + public synchronized void init(Properties keyValue) throws Exception { + final ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.init(); + boolean isBroadcast = Boolean.parseBoolean(keyValue.getProperty("isBroadcast")); + + String consumerGroup = keyValue.getProperty("consumerGroup"); + if (isBroadcast) { + consumerGroup = Constants.BROADCAST_PREFIX + consumerGroup; + } + + String namesrvAddr = clientConfiguration.namesrvAddr; + String instanceName = keyValue.getProperty("instanceName"); + Properties properties = new Properties(); + properties.put("ACCESS_POINTS", namesrvAddr); + properties.put("REGION", "namespace"); + properties.put("instanceName", instanceName); + properties.put("CONSUMER_ID", consumerGroup); + if (isBroadcast) { + properties.put("MESSAGE_MODEL", MessageModel.BROADCASTING.name()); + } else { + properties.put("MESSAGE_MODEL", MessageModel.CLUSTERING.name()); + } + + pushConsumer = new PushConsumerImpl(properties); + } + + @Override + public void subscribe(String topic) throws Exception { + pushConsumer.subscribe(topic, "*"); + } + + @Override + public boolean isStarted() { + return pushConsumer.isStarted(); + } + + @Override + public boolean isClosed() { + return pushConsumer.isClosed(); + } + + @Override + public synchronized void start() { + pushConsumer.start(); + } + + @Override + public void updateOffset(List cloudEvents, AbstractContext context) { + pushConsumer.updateOffset(cloudEvents, context); + } + + @Override + public void unsubscribe(String topic) { + pushConsumer.unsubscribe(topic); + } + + @Override + public void registerEventListener(EventListener listener) { + pushConsumer.registerEventListener(listener); + } + + @Override + public synchronized void shutdown() { + pushConsumer.shutdown(); + } + + public Properties attributes() { + return pushConsumer.attributes(); + } + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/domain/NonStandardKeys.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/domain/NonStandardKeys.java new file mode 100644 index 0000000000..209557dc9f --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/domain/NonStandardKeys.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.domain; + +/** + * NonStandardKeys + */ +public interface NonStandardKeys { + String CONSUMER_GROUP = "rmq.consumer.group"; + String MAX_REDELIVERY_TIMES = "rmq.max.redelivery.times"; + String MESSAGE_CONSUME_TIMEOUT = "rmq.message.consume.timeout"; + String MESSAGE_CONSUME_STATUS = "rmq.message.consume.status"; + String MESSAGE_DESTINATION = "rmq.message.destination"; +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/exception/RMQMessageFormatException.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/exception/RMQMessageFormatException.java new file mode 100644 index 0000000000..703b7ea2bf --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/exception/RMQMessageFormatException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.exception; + +import org.apache.eventmesh.api.exception.ConnectorRuntimeException; + +public class RMQMessageFormatException extends ConnectorRuntimeException { + + public RMQMessageFormatException(String message) { + super(message); + } + + public RMQMessageFormatException(Throwable throwable) { + super(throwable); + } + + public RMQMessageFormatException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/exception/RMQTimeoutException.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/exception/RMQTimeoutException.java new file mode 100644 index 0000000000..c2a6b03410 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/exception/RMQTimeoutException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.exception; + +import org.apache.eventmesh.api.exception.ConnectorRuntimeException; + +public class RMQTimeoutException extends ConnectorRuntimeException { + + public RMQTimeoutException(String message) { + super(message); + } + + public RMQTimeoutException(Throwable throwable) { + super(throwable); + } + + public RMQTimeoutException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshConsumeConcurrentlyContext.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshConsumeConcurrentlyContext.java new file mode 100644 index 0000000000..2dcfa95038 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshConsumeConcurrentlyContext.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.patch; + +import org.apache.eventmesh.api.AbstractContext; + +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; +import org.apache.rocketmq.client.impl.consumer.ProcessQueue; +import org.apache.rocketmq.common.message.MessageQueue; + +public class EventMeshConsumeConcurrentlyContext extends ConsumeConcurrentlyContext implements AbstractContext { + private final ProcessQueue processQueue; + private boolean manualAck = true; + + public EventMeshConsumeConcurrentlyContext(MessageQueue messageQueue, ProcessQueue processQueue) { + super(messageQueue); + this.processQueue = processQueue; + } + + public ProcessQueue getProcessQueue() { + return processQueue; + } + + public boolean isManualAck() { + return manualAck; + } + + public void setManualAck(boolean manualAck) { + this.manualAck = manualAck; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshConsumeConcurrentlyStatus.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshConsumeConcurrentlyStatus.java new file mode 100644 index 0000000000..468b14f568 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshConsumeConcurrentlyStatus.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.patch; + +public enum EventMeshConsumeConcurrentlyStatus { + /** + * Success consumption + */ + CONSUME_SUCCESS, + /** + * Failure consumption,later try to consume + */ + RECONSUME_LATER, + /** + * Success consumption but ack later manually + */ + CONSUME_FINISH; +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshMessageListenerConcurrently.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshMessageListenerConcurrently.java new file mode 100644 index 0000000000..0d32ba27d3 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/patch/EventMeshMessageListenerConcurrently.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.patch; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; +import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; +import org.apache.rocketmq.common.message.MessageExt; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class EventMeshMessageListenerConcurrently implements MessageListenerConcurrently { + + private static final Logger LOG = LoggerFactory.getLogger(EventMeshMessageListenerConcurrently.class); + + @Override + public ConsumeConcurrentlyStatus consumeMessage(final List msgs, + final ConsumeConcurrentlyContext context) { + ConsumeConcurrentlyStatus status = null; + + if (CollectionUtils.isEmpty(msgs)) { + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } + + MessageExt msg = msgs.get(0); + try { + EventMeshConsumeConcurrentlyContext eventMeshConsumeConcurrentlyContext = (EventMeshConsumeConcurrentlyContext) context; + EventMeshConsumeConcurrentlyStatus eventMeshConsumeStatus = handleMessage(msg, eventMeshConsumeConcurrentlyContext); + try { + switch (eventMeshConsumeStatus) { + case CONSUME_SUCCESS: + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + case RECONSUME_LATER: + return ConsumeConcurrentlyStatus.RECONSUME_LATER; + case CONSUME_FINISH: + eventMeshConsumeConcurrentlyContext.setManualAck(true); + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + default: + return status; + } + } catch (Throwable e) { + LOG.info("handleMessage fail", e); + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } + } catch (Throwable e) { + LOG.info("handleMessage fail", e); + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } + //return status; + } + + public abstract EventMeshConsumeConcurrentlyStatus handleMessage(MessageExt msg, EventMeshConsumeConcurrentlyContext context); +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/AbstractProducer.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/AbstractProducer.java new file mode 100644 index 0000000000..e95a47f0b6 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/AbstractProducer.java @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.producer; + +import org.apache.eventmesh.api.exception.ConnectorRuntimeException; +import org.apache.eventmesh.connector.rocketmq.config.ClientConfig; +import org.apache.eventmesh.connector.rocketmq.exception.RMQMessageFormatException; +import org.apache.eventmesh.connector.rocketmq.exception.RMQTimeoutException; +import org.apache.eventmesh.connector.rocketmq.utils.BeanUtils; +import org.apache.eventmesh.connector.rocketmq.utils.OMSUtil; + +import org.apache.rocketmq.client.exception.MQBrokerException; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; +import org.apache.rocketmq.client.log.ClientLogger; +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.apache.rocketmq.common.protocol.ResponseCode; +import org.apache.rocketmq.logging.InternalLogger; +import org.apache.rocketmq.remoting.exception.RemotingConnectException; +import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; +import org.apache.rocketmq.remoting.protocol.LanguageCode; + +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +public abstract class AbstractProducer { + + static final InternalLogger log = ClientLogger.getLog(); + final Properties properties; + final DefaultMQProducer rocketmqProducer; + protected final AtomicBoolean started = new AtomicBoolean(false); + // private boolean started = false; + private final ClientConfig clientConfig; + private static final String PRODUCER_ID = "PRODUCER_ID"; + + AbstractProducer(final Properties properties) { + this.properties = properties; + this.rocketmqProducer = new DefaultMQProducer(); + this.clientConfig = BeanUtils.populate(properties, ClientConfig.class); + + String accessPoints = clientConfig.getAccessPoints(); + if (accessPoints == null || accessPoints.isEmpty()) { + throw new ConnectorRuntimeException("OMS AccessPoints is null or empty."); + } + + this.rocketmqProducer.setNamesrvAddr(accessPoints.replace(',', ';')); + + this.rocketmqProducer.setProducerGroup(clientConfig.getRmqProducerGroup()); + + String producerId = OMSUtil.buildInstanceName(); + this.rocketmqProducer.setSendMsgTimeout(clientConfig.getOperationTimeout()); + this.rocketmqProducer.setInstanceName(producerId); + this.rocketmqProducer.setMaxMessageSize(1024 * 1024 * 4); + this.rocketmqProducer.setLanguage(LanguageCode.OMS); + properties.put(PRODUCER_ID, producerId); + } + + public synchronized void start() { + if (!started.get()) { + try { + this.rocketmqProducer.start(); + } catch (MQClientException e) { + throw new ConnectorRuntimeException("-1", e); + } + } + this.started.set(true); + } + + public synchronized void shutdown() { + if (this.started.get()) { + this.rocketmqProducer.shutdown(); + } + this.started.set(false); + } + + public boolean isStarted() { + return this.started.get(); + } + + public boolean isClosed() { + return !this.isStarted(); + } + + ConnectorRuntimeException checkProducerException(String topic, String msgId, Throwable e) { + if (e instanceof MQClientException) { + if (e.getCause() != null) { + if (e.getCause() instanceof RemotingTimeoutException) { + return new RMQTimeoutException( + String.format("Send message to broker timeout, %dms, Topic=%s, msgId=%s", + this.rocketmqProducer.getSendMsgTimeout(), topic, msgId), e); + } else if (e.getCause() instanceof MQBrokerException + || e.getCause() instanceof RemotingConnectException) { + if (e.getCause() instanceof MQBrokerException) { + MQBrokerException brokerException = (MQBrokerException) e.getCause(); + return new ConnectorRuntimeException( + String.format("Received a broker exception, Topic=%s, msgId=%s, %s", + topic, msgId, brokerException.getErrorMessage()), e); + } + + if (e.getCause() instanceof RemotingConnectException) { + RemotingConnectException connectException = + (RemotingConnectException) e.getCause(); + return new ConnectorRuntimeException( + String.format( + "Network connection experiences failures. Topic=%s, msgId=%s, %s", + topic, msgId, connectException.getMessage()), e); + } + } + } else { + // Exception thrown by local. + MQClientException clientException = (MQClientException) e; + if (-1 == clientException.getResponseCode()) { + return new ConnectorRuntimeException( + String.format("Topic does not exist, Topic=%s, msgId=%s", + topic, msgId), e); + } else if (ResponseCode.MESSAGE_ILLEGAL == clientException.getResponseCode()) { + return new RMQMessageFormatException( + String.format("A illegal message for RocketMQ, Topic=%s, msgId=%s", + topic, msgId), e); + } + } + } + return new ConnectorRuntimeException("Send message to RocketMQ broker failed.", e); + } + + protected void checkProducerServiceState(DefaultMQProducerImpl producer) { + switch (producer.getServiceState()) { + case CREATE_JUST: + throw new ConnectorRuntimeException( + String.format("You do not have start the producer, %s", + producer.getServiceState())); + case SHUTDOWN_ALREADY: + throw new ConnectorRuntimeException( + String.format("Your producer has been shut down, %s", + producer.getServiceState())); + case START_FAILED: + throw new ConnectorRuntimeException( + String.format("When you start your service throws an exception, %s", + producer.getServiceState())); + case RUNNING: + default: + } + } + + public DefaultMQProducer getRocketmqProducer() { + return rocketmqProducer; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/ProducerImpl.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/ProducerImpl.java new file mode 100644 index 0000000000..fd4cecc710 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/ProducerImpl.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.producer; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.ConnectorRuntimeException; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.rocketmq.cloudevent.RocketMQMessageFactory; +import org.apache.eventmesh.connector.rocketmq.utils.CloudEventUtils; + +import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.client.exception.MQBrokerException; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.client.producer.RequestCallback; +import org.apache.rocketmq.common.MixAll; +import org.apache.rocketmq.common.message.Message; +import org.apache.rocketmq.common.message.MessageAccessor; +import org.apache.rocketmq.common.message.MessageClientIDSetter; +import org.apache.rocketmq.common.message.MessageConst; +import org.apache.rocketmq.remoting.exception.RemotingException; + +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SuppressWarnings("deprecation") +public class ProducerImpl extends AbstractProducer { + + public static final int eventMeshServerAsyncAccumulationThreshold = 1000; + + public ProducerImpl(final Properties properties) { + super(properties); + } + + public Properties attributes() { + return properties; + } + + public void setExtFields() { + super.getRocketmqProducer().setRetryTimesWhenSendFailed(0); + super.getRocketmqProducer().setRetryTimesWhenSendAsyncFailed(0); + super.getRocketmqProducer().setPollNameServerInterval(60000); + + super.getRocketmqProducer().getDefaultMQProducerImpl().getmQClientFactory().getNettyClientConfig() + .setClientAsyncSemaphoreValue(eventMeshServerAsyncAccumulationThreshold); + super.getRocketmqProducer().setCompressMsgBodyOverHowmuch(10); + } + + + public SendResult send(CloudEvent cloudEvent) { + this.checkProducerServiceState(rocketmqProducer.getDefaultMQProducerImpl()); + org.apache.rocketmq.common.message.Message msg = + RocketMQMessageFactory.createWriter(cloudEvent.getSubject()).writeBinary(cloudEvent); + msg = supplySysProp(msg, cloudEvent); + String messageId = null; + try { + org.apache.rocketmq.client.producer.SendResult sendResultRmq = this.rocketmqProducer.send(msg); + SendResult sendResult = new SendResult(); + sendResult.setTopic(sendResultRmq.getMessageQueue().getTopic()); + messageId = sendResultRmq.getMsgId(); + sendResult.setMessageId(messageId); + return sendResult; + } catch (Exception e) { + log.error(String.format("Send message Exception, %s", msg), e); + throw this.checkProducerException(msg.getTopic(), messageId, e); + } + } + + + public void sendOneway(CloudEvent cloudEvent) { + this.checkProducerServiceState(this.rocketmqProducer.getDefaultMQProducerImpl()); + org.apache.rocketmq.common.message.Message msg = + RocketMQMessageFactory.createWriter(cloudEvent.getSubject()).writeBinary(cloudEvent); + msg = supplySysProp(msg, cloudEvent); + try { + this.rocketmqProducer.sendOneway(msg); + } catch (Exception e) { + log.error(String.format("Send message oneway Exception, %s", msg), e); + throw this.checkProducerException(msg.getTopic(), MessageClientIDSetter.getUniqID(msg), e); + } + } + + + public void sendAsync(CloudEvent cloudEvent, SendCallback sendCallback) { + this.checkProducerServiceState(this.rocketmqProducer.getDefaultMQProducerImpl()); + org.apache.rocketmq.common.message.Message msg = + RocketMQMessageFactory.createWriter(cloudEvent.getSubject()).writeBinary(cloudEvent); + msg = supplySysProp(msg, cloudEvent); + try { + this.rocketmqProducer.send(msg, this.sendCallbackConvert(msg, sendCallback)); + } catch (Exception e) { + log.error(String.format("Send message async Exception, %s", msg), e); + throw this.checkProducerException(msg.getTopic(), MessageClientIDSetter.getUniqID(msg), e); + } + } + + public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) + throws InterruptedException, RemotingException, MQClientException, MQBrokerException { + + this.checkProducerServiceState(this.rocketmqProducer.getDefaultMQProducerImpl()); + org.apache.rocketmq.common.message.Message msg = + RocketMQMessageFactory.createWriter(cloudEvent.getSubject()).writeBinary(cloudEvent); + + msg = supplySysProp(msg, cloudEvent); + + rocketmqProducer.request(msg, rrCallbackConvert(msg, rrCallback), timeout); + } + + public boolean reply(final CloudEvent cloudEvent, final SendCallback sendCallback) { + this.checkProducerServiceState(this.rocketmqProducer.getDefaultMQProducerImpl()); + org.apache.rocketmq.common.message.Message msg = + RocketMQMessageFactory.createWriter(cloudEvent.getSubject()).writeBinary(cloudEvent); + MessageAccessor.putProperty(msg, MessageConst.PROPERTY_MESSAGE_TYPE, MixAll.REPLY_MESSAGE_FLAG); + msg = supplySysProp(msg, cloudEvent); + + try { + this.rocketmqProducer.send(msg, this.sendCallbackConvert(msg, sendCallback)); + } catch (Exception e) { + log.error(String.format("Send message async Exception, %s", msg), e); + throw this.checkProducerException(msg.getTopic(), MessageClientIDSetter.getUniqID(msg), e); + } + return true; + + } + + private Message supplySysProp(Message msg, CloudEvent cloudEvent) { + for (String sysPropKey : MessageConst.STRING_HASH_SET) { + String ceKey = sysPropKey.toLowerCase().replaceAll("_", Constants.MESSAGE_PROP_SEPARATOR); + if (cloudEvent.getExtension(ceKey) != null && StringUtils.isNotEmpty(cloudEvent.getExtension(ceKey).toString())) { + MessageAccessor.putProperty(msg, sysPropKey, cloudEvent.getExtension(ceKey).toString()); + msg.getProperties().remove(ceKey); + } + } + return msg; + } + + private RequestCallback rrCallbackConvert(final Message message, final RequestReplyCallback rrCallback) { + return new RequestCallback() { + @Override + public void onSuccess(org.apache.rocketmq.common.message.Message message) { + // clean the message property to lowercase + for (String sysPropKey : MessageConst.STRING_HASH_SET) { + if (StringUtils.isNotEmpty(message.getProperty(sysPropKey))) { + String prop = message.getProperty(sysPropKey); + String tmpPropKey = sysPropKey.toLowerCase().replaceAll("_", Constants.MESSAGE_PROP_SEPARATOR); + MessageAccessor.putProperty(message, tmpPropKey, prop); + message.getProperties().remove(sysPropKey); + } + } + CloudEvent event = RocketMQMessageFactory.createReader(message).toEvent(); + rrCallback.onSuccess(event); + } + + @Override + public void onException(Throwable e) { + String topic = message.getTopic(); + ConnectorRuntimeException onsEx = ProducerImpl.this.checkProducerException(topic, null, e); + OnExceptionContext context = new OnExceptionContext(); + context.setTopic(topic); + context.setException(onsEx); + rrCallback.onException(e); + + } + }; + } + + private org.apache.rocketmq.client.producer.SendCallback sendCallbackConvert(final Message message, + final SendCallback sendCallback) { + org.apache.rocketmq.client.producer.SendCallback rmqSendCallback = + new org.apache.rocketmq.client.producer.SendCallback() { + @Override + public void onSuccess(org.apache.rocketmq.client.producer.SendResult sendResult) { + sendCallback.onSuccess(CloudEventUtils.convertSendResult(sendResult)); + } + + @Override + public void onException(Throwable e) { + String topic = message.getTopic(); + ConnectorRuntimeException onsEx = ProducerImpl.this.checkProducerException(topic, null, e); + OnExceptionContext context = new OnExceptionContext(); + context.setTopic(topic); + context.setException(onsEx); + sendCallback.onException(context); + } + }; + return rmqSendCallback; + } + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/RocketMQProducerImpl.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/RocketMQProducerImpl.java new file mode 100644 index 0000000000..03c870f01f --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/producer/RocketMQProducerImpl.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.producer; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.producer.Producer; +import org.apache.eventmesh.connector.rocketmq.common.EventMeshConstants; +import org.apache.eventmesh.connector.rocketmq.config.ClientConfiguration; + +import org.apache.rocketmq.client.exception.MQBrokerException; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.remoting.exception.RemotingException; + +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SuppressWarnings("deprecation") +public class RocketMQProducerImpl implements Producer { + + private ProducerImpl producer; + + @Override + public synchronized void init(Properties keyValue) { + final ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.init(); + String producerGroup = keyValue.getProperty("producerGroup"); + + String omsNamesrv = clientConfiguration.namesrvAddr; + Properties properties = new Properties(); + properties.put("ACCESS_POINTS", omsNamesrv); + properties.put("REGION", "namespace"); + properties.put("RMQ_PRODUCER_GROUP", producerGroup); + properties.put("OPERATION_TIMEOUT", 3000); + properties.put("PRODUCER_ID", producerGroup); + + producer = new ProducerImpl(properties); + + } + + @Override + public boolean isStarted() { + return producer.isStarted(); + } + + @Override + public boolean isClosed() { + return producer.isClosed(); + } + + @Override + public void start() { + producer.start(); + } + + @Override + public synchronized void shutdown() { + producer.shutdown(); + } + + @Override + public void publish(CloudEvent message, SendCallback sendCallback) throws Exception { + producer.sendAsync(message, sendCallback); + } + + @Override + public void request(CloudEvent message, RequestReplyCallback rrCallback, long timeout) + throws InterruptedException, RemotingException, MQClientException, MQBrokerException { + producer.request(message, rrCallback, timeout); + } + + @Override + public boolean reply(final CloudEvent message, final SendCallback sendCallback) throws Exception { + producer.reply(message, sendCallback); + return true; + } + + @Override + public void checkTopicExist(String topic) throws Exception { + this.producer.getRocketmqProducer().getDefaultMQProducerImpl().getmQClientFactory().getMQClientAPIImpl() + .getDefaultTopicRouteInfoFromNameServer(topic, EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + @Override + public void setExtFields() { + producer.setExtFields(); + } + + + @Override + public void sendOneway(CloudEvent message) { + producer.sendOneway(message); + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/BeanUtils.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/BeanUtils.java new file mode 100644 index 0000000000..ee9644502c --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/BeanUtils.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.utils; + +import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.client.log.ClientLogger; +import org.apache.rocketmq.logging.InternalLogger; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +public final class BeanUtils { + + private static final InternalLogger LOG = ClientLogger.getLog(); + + /** + * Maps primitive {@code Class}es to their corresponding wrapper {@code Class}. + */ + private static Map, Class> primitiveWrapperMap = new HashMap<>(); + + static { + primitiveWrapperMap.put(Boolean.TYPE, Boolean.class); + primitiveWrapperMap.put(Byte.TYPE, Byte.class); + primitiveWrapperMap.put(Character.TYPE, Character.class); + primitiveWrapperMap.put(Short.TYPE, Short.class); + primitiveWrapperMap.put(Integer.TYPE, Integer.class); + primitiveWrapperMap.put(Long.TYPE, Long.class); + primitiveWrapperMap.put(Double.TYPE, Double.class); + primitiveWrapperMap.put(Float.TYPE, Float.class); + primitiveWrapperMap.put(Void.TYPE, Void.TYPE); + } + + private static Map, Class> wrapperMap = new HashMap<>(); + + static { + for (final Class primitiveClass : primitiveWrapperMap.keySet()) { + final Class wrapperClass = primitiveWrapperMap.get(primitiveClass); + if (!primitiveClass.equals(wrapperClass)) { + wrapperMap.put(wrapperClass, primitiveClass); + } + } + wrapperMap.put(String.class, String.class); + } + + /** + *

Populate the JavaBeans properties of the specified bean, based on + * the specified name/value pairs. This method uses Java reflection APIs + * to identify corresponding "property setter" method names, and deals + * with setter arguments of type String, boolean, + * int, long, float, and + * double.

+ * + *

The particular setter method to be called for each property is + * determined using the usual JavaBeans introspection mechanisms. Thus, + * you may identify custom setter methods using a BeanInfo class that is + * associated with the class of the bean itself. If no such BeanInfo + * class is available, the standard method name conversion ("set" plus + * the capitalized name of the property in question) is used.

+ * + *

NOTE: It is contrary to the JavaBeans Specification + * to have more than one setter method (with different argument + * signatures) for the same property.

+ * + * @param clazz JavaBean class whose properties are being populated + * @param properties Map keyed by property name, with the corresponding (String or String[]) value(s) to be set + * @param Class type + * @return Class instance + */ + public static T populate(final Properties properties, final Class clazz) { + T obj = null; + try { + obj = clazz.getDeclaredConstructor().newInstance(); + return populate(properties, obj); + } catch (Throwable e) { + LOG.warn("Error occurs !", e); + } + return obj; + } + + public static T populate(final Properties properties, final T obj) { + Class clazz = obj.getClass(); + try { + + Set> entries = properties.entrySet(); + for (Map.Entry entry : entries) { + String entryKey = entry.getKey().toString(); + String[] keyGroup = entryKey.split("[\\._]"); + for (int i = 0; i < keyGroup.length; i++) { + keyGroup[i] = keyGroup[i].toLowerCase(); + keyGroup[i] = StringUtils.capitalize(keyGroup[i]); + } + String beanFieldNameWithCapitalization = StringUtils.join(keyGroup); + try { + setProperties(clazz, obj, "set" + beanFieldNameWithCapitalization, entry.getValue()); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { + //ignored... + } + } + } catch (RuntimeException e) { + LOG.warn("Error occurs !", e); + } + return obj; + } + + public static Class getMethodClass(Class clazz, String methodName) { + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + if (method.getName().equalsIgnoreCase(methodName)) { + return method.getParameterTypes()[0]; + } + } + return null; + } + + public static void setProperties(Class clazz, Object obj, String methodName, + Object value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class parameterClass = getMethodClass(clazz, methodName); + Method setterMethod = clazz.getMethod(methodName, parameterClass); + if (parameterClass == Boolean.TYPE) { + setterMethod.invoke(obj, Boolean.valueOf(value.toString())); + } else if (parameterClass == Integer.TYPE) { + setterMethod.invoke(obj, Integer.valueOf(value.toString())); + } else if (parameterClass == Double.TYPE) { + setterMethod.invoke(obj, Double.valueOf(value.toString())); + } else if (parameterClass == Float.TYPE) { + setterMethod.invoke(obj, Float.valueOf(value.toString())); + } else if (parameterClass == Long.TYPE) { + setterMethod.invoke(obj, Long.valueOf(value.toString())); + } else { + setterMethod.invoke(obj, value); + } + } +} + diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/CloudEventUtils.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/CloudEventUtils.java new file mode 100644 index 0000000000..dbf1175e9c --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/CloudEventUtils.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.utils; + +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.common.Constants; + +import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.common.message.Message; +import org.apache.rocketmq.common.message.MessageAccessor; +import org.apache.rocketmq.common.message.MessageConst; +import org.apache.rocketmq.common.message.MessageExt; + +import java.util.Map; +import java.util.Set; + +public class CloudEventUtils { + + public static SendResult convertSendResult( + org.apache.rocketmq.client.producer.SendResult rmqResult) { + SendResult sendResult = new SendResult(); + sendResult.setTopic(rmqResult.getMessageQueue().getTopic()); + sendResult.setMessageId(rmqResult.getMsgId()); + return sendResult; + } + + + public static Message msgConvert(MessageExt rmqMsg) { + Message message = new Message(); + if (rmqMsg.getTopic() != null) { + message.setTopic(rmqMsg.getTopic()); + } + + if (rmqMsg.getKeys() != null) { + message.setKeys(rmqMsg.getKeys()); + } + + if (rmqMsg.getTags() != null) { + message.setTags(rmqMsg.getTags()); + } + + if (rmqMsg.getBody() != null) { + message.setBody(rmqMsg.getBody()); + } + + final Set> entries = rmqMsg.getProperties().entrySet(); + + for (final Map.Entry entry : entries) { + MessageAccessor.putProperty(message, entry.getKey(), entry.getValue()); + } + + if (rmqMsg.getMsgId() != null) { + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_MESSAGE_ID), + rmqMsg.getMsgId()); + } + + if (rmqMsg.getTopic() != null) { + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_DESTINATION), + rmqMsg.getTopic()); + } + + // + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_BORN_HOST), + String.valueOf(rmqMsg.getBornHost())); + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_BORN_TIMESTAMP), + String.valueOf(rmqMsg.getBornTimestamp())); + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_STORE_HOST), + String.valueOf(rmqMsg.getStoreHost())); + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_STORE_TIMESTAMP), + String.valueOf(rmqMsg.getStoreTimestamp())); + + //use in manual ack + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_QUEUE_ID), + String.valueOf(rmqMsg.getQueueId())); + MessageAccessor.putProperty(message, buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_QUEUE_OFFSET), + String.valueOf(rmqMsg.getQueueOffset())); + + for (String sysPropKey : MessageConst.STRING_HASH_SET) { + if (StringUtils.isNotEmpty(message.getProperty(sysPropKey))) { + String prop = message.getProperty(sysPropKey); + String tmpPropKey = sysPropKey.toLowerCase().replaceAll("_", Constants.MESSAGE_PROP_SEPARATOR); + MessageAccessor.putProperty(message, tmpPropKey, prop); + message.getProperties().remove(sysPropKey); + } + } + + return message; + } + + + private static String buildCloudEventPropertyKey(String propName) { + return propName; + } + + public static org.apache.rocketmq.common.message.MessageExt msgConvertExt(Message message) { + + org.apache.rocketmq.common.message.MessageExt rmqMessageExt = + new org.apache.rocketmq.common.message.MessageExt(); + try { + if (message.getKeys() != null) { + rmqMessageExt.setKeys(message.getKeys()); + } + if (message.getTags() != null) { + rmqMessageExt.setTags(message.getTags()); + } + + + if (message.getBody() != null) { + rmqMessageExt.setBody(message.getBody()); + } + + + //All destinations in RocketMQ use Topic + rmqMessageExt.setTopic(message.getTopic()); + + int queueId = + Integer.parseInt(message.getProperty(buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_QUEUE_ID))); + long queueOffset = Long.parseLong( + message.getProperty(buildCloudEventPropertyKey(Constants.PROPERTY_MESSAGE_QUEUE_OFFSET))); + //use in manual ack + rmqMessageExt.setQueueId(queueId); + rmqMessageExt.setQueueOffset(queueOffset); + Map properties = message.getProperties(); + for (final Map.Entry entry : properties.entrySet()) { + MessageAccessor.putProperty(rmqMessageExt, entry.getKey(), entry.getValue()); + } + } catch (Exception e) { + e.printStackTrace(); + } + return rmqMessageExt; + + } + + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/OMSUtil.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/OMSUtil.java new file mode 100644 index 0000000000..f42e640321 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/utils/OMSUtil.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.utils; + +import org.apache.rocketmq.common.UtilAll; + +public class OMSUtil { + + /** + * Builds a OMS client instance name. + * + * @return a unique instance name + */ + public static String buildInstanceName() { + return UtilAll.getPid() + "%EventMesh" + "%" + System.nanoTime(); + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyService.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyService.java new file mode 100644 index 0000000000..1fe8dc3172 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyService.java @@ -0,0 +1,507 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.rocketmq.client.impl.consumer; + +import org.apache.eventmesh.connector.rocketmq.patch.EventMeshConsumeConcurrentlyContext; + +import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; +import org.apache.rocketmq.client.consumer.listener.ConsumeReturnType; +import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; +import org.apache.rocketmq.client.hook.ConsumeMessageContext; +import org.apache.rocketmq.client.log.ClientLogger; +import org.apache.rocketmq.client.stat.ConsumerStatsManager; +import org.apache.rocketmq.common.MixAll; +import org.apache.rocketmq.common.ThreadFactoryImpl; +import org.apache.rocketmq.common.message.MessageAccessor; +import org.apache.rocketmq.common.message.MessageConst; +import org.apache.rocketmq.common.message.MessageExt; +import org.apache.rocketmq.common.message.MessageQueue; +import org.apache.rocketmq.common.protocol.body.CMResult; +import org.apache.rocketmq.common.protocol.body.ConsumeMessageDirectlyResult; +import org.apache.rocketmq.logging.InternalLogger; +import org.apache.rocketmq.remoting.common.RemotingHelper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class ConsumeMessageConcurrentlyService implements ConsumeMessageService { + private static final InternalLogger log = ClientLogger.getLog(); + private final DefaultMQPushConsumerImpl defaultMQPushConsumerImpl; + private final DefaultMQPushConsumer defaultMQPushConsumer; + private final MessageListenerConcurrently messageListener; + private final BlockingQueue consumeRequestQueue; + private final ThreadPoolExecutor consumeExecutor; + private final String consumerGroup; + + static { + log.info("load custom ConsumeMessageConcurrentlyService class for eventMesh, because of updateOffset"); + } + + private final ScheduledExecutorService scheduledExecutorService; + private final ScheduledExecutorService cleanExpireMsgExecutors; + + public ConsumeMessageConcurrentlyService(DefaultMQPushConsumerImpl defaultMQPushConsumerImpl, + MessageListenerConcurrently messageListener) { + this.defaultMQPushConsumerImpl = defaultMQPushConsumerImpl; + this.messageListener = messageListener; + + this.defaultMQPushConsumer = this.defaultMQPushConsumerImpl.getDefaultMQPushConsumer(); + this.consumerGroup = this.defaultMQPushConsumer.getConsumerGroup(); + this.consumeRequestQueue = new LinkedBlockingQueue(); + + this.consumeExecutor = new ThreadPoolExecutor( + this.defaultMQPushConsumer.getConsumeThreadMin(), + this.defaultMQPushConsumer.getConsumeThreadMax(), + 1000 * 60, + TimeUnit.MILLISECONDS, + this.consumeRequestQueue, + new ThreadFactoryImpl("ConsumeMessageThread_" + consumerGroup + "_")); + + this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("ConsumeMessageScheduledThread_")); + this.cleanExpireMsgExecutors = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("CleanExpireMsgScheduledThread_")); + + log.info("new ConsumeMessageConcurrentlyService instance for eventMesh has been created "); + } + + public void start() { + if (this.defaultMQPushConsumer.getConsumeTimeout() > 0) { + this.cleanExpireMsgExecutors.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + cleanExpireMsg(); + } catch (Exception e) { + log.warn("cleanExpireMsg ", e); + } + } + + }, this.defaultMQPushConsumer.getConsumeTimeout(), this.defaultMQPushConsumer.getConsumeTimeout(), TimeUnit.MINUTES); + } + } + + @Override + public void shutdown(long awaitTerminateMillis) { + + } + + public void shutdown() { + this.scheduledExecutorService.shutdown(); + this.consumeExecutor.shutdown(); + this.cleanExpireMsgExecutors.shutdown(); + } + + public ThreadPoolExecutor getConsumeExecutor() { + return consumeExecutor; + } + + @Override + public void updateCorePoolSize(int corePoolSize) { + if (corePoolSize > 0 + && corePoolSize <= Short.MAX_VALUE + && corePoolSize < this.defaultMQPushConsumer.getConsumeThreadMax()) { + this.consumeExecutor.setCorePoolSize(corePoolSize); + } + } + + @Override + public void incCorePoolSize() { } + + @Override + public void decCorePoolSize() { } + + @Override + public int getCorePoolSize() { + return this.consumeExecutor.getCorePoolSize(); + } + + @Override + public ConsumeMessageDirectlyResult consumeMessageDirectly(MessageExt msg, String brokerName) { + ConsumeMessageDirectlyResult result = new ConsumeMessageDirectlyResult(); + result.setOrder(false); + result.setAutoCommit(true); + + List msgs = new ArrayList(); + msgs.add(msg); + MessageQueue mq = new MessageQueue(); + mq.setTopic(msg.getTopic()); + mq.setQueueId(msg.getQueueId()); + + ProcessQueue pq = new ProcessQueue(); + EventMeshConsumeConcurrentlyContext context = new EventMeshConsumeConcurrentlyContext(mq, pq); + + this.resetRetryTopic(msgs); + + final long beginTime = System.currentTimeMillis(); + + log.info("consumeMessageDirectly receive new message: {}", msg); + + try { + ConsumeConcurrentlyStatus status = this.messageListener.consumeMessage(msgs, context); + if (status != null) { + switch (status) { + case CONSUME_SUCCESS: + result.setConsumeResult(CMResult.CR_SUCCESS); + break; + case RECONSUME_LATER: + result.setConsumeResult(CMResult.CR_LATER); + break; + default: + break; + } + } else { + result.setConsumeResult(CMResult.CR_RETURN_NULL); + } + } catch (Throwable e) { + result.setConsumeResult(CMResult.CR_THROW_EXCEPTION); + result.setRemark(RemotingHelper.exceptionSimpleDesc(e)); + + log.warn(String.format("consumeMessageDirectly exception: %s Group: %s Msgs: %s MQ: %s", + RemotingHelper.exceptionSimpleDesc(e), + ConsumeMessageConcurrentlyService.this.consumerGroup, + msgs, + mq), e); + } + + result.setSpentTimeMills(System.currentTimeMillis() - beginTime); + + log.info("consumeMessageDirectly Result: {}", result); + + return result; + } + + @Override + public void submitConsumeRequest( + final List msgs, + final ProcessQueue processQueue, + final MessageQueue messageQueue, + final boolean dispatchToConsume) { + final int consumeBatchSize = this.defaultMQPushConsumer.getConsumeMessageBatchMaxSize(); + if (msgs.size() <= consumeBatchSize) { + ConsumeRequest consumeRequest = new ConsumeRequest(msgs, processQueue, messageQueue); + try { + this.consumeExecutor.submit(consumeRequest); + } catch (RejectedExecutionException e) { + this.submitConsumeRequestLater(consumeRequest); + } + } else { + for (int total = 0; total < msgs.size(); ) { + List msgThis = new ArrayList(consumeBatchSize); + for (int i = 0; i < consumeBatchSize; i++, total++) { + if (total < msgs.size()) { + msgThis.add(msgs.get(total)); + } else { + break; + } + } + + ConsumeRequest consumeRequest = new ConsumeRequest(msgThis, processQueue, messageQueue); + try { + this.consumeExecutor.submit(consumeRequest); + } catch (RejectedExecutionException e) { + for (; total < msgs.size(); total++) { + msgThis.add(msgs.get(total)); + } + + this.submitConsumeRequestLater(consumeRequest); + } + } + } + } + + public void resetRetryTopic(final List msgs) { + final String groupTopic = MixAll.getRetryTopic(consumerGroup); + for (MessageExt msg : msgs) { + String retryTopic = msg.getProperty(MessageConst.PROPERTY_RETRY_TOPIC); + if (retryTopic != null && groupTopic.equals(msg.getTopic())) { + msg.setTopic(retryTopic); + } + } + } + + private void cleanExpireMsg() { + Iterator> it = + this.defaultMQPushConsumerImpl.getRebalanceImpl().getProcessQueueTable().entrySet().iterator(); + while (it.hasNext()) { + Map.Entry next = it.next(); + ProcessQueue pq = next.getValue(); + pq.cleanExpiredMsg(this.defaultMQPushConsumer); + } + } + + public void processConsumeResult( + final ConsumeConcurrentlyStatus status, + final EventMeshConsumeConcurrentlyContext context, + final ConsumeRequest consumeRequest) { + int ackIndex = context.getAckIndex(); + + if (consumeRequest.getMsgs().isEmpty()) { + return; + } + + switch (status) { + case CONSUME_SUCCESS: + if (ackIndex >= consumeRequest.getMsgs().size()) { + ackIndex = consumeRequest.getMsgs().size() - 1; + } + int ok = ackIndex + 1; + int failed = consumeRequest.getMsgs().size() - ok; + this.getConsumerStatsManager().incConsumeOKTPS(consumerGroup, consumeRequest.getMessageQueue().getTopic(), ok); + this.getConsumerStatsManager().incConsumeFailedTPS(consumerGroup, consumeRequest.getMessageQueue().getTopic(), failed); + break; + case RECONSUME_LATER: + ackIndex = -1; + this.getConsumerStatsManager().incConsumeFailedTPS(consumerGroup, consumeRequest.getMessageQueue().getTopic(), + consumeRequest.getMsgs().size()); + break; + default: + break; + } + + switch (this.defaultMQPushConsumer.getMessageModel()) { + case BROADCASTING: + for (int i = ackIndex + 1; i < consumeRequest.getMsgs().size(); i++) { + MessageExt msg = consumeRequest.getMsgs().get(i); + log.warn("BROADCASTING, the message consume failed, drop it, {}", msg.toString()); + } + break; + case CLUSTERING: + List msgBackFailed = new ArrayList(consumeRequest.getMsgs().size()); + for (int i = ackIndex + 1; i < consumeRequest.getMsgs().size(); i++) { + MessageExt msg = consumeRequest.getMsgs().get(i); + boolean result = this.sendMessageBack(msg, context); + if (!result) { + msg.setReconsumeTimes(msg.getReconsumeTimes() + 1); + msgBackFailed.add(msg); + } + } + + if (!msgBackFailed.isEmpty()) { + consumeRequest.getMsgs().removeAll(msgBackFailed); + + this.submitConsumeRequestLater(msgBackFailed, consumeRequest.getProcessQueue(), consumeRequest.getMessageQueue()); + } + break; + default: + break; + } + if (!context.isManualAck()) { + updateOffset(consumeRequest.getMsgs(), context); + } + } + + public void updateOffset(List msgs, ConsumeConcurrentlyContext context) { + for (MessageExt m : msgs) { + log.debug("update offset, msg: {} {} {}", m.getTopic(), m.getQueueId(), m.getQueueOffset()); + } + MessageQueue messageQueue = context.getMessageQueue(); + ProcessQueue processQueue = ((EventMeshConsumeConcurrentlyContext) context).getProcessQueue(); + long offset = processQueue.removeMessage(msgs); + if (offset >= 0) { + log.debug("update offset={}", offset); + this.defaultMQPushConsumerImpl.getOffsetStore().updateOffset(messageQueue, offset, true); + } + } + + + public ConsumerStatsManager getConsumerStatsManager() { + return this.defaultMQPushConsumerImpl.getConsumerStatsManager(); + } + + public boolean sendMessageBack(final MessageExt msg, final ConsumeConcurrentlyContext context) { + int delayLevel = context.getDelayLevelWhenNextConsume(); + + try { + this.defaultMQPushConsumerImpl.sendMessageBack(msg, delayLevel, context.getMessageQueue().getBrokerName()); + return true; + } catch (Exception e) { + log.error("sendMessageBack exception, group: " + this.consumerGroup + " msg: " + msg.toString(), e); + } + + return false; + } + + private void submitConsumeRequestLater( + final List msgs, + final ProcessQueue processQueue, + final MessageQueue messageQueue + ) { + + this.scheduledExecutorService.schedule(new Runnable() { + + @Override + public void run() { + ConsumeMessageConcurrentlyService.this.submitConsumeRequest(msgs, processQueue, messageQueue, true); + } + }, 5000, TimeUnit.MILLISECONDS); + } + + private void submitConsumeRequestLater(final ConsumeRequest consumeRequest) { + final int times = defaultMQPushConsumerImpl.getDefaultMQPushConsumer().getMaxReconsumeTimes(); + log.warn("rejected by thread pool, try resubmit {} times, consumerGroup:{}", times, + defaultMQPushConsumerImpl.getDefaultMQPushConsumer().getConsumerGroup()); + this.scheduledExecutorService.schedule(new Runnable() { + + @Override + public void run() { + boolean success = false; + for (int i = 0; i < times; i++) { + try { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + //ignore + } + ConsumeMessageConcurrentlyService.this.consumeExecutor.submit(consumeRequest); + success = true; + break; + } catch (RejectedExecutionException e) { + //ignore + } + } + if (!success) { + for (MessageExt messageExt : consumeRequest.getMsgs()) { + log.warn("discard rejected messages {} after retry {} times", messageExt, times); + } + consumeRequest.getProcessQueue().removeMessage(consumeRequest.getMsgs()); + } + } + }, 1000, TimeUnit.MILLISECONDS); + } + + class ConsumeRequest implements Runnable { + private final List msgs; + private final ProcessQueue processQueue; + private final MessageQueue messageQueue; + + public ConsumeRequest(List msgs, ProcessQueue processQueue, MessageQueue messageQueue) { + this.msgs = msgs; + this.processQueue = processQueue; + this.messageQueue = messageQueue; + } + + public List getMsgs() { + return msgs; + } + + public ProcessQueue getProcessQueue() { + return processQueue; + } + + @Override + public void run() { + if (this.processQueue.isDropped()) { + log.info("the message queue not be able to consume, because it's dropped. group={} {}", + ConsumeMessageConcurrentlyService.this.consumerGroup, this.messageQueue); + return; + } + + MessageListenerConcurrently listener = ConsumeMessageConcurrentlyService.this.messageListener; + EventMeshConsumeConcurrentlyContext context = new EventMeshConsumeConcurrentlyContext(messageQueue, processQueue); + ConsumeConcurrentlyStatus status = null; + + ConsumeMessageContext consumeMessageContext = null; + if (ConsumeMessageConcurrentlyService.this.defaultMQPushConsumerImpl.hasHook()) { + consumeMessageContext = new ConsumeMessageContext(); + consumeMessageContext.setConsumerGroup(defaultMQPushConsumer.getConsumerGroup()); + consumeMessageContext.setProps(new HashMap()); + consumeMessageContext.setMq(messageQueue); + consumeMessageContext.setMsgList(msgs); + consumeMessageContext.setSuccess(false); + ConsumeMessageConcurrentlyService.this.defaultMQPushConsumerImpl.executeHookBefore(consumeMessageContext); + } + + long beginTimestamp = System.currentTimeMillis(); + boolean hasException = false; + ConsumeReturnType returnType = ConsumeReturnType.SUCCESS; + try { + ConsumeMessageConcurrentlyService.this.resetRetryTopic(msgs); + if (msgs != null && !msgs.isEmpty()) { + for (MessageExt msg : msgs) { + MessageAccessor.setConsumeStartTimeStamp(msg, String.valueOf(System.currentTimeMillis())); + } + + + } + status = listener.consumeMessage(Collections.unmodifiableList(msgs), context); + } catch (Throwable e) { + log.warn("consumeMessage exception: {} Group: {} Msgs: {} MQ: {}", + RemotingHelper.exceptionSimpleDesc(e), + ConsumeMessageConcurrentlyService.this.consumerGroup, + msgs, + messageQueue); + hasException = true; + } + long consumeRT = System.currentTimeMillis() - beginTimestamp; + if (null == status) { + if (hasException) { + returnType = ConsumeReturnType.EXCEPTION; + } else { + returnType = ConsumeReturnType.RETURNNULL; + } + } else if (consumeRT >= defaultMQPushConsumer.getConsumeTimeout() * 60 * 1000) { + returnType = ConsumeReturnType.TIME_OUT; + } else if (ConsumeConcurrentlyStatus.RECONSUME_LATER == status) { + returnType = ConsumeReturnType.FAILED; + } else if (ConsumeConcurrentlyStatus.CONSUME_SUCCESS == status) { + returnType = ConsumeReturnType.SUCCESS; + } + + if (ConsumeMessageConcurrentlyService.this.defaultMQPushConsumerImpl.hasHook()) { + consumeMessageContext.getProps().put(MixAll.CONSUME_CONTEXT_TYPE, returnType.name()); + } + + if (null == status) { + log.warn("consumeMessage return null, Group: {} Msgs: {} MQ: {}", + ConsumeMessageConcurrentlyService.this.consumerGroup, + msgs, + messageQueue); + status = ConsumeConcurrentlyStatus.RECONSUME_LATER; + } + + if (ConsumeMessageConcurrentlyService.this.defaultMQPushConsumerImpl.hasHook()) { + consumeMessageContext.setStatus(status.toString()); + consumeMessageContext.setSuccess(ConsumeConcurrentlyStatus.CONSUME_SUCCESS == status); + ConsumeMessageConcurrentlyService.this.defaultMQPushConsumerImpl.executeHookAfter(consumeMessageContext); + } + + ConsumeMessageConcurrentlyService.this.getConsumerStatsManager() + .incConsumeRT(ConsumeMessageConcurrentlyService.this.consumerGroup, messageQueue.getTopic(), consumeRT); + + ConsumeMessageConcurrentlyService.this.processConsumeResult(status, context, this); + } + + public MessageQueue getMessageQueue() { + return messageQueue; + } + + } +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.connector.ConnectorResourceService b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.connector.ConnectorResourceService new file mode 100644 index 0000000000..fadf0de344 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.connector.ConnectorResourceService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +rocketmq=org.apache.eventmesh.connector.rocketmq.connector.ConnectorResourceServiceRocketmqImpl \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer new file mode 100644 index 0000000000..0df2e286d7 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +rocketmq=org.apache.eventmesh.connector.rocketmq.consumer.RocketMQConsumerImpl \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer new file mode 100644 index 0000000000..ef4959d994 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +rocketmq=org.apache.eventmesh.connector.rocketmq.producer.RocketMQProducerImpl \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/rocketmq-client.properties b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/rocketmq-client.properties new file mode 100644 index 0000000000..8e0822ad36 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/main/resources/rocketmq-client.properties @@ -0,0 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#######################rocketmq-client################## +eventMesh.server.rocketmq.namesrvAddr=127.0.0.1:9876;127.0.0.1:9876 +eventMesh.server.rocketmq.cluster=DefaultCluster +eventMesh.server.rocketmq.accessKey=******** +eventMesh.server.rocketmq.secretKey=******** diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/config/ConfigurationWrapperTest.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/config/ConfigurationWrapperTest.java new file mode 100644 index 0000000000..6d25baf7cf --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/config/ConfigurationWrapperTest.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rocketmq.config; + +import org.junit.Assert; +import org.junit.Test; + +public class ConfigurationWrapperTest { + + @Test + public void getProp() { + String namesrcAddr = ConfigurationWrapper.getProp("eventMesh.server.rocketmq.namesrvAddr"); + Assert.assertNotNull(namesrcAddr); + } +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/producer/DefaultProducerImplTest.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/producer/DefaultProducerImplTest.java new file mode 100644 index 0000000000..3114c54f0e --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/producer/DefaultProducerImplTest.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.producer; + + +import org.junit.After; +import org.junit.Before; + +public class DefaultProducerImplTest { + + @Before + public void before() { + } + + + @After + public void after() { + //TBD:Remove topic + } + + //@Test + //public void testCreate_EmptyTopic() { + // MeshMQProducer meshPub = new RocketMQProducerImpl(); + // try { + // meshPub.createTopic(" "); + // } catch (OMSRuntimeException e) { + // assertThat(e.getMessage()).isEqualToIgnoringWhitespace("RocketMQ can not create topic"); + // } + //} + // + //@Test + //public void testCreate_NullTopic() { + // MeshMQProducer meshPub = new RocketMQProducerImpl(); + // try { + // meshPub.createTopic(null); + // } catch (OMSRuntimeException e) { + // String errorMessage = e.getMessage(); + // assertThat(errorMessage).isEqualTo("RocketMQ can not create topic null"); + // } + //} +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/consumer/PushConsumerImplTest.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/consumer/PushConsumerImplTest.java new file mode 100644 index 0000000000..683183bc21 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/consumer/PushConsumerImplTest.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.rocketmq.consumer; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.EventMeshAction; +import org.apache.eventmesh.connector.rocketmq.consumer.PushConsumerImpl; +import org.apache.eventmesh.connector.rocketmq.domain.NonStandardKeys; + +import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; +import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; +import org.apache.rocketmq.common.message.MessageExt; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Properties; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import io.cloudevents.CloudEvent; + +@RunWith(MockitoJUnitRunner.class) +public class PushConsumerImplTest { + private PushConsumerImpl consumer; + + @Mock + private DefaultMQPushConsumer rocketmqPushConsumer; + + @Before + public void before() throws Exception { + Properties consumerProp = new Properties(); + //consumerProp.setProperty(OMSBuiltinKeys.DRIVER_IMPL, + // "org.apache.eventmesh.connector.rocketmq.MessagingAccessPointImpl"); + consumerProp.setProperty("access_points", "IP1:9876,IP2:9876"); + //final MessagingAccessPoint messagingAccessPoint = OMS.builder().build(consumerProp); + // .endpoint("oms:rocketmq://IP1:9876,IP2:9876/namespace").build(config); + + consumerProp.setProperty("message.model", "CLUSTERING"); + + //Properties consumerProp = new Properties(); + consumerProp.put("CONSUMER_ID", "TestGroup"); + consumer = new PushConsumerImpl(consumerProp); + + + Field field = PushConsumerImpl.class.getDeclaredField("rocketmqPushConsumer"); + field.setAccessible(true); + DefaultMQPushConsumer innerConsumer = (DefaultMQPushConsumer) field.get(consumer); + field.set(consumer, rocketmqPushConsumer); //Replace + + Mockito.when(rocketmqPushConsumer.getMessageListener()).thenReturn(innerConsumer.getMessageListener()); + consumer.start(); + } + + @After + public void after() throws Exception { + Mockito.verify(rocketmqPushConsumer).getMessageListener(); + consumer.shutdown(); + } + + @Test + public void testConsumeMessage() { + final byte[] testBody = new byte[]{'a', 'b'}; + + MessageExt consumedMsg = new MessageExt(); + consumedMsg.setMsgId("NewMsgId"); + consumedMsg.setBody(testBody); + consumedMsg.putUserProperty(NonStandardKeys.MESSAGE_DESTINATION, "TOPIC"); + consumedMsg.setTopic("HELLO_QUEUE"); + consumer.subscribe("HELLO_QUEUE", "*"); + ((MessageListenerConcurrently) rocketmqPushConsumer + .getMessageListener()).consumeMessage(Collections.singletonList(consumedMsg), null); + + + } +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/producer/ProducerImplTest.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/producer/ProducerImplTest.java new file mode 100644 index 0000000000..d144bd2c4c --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/producer/ProducerImplTest.java @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.rocketmq.producer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Fail.failBecauseExceptionWasNotThrown; +import static org.mockito.ArgumentMatchers.any; + +import org.apache.eventmesh.api.exception.ConnectorRuntimeException; +import org.apache.eventmesh.connector.rocketmq.producer.AbstractProducer; +import org.apache.eventmesh.connector.rocketmq.producer.ProducerImpl; + +import org.apache.rocketmq.client.exception.MQBrokerException; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.apache.rocketmq.client.producer.SendResult; +import org.apache.rocketmq.client.producer.SendStatus; +import org.apache.rocketmq.common.ServiceState; +import org.apache.rocketmq.common.message.Message; +import org.apache.rocketmq.common.message.MessageQueue; +import org.apache.rocketmq.remoting.exception.RemotingException; + +import java.lang.reflect.Field; +import java.net.URI; +import java.util.Properties; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +@RunWith(MockitoJUnitRunner.class) +public class ProducerImplTest { + private ProducerImpl producer; + + @Mock + private DefaultMQProducer rocketmqProducer; + + @Before + public void before() throws NoSuchFieldException, IllegalAccessException { + Properties config = new Properties(); + config.setProperty("access_points", "IP1:9876,IP2:9876"); + producer = new ProducerImpl(config); + + Field field = AbstractProducer.class.getDeclaredField("rocketmqProducer"); + field.setAccessible(true); + field.set(producer, rocketmqProducer); + + producer.start(); + + } + + @After + public void after() { + producer.shutdown(); + } + + @Test + public void testSend_OK() throws InterruptedException, RemotingException, MQClientException, MQBrokerException { + SendResult sendResult = new SendResult(); + sendResult.setMsgId("TestMsgID"); + sendResult.setSendStatus(SendStatus.SEND_OK); + MessageQueue messageQueue = new MessageQueue("HELLO_TOPIC", "testBroker", 0); + sendResult.setMessageQueue(messageQueue); + + Mockito.when(rocketmqProducer.send(any(Message.class))).thenReturn(sendResult); + + DefaultMQProducer defaultMQProducer = new DefaultMQProducer("testGroup"); + DefaultMQProducerImpl defaultMQProducerImpl = new DefaultMQProducerImpl(defaultMQProducer); + defaultMQProducerImpl.setServiceState(ServiceState.RUNNING); + Mockito.when(rocketmqProducer.getDefaultMQProducerImpl()).thenReturn(defaultMQProducerImpl); + + + CloudEvent cloudEvent = CloudEventBuilder.v1() + .withId("id1") + .withSource(URI.create("https://github.com/cloudevents/*****")) + .withType("producer.example") + .withSubject("HELLO_TOPIC") + .withData("hello world".getBytes()) + .build(); + org.apache.eventmesh.api.SendResult result = + producer.send(cloudEvent); + + assertThat(result.getMessageId()).isEqualTo("TestMsgID"); + Mockito.verify(rocketmqProducer).getDefaultMQProducerImpl(); + Mockito.verify(rocketmqProducer).send(any(Message.class)); + + } + + @Test + public void testSend_WithException() throws InterruptedException, RemotingException, MQClientException, MQBrokerException { + DefaultMQProducer defaultMQProducer = new DefaultMQProducer("testGroup"); + DefaultMQProducerImpl defaultMQProducerImpl = new DefaultMQProducerImpl(defaultMQProducer); + defaultMQProducerImpl.setServiceState(ServiceState.RUNNING); + Mockito.when(rocketmqProducer.getDefaultMQProducerImpl()).thenReturn(defaultMQProducerImpl); + MQClientException exception = new MQClientException("Send message to RocketMQ broker failed.", new Exception()); + Mockito.when(rocketmqProducer.send(any(Message.class))).thenThrow(exception); + + try { + CloudEvent cloudEvent = CloudEventBuilder.v1() + .withId("id1") + .withSource(URI.create("https://github.com/cloudevents/*****")) + .withType("producer.example") + .withSubject("HELLO_TOPIC") + .withData(new byte[]{'a'}) + .build(); + producer.send(cloudEvent); + failBecauseExceptionWasNotThrown(ConnectorRuntimeException.class); + } catch (Exception e) { + assertThat(e).hasMessageContaining("Send message to RocketMQ broker failed."); + } + + Mockito.verify(rocketmqProducer).send(any(Message.class)); + } + +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/promise/DefaultPromiseTest.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/promise/DefaultPromiseTest.java new file mode 100644 index 0000000000..3d4c8c2ab3 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/promise/DefaultPromiseTest.java @@ -0,0 +1,121 @@ +///* +// * Licensed to the Apache Software Foundation (ASF) under one or more +// * contributor license agreements. See the NOTICE file distributed with +// * this work for additional information regarding copyright ownership. +// * The ASF licenses this file to You under the Apache License, Version 2.0 +// * (the "License"); you may not use this file except in compliance with +// * the License. You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +//package rocketmq.promise; +// +//import org.apache.eventmesh.connector.rocketmq.promise.DefaultPromise; +//import io.openmessaging.Future; +//import io.openmessaging.FutureListener; +//import io.openmessaging.Promise; +//import io.openmessaging.exception.OMSRuntimeException; +//import org.junit.Before; +//import org.junit.Test; +// +//import static org.assertj.core.api.Assertions.assertThat; +//import static org.assertj.core.api.Fail.failBecauseExceptionWasNotThrown; +// +//public class DefaultPromiseTest { +// private Promise promise; +// +// @Before +// public void init() { +// promise = new DefaultPromise<>(); +// } +// +// @Test +// public void testIsCancelled() throws Exception { +// assertThat(promise.isCancelled()).isEqualTo(false); +// } +// +// @Test +// public void testIsDone() throws Exception { +// assertThat(promise.isDone()).isEqualTo(false); +// promise.set("Done"); +// assertThat(promise.isDone()).isEqualTo(true); +// } +// +// @Test +// public void testGet() throws Exception { +// promise.set("Done"); +// assertThat(promise.get()).isEqualTo("Done"); +// } +// +// @Test +// public void testGet_WithTimeout() throws Exception { +// try { +// promise.get(100); +// failBecauseExceptionWasNotThrown(OMSRuntimeException.class); +// } catch (OMSRuntimeException e) { +// assertThat(e).hasMessageContaining("Get request result is timeout or interrupted"); +// } +// } +// +// @Test +// public void testAddListener() throws Exception { +// promise.addListener(new FutureListener() { +// @Override +// public void operationComplete(Future future) { +// assertThat(promise.get()).isEqualTo("Done"); +// +// } +// }); +// promise.set("Done"); +// } +// +// @Test +// public void testAddListener_ListenerAfterSet() throws Exception { +// promise.set("Done"); +// promise.addListener(new FutureListener() { +// @Override +// public void operationComplete(Future future) { +// assertThat(future.get()).isEqualTo("Done"); +// } +// }); +// } +// +// @Test +// public void testAddListener_WithException_ListenerAfterSet() throws Exception { +// final Throwable exception = new OMSRuntimeException("-1", "Test Error"); +// promise.setFailure(exception); +// promise.addListener(new FutureListener() { +// @Override +// public void operationComplete(Future future) { +// assertThat(promise.getThrowable()).isEqualTo(exception); +// } +// }); +// } +// +// @Test +// public void testAddListener_WithException() throws Exception { +// final Throwable exception = new OMSRuntimeException("-1", "Test Error"); +// promise.addListener(new FutureListener() { +// @Override +// public void operationComplete(Future future) { +// assertThat(promise.getThrowable()).isEqualTo(exception); +// } +// }); +// promise.setFailure(exception); +// } +// +// @Test +// public void getThrowable() throws Exception { +// assertThat(promise.getThrowable()).isNull(); +// Throwable exception = new OMSRuntimeException("-1", "Test Error"); +// promise.setFailure(exception); +// assertThat(promise.getThrowable()).isEqualTo(exception); +// } +// +//} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/utils/BeanUtilsTest.java b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/utils/BeanUtilsTest.java new file mode 100644 index 0000000000..1a7f52c0e5 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/java/org/apache/rocketmq/utils/BeanUtilsTest.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.rocketmq.utils; + +import org.apache.eventmesh.connector.rocketmq.config.ClientConfig; +import org.apache.eventmesh.connector.rocketmq.domain.NonStandardKeys; +import org.apache.eventmesh.connector.rocketmq.utils.BeanUtils; + +import java.util.Properties; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class BeanUtilsTest { + private Properties properties = new Properties(); + + public static class CustomizedConfig extends ClientConfig { + static final String STRING_TEST = "string.test"; + String stringTest = "foobar"; + + static final String DOUBLE_TEST = "double.test"; + double doubleTest = 123.0; + + static final String LONG_TEST = "long.test"; + long longTest = 123L; + + String getStringTest() { + return stringTest; + } + + public void setStringTest(String stringTest) { + this.stringTest = stringTest; + } + + double getDoubleTest() { + return doubleTest; + } + + public void setDoubleTest(final double doubleTest) { + this.doubleTest = doubleTest; + } + + long getLongTest() { + return longTest; + } + + public void setLongTest(final long longTest) { + this.longTest = longTest; + } + + public CustomizedConfig() { + } + } + + @Before + public void before() { + properties.put(NonStandardKeys.MAX_REDELIVERY_TIMES, 120); + properties.put(CustomizedConfig.STRING_TEST, "kaka"); + properties.put(NonStandardKeys.CONSUMER_GROUP, "Default_Consumer_Group"); + properties.put(NonStandardKeys.MESSAGE_CONSUME_TIMEOUT, 101); + + properties.put(CustomizedConfig.LONG_TEST, 1234567890L); + properties.put(CustomizedConfig.DOUBLE_TEST, 10.234); + } + + @Test + public void testPopulate() { + CustomizedConfig config = BeanUtils.populate(properties, CustomizedConfig.class); + + //RemotingConfig config = BeanUtils.populate(properties, RemotingConfig.class); + Assert.assertEquals(config.getRmqMaxRedeliveryTimes(), 120); + Assert.assertEquals(config.getStringTest(), "kaka"); + Assert.assertEquals(config.getRmqConsumerGroup(), "Default_Consumer_Group"); + Assert.assertEquals(config.getRmqMessageConsumeTimeout(), 101); + Assert.assertEquals(config.getLongTest(), 1234567890L); + Assert.assertEquals(config.getDoubleTest(), 10.234, 0.000001); + } + + @Test + public void testPopulate_ExistObj() { + CustomizedConfig config = new CustomizedConfig(); + config.setConsumerId("NewConsumerId"); + + Assert.assertEquals(config.getConsumerId(), "NewConsumerId"); + + config = BeanUtils.populate(properties, config); + + //RemotingConfig config = BeanUtils.populate(properties, RemotingConfig.class); + Assert.assertEquals(config.getRmqMaxRedeliveryTimes(), 120); + Assert.assertEquals(config.getStringTest(), "kaka"); + Assert.assertEquals(config.getRmqConsumerGroup(), "Default_Consumer_Group"); + Assert.assertEquals(config.getRmqMessageConsumeTimeout(), 101); + Assert.assertEquals(config.getLongTest(), 1234567890L); + Assert.assertEquals(config.getDoubleTest(), 10.234, 0.000001); + } + +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/resources/META-INF/services/org.apache.io.openmessaging.producer.Producer b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/resources/META-INF/services/org.apache.io.openmessaging.producer.Producer new file mode 100644 index 0000000000..bf0a8ddc29 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/resources/META-INF/services/org.apache.io.openmessaging.producer.Producer @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +org.apache.eventmesh.connector.rocketmq.producer.ProducerImpl \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/resources/rocketmq-client.properties b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/resources/rocketmq-client.properties new file mode 100644 index 0000000000..1261f30e2c --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-rocketmq/src/test/resources/rocketmq-client.properties @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#######################rocketmq-client################## +eventMesh.server.rocketmq.namesrvAddr=127.0.0.1:9876;127.0.0.1:9876 diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/build.gradle b/eventmesh-connector-plugin/eventmesh-connector-standalone/build.gradle new file mode 100644 index 0000000000..c178f455a1 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/build.gradle @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation project(":eventmesh-common") + implementation project(":eventmesh-connector-plugin:eventmesh-connector-api") +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/gradle.properties b/eventmesh-connector-plugin/eventmesh-connector-standalone/gradle.properties new file mode 100644 index 0000000000..9499e382cb --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=connector +pluginName=standalone \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/MessageQueue.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/MessageQueue.java new file mode 100644 index 0000000000..ddac489d4d --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/MessageQueue.java @@ -0,0 +1,224 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.broker; + +import org.apache.eventmesh.connector.standalone.broker.model.MessageEntity; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import com.google.common.base.Preconditions; + +/** + * This is a block queue, can get entity by offset. + * The queue is a FIFO data structure. + */ +public class MessageQueue { + + public MessageEntity[] items; + + private int takeIndex; + + private int putIndex; + + private int count; + + private final ReentrantLock lock; + + private final Condition notEmpty; + + private final Condition notFull; + + + public MessageQueue() { + this(2 << 10); + } + + public MessageQueue(int capacity) { + if (capacity <= 0) { + throw new IllegalArgumentException("capacity is illegal"); + } + this.items = new MessageEntity[capacity]; + this.lock = new ReentrantLock(); + this.notEmpty = lock.newCondition(); + this.notFull = lock.newCondition(); + } + + /** + * Insert the message at the tail of this queue, waiting for space to become available if the queue is full + * + * @param messageEntity + */ + public void put(MessageEntity messageEntity) throws InterruptedException { + Preconditions.checkNotNull(messageEntity); + ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + while (count == items.length) { + notFull.await(); + } + enqueue(messageEntity); + } finally { + lock.unlock(); + } + } + + /** + * Get the first message at this queue, waiting for the message is available if the queue is empty, + * this method will not remove the message + * + * @return MessageEntity + * @throws InterruptedException + */ + public MessageEntity take() throws InterruptedException { + ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + while (count == 0) { + notEmpty.await(); + } + return dequeue(); + } finally { + lock.unlock(); + } + } + + /** + * Get the first message at this queue, if the queue is empty return null immediately + * + * @return MessageEntity + */ + public MessageEntity peek() { + ReentrantLock lock = this.lock; + lock.lock(); + try { + return itemAt(takeIndex); + } finally { + lock.unlock(); + } + } + + /** + * Get the head in this queue + * + * @return MessageEntity + */ + public MessageEntity getHead() { + return peek(); + } + + /** + * Get the tail in this queue + * + * @return MessageEntity + */ + public MessageEntity getTail() { + ReentrantLock lock = this.lock; + lock.lock(); + try { + if (count == 0) { + return null; + } + int tailIndex = putIndex - 1; + if (tailIndex < 0) { + tailIndex += items.length; + } + return itemAt(tailIndex); + } finally { + lock.unlock(); + } + } + + /** + * Get the message by offset, since the offset is increment, so we can get the first message in this queue + * and calculate the index of this offset + * + * @param offset + * @return MessageEntity + */ + public MessageEntity getByOffset(long offset) { + ReentrantLock lock = this.lock; + lock.lock(); + try { + MessageEntity head = getHead(); + if (head == null) { + return null; + } + if (head.getOffset() > offset) { + throw new RuntimeException(String.format("The message has been deleted, offset: %s", offset)); + } + MessageEntity tail = getTail(); + if (tail == null || tail.getOffset() < offset) { + return null; + } + int offsetDis = (int) (head.getOffset() - offset); + int offsetIndex = takeIndex - offsetDis; + if (offsetIndex < 0) { + offsetIndex += items.length; + } + return itemAt(offsetIndex); + } finally { + lock.unlock(); + } + } + + public void removeHead() { + ReentrantLock lock = this.lock; + lock.lock(); + try { + if (count == 0) { + return; + } + items[takeIndex++] = null; + if (takeIndex == items.length) { + takeIndex = 0; + } + notFull.signal(); + } finally { + lock.unlock(); + } + } + + public int getSize() { + return count; + } + + + private MessageEntity itemAt(int index) { + return items[index]; + } + + private void enqueue(MessageEntity messageEntity) { + items[putIndex++] = messageEntity; + if (putIndex == items.length) { + putIndex = 0; + } + count++; + notEmpty.signal(); + } + + private MessageEntity dequeue() { + MessageEntity item = items[takeIndex++]; + if (takeIndex == items.length) { + takeIndex = 0; + } + notFull.signal(); + return item; + } + +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/StandaloneBroker.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/StandaloneBroker.java new file mode 100644 index 0000000000..2e715e35b5 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/StandaloneBroker.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.broker; + +import org.apache.eventmesh.connector.standalone.broker.model.MessageEntity; +import org.apache.eventmesh.connector.standalone.broker.model.TopicMetadata; +import org.apache.eventmesh.connector.standalone.broker.task.HistoryMessageClearTask; + +import org.apache.commons.lang3.tuple.Pair; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import io.cloudevents.CloudEvent; + +/** + * This broker used to store event, it just support standalone mode, you shouldn't use this module in production environment + */ +public class StandaloneBroker { + + private final ConcurrentHashMap messageContainer; + + // todo: move the offset manage to consumer + private final ConcurrentHashMap offsetMap; + + private StandaloneBroker() { + this.messageContainer = new ConcurrentHashMap<>(); + this.offsetMap = new ConcurrentHashMap<>(); + startHistoryMessageCleanTask(); + } + + public static StandaloneBroker getInstance() { + return StandaloneBrokerInstanceHolder.instance; + } + + /** + * put message + * + * @param topicName topic name + * @param message message + * @throws InterruptedException + */ + public MessageEntity putMessage(String topicName, CloudEvent message) throws InterruptedException { + Pair pair = createTopicIfAbsent(topicName); + AtomicLong topicOffset = pair.getRight(); + MessageQueue messageQueue = pair.getLeft(); + + MessageEntity messageEntity = new MessageEntity( + new TopicMetadata(topicName), message, topicOffset.getAndIncrement(), System.currentTimeMillis()); + messageQueue.put(messageEntity); + + return messageEntity; + } + + /** + * Get the message, if the queue is empty then await + * + * @param topicName + */ + public CloudEvent takeMessage(String topicName) throws InterruptedException { + TopicMetadata topicMetadata = new TopicMetadata(topicName); + return messageContainer.computeIfAbsent(topicMetadata, k -> new MessageQueue()).take().getMessage(); + } + + /** + * Get the message, if the queue is empty return null + * + * @param topicName + */ + public CloudEvent getMessage(String topicName) { + TopicMetadata topicMetadata = new TopicMetadata(topicName); + MessageEntity head = messageContainer.computeIfAbsent(topicMetadata, k -> new MessageQueue()).getHead(); + if (head == null) { + return null; + } + return head.getMessage(); + } + + /** + * Get the message by offset + * + * @param topicName topic name + * @param offset offset + * @return CloudEvent + */ + public CloudEvent getMessage(String topicName, long offset) { + TopicMetadata topicMetadata = new TopicMetadata(topicName); + MessageEntity messageEntity = messageContainer.computeIfAbsent(topicMetadata, k -> new MessageQueue()).getByOffset(offset); + if (messageEntity == null) { + return null; + } + return messageEntity.getMessage(); + } + + + private void startHistoryMessageCleanTask() { + Thread thread = new Thread(new HistoryMessageClearTask(messageContainer)); + thread.setDaemon(true); + thread.setName("StandaloneBroker-HistoryMessageCleanTask"); + thread.start(); + } + + public boolean checkTopicExist(String topicName) { + return messageContainer.containsKey(new TopicMetadata(topicName)); + } + + /** + * if topic not exist, create a topic + * + * @param topicName topicName + * @return messageQueue and offset + */ + public Pair createTopicIfAbsent(String topicName) { + TopicMetadata topicMetadata = new TopicMetadata(topicName); + MessageQueue messageQueue = messageContainer.computeIfAbsent(topicMetadata, k -> new MessageQueue()); + AtomicLong offset = offsetMap.computeIfAbsent(topicMetadata, k -> new AtomicLong()); + return Pair.of(messageQueue, offset); + } + + public void updateOffset(TopicMetadata topicMetadata, long offset) { + offsetMap.computeIfPresent(topicMetadata, (k, v) -> { + v.set(offset); + return v; + }); + } + + private static class StandaloneBrokerInstanceHolder { + private static final StandaloneBroker instance = new StandaloneBroker(); + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/model/MessageEntity.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/model/MessageEntity.java new file mode 100644 index 0000000000..0225874b7c --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/model/MessageEntity.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.broker.model; + +import java.io.Serializable; + +import io.cloudevents.CloudEvent; + +public class MessageEntity implements Serializable { + + private TopicMetadata topicMetadata; + + private CloudEvent message; + + private long offset; + + private long createTimeMills; + + public MessageEntity(TopicMetadata topicMetadata, CloudEvent message, long offset, long currentTimeMills) { + this.topicMetadata = topicMetadata; + this.message = message; + this.offset = offset; + this.createTimeMills = currentTimeMills; + } + + public TopicMetadata getTopicMetadata() { + return topicMetadata; + } + + public void setTopicMetadata(TopicMetadata topicMetadata) { + this.topicMetadata = topicMetadata; + } + + public CloudEvent getMessage() { + return message; + } + + public void setMessage(CloudEvent message) { + this.message = message; + } + + public long getOffset() { + return offset; + } + + public void setOffset(long offset) { + this.offset = offset; + } + + public long getCreateTimeMills() { + return createTimeMills; + } + + public void setCreateTimeMills(long createTimeMills) { + this.createTimeMills = createTimeMills; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/model/TopicMetadata.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/model/TopicMetadata.java new file mode 100644 index 0000000000..9b6c673e3a --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/model/TopicMetadata.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.broker.model; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Topic metadata, each topic has it's own metadata + */ +public class TopicMetadata implements Serializable { + + private String topicName; + + public TopicMetadata(String topicName) { + this.topicName = topicName; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TopicMetadata)) { + return false; + } + TopicMetadata that = (TopicMetadata) o; + return Objects.equals(topicName, that.topicName); + } + + @Override + public int hashCode() { + return Objects.hash(topicName); + } + + @Override + public String toString() { + return "TopicMetadata{" + + + "topic='" + topicName + '\'' + + + '}'; + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/task/HistoryMessageClearTask.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/task/HistoryMessageClearTask.java new file mode 100644 index 0000000000..5499f331f2 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/task/HistoryMessageClearTask.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.broker.task; + +import org.apache.eventmesh.connector.standalone.broker.MessageQueue; +import org.apache.eventmesh.connector.standalone.broker.model.MessageEntity; +import org.apache.eventmesh.connector.standalone.broker.model.TopicMetadata; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This task used to clear the history message, the element in message queue can only be cleaned by this task. + */ +public class HistoryMessageClearTask implements Runnable { + + + private final Logger logger = LoggerFactory.getLogger(HistoryMessageClearTask.class); + + private final ConcurrentHashMap messageContainer; + + /** + * If the currentTimeMills - messageCreateTimeMills >= MESSAGE_STORE_WINDOW, then the message will be clear + */ + private static final long MESSAGE_STORE_WINDOW = 60 * 60 * 1000; + + public HistoryMessageClearTask(ConcurrentHashMap messageContainer) { + this.messageContainer = messageContainer; + } + + @Override + public void run() { + while (true) { + messageContainer.forEach((topicMetadata, messageQueue) -> { + long currentTimeMillis = System.currentTimeMillis(); + MessageEntity oldestMessage = messageQueue.getHead(); + if (oldestMessage == null) { + return; + } + if (currentTimeMillis - oldestMessage.getCreateTimeMills() >= MESSAGE_STORE_WINDOW) { + messageQueue.removeHead(); + } + }); + try { + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + } catch (InterruptedException e) { + logger.error("Thread is interrupted, thread name: {}", Thread.currentThread().getName(), e); + Thread.currentThread().interrupt(); + } + } + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/task/SubScribeTask.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/task/SubScribeTask.java new file mode 100644 index 0000000000..81f1e2bfc7 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/broker/task/SubScribeTask.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.broker.task; + +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.EventMeshAction; +import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; +import org.apache.eventmesh.connector.standalone.broker.StandaloneBroker; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class SubScribeTask implements Runnable { + + private String topicName; + private StandaloneBroker standaloneBroker; + private EventListener listener; + private volatile boolean isRunning; + + private AtomicInteger offset; + + private final Logger logger = LoggerFactory.getLogger(SubScribeTask.class); + + public SubScribeTask(String topicName, + StandaloneBroker standaloneBroker, + EventListener listener) { + this.topicName = topicName; + this.standaloneBroker = standaloneBroker; + this.listener = listener; + this.isRunning = true; + } + + @Override + public void run() { + while (isRunning) { + try { + logger.debug("execute subscribe task, topic: {}, offset: {}", topicName, offset); + if (offset == null) { + CloudEvent message = standaloneBroker.getMessage(topicName); + if (message != null) { + if (message.getExtension("offset") != null) { + offset = new AtomicInteger((int) message.getExtension("offset")); + } else { + offset = new AtomicInteger(0); + } + + } + } + if (offset != null) { + CloudEvent message = standaloneBroker.getMessage(topicName, offset.get()); + if (message != null) { + EventMeshAsyncConsumeContext consumeContext = new EventMeshAsyncConsumeContext() { + @Override + public void commit(EventMeshAction action) { + switch (action) { + case CommitMessage: + // update offset + logger.info("message commit, topic: {}, current offset:{}", topicName, + offset.get()); + break; + case ReconsumeLater: + // don't update offset + break; + case ManualAck: + // update offset + offset.incrementAndGet(); + logger + .info("message ack, topic: {}, current offset:{}", topicName, offset.get()); + break; + default: + + } + } + }; + listener.consume(message, consumeContext); + } + } + + } catch (Exception ex) { + logger.error("consumer error, topic: {}, offset: {}", topicName, offset == null ? null : offset.get(), + ex); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + logger.error("Thread is interrupted, topic: {}, offset: {} thread name: {}", + topicName, offset == null ? null : offset.get(), Thread.currentThread().getName(), e); + Thread.currentThread().interrupt(); + } + } + } + + public void shutdown() { + isRunning = false; + } + +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/consumer/StandaloneConsumer.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/consumer/StandaloneConsumer.java new file mode 100644 index 0000000000..f56fc2b20d --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/consumer/StandaloneConsumer.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.consumer.Consumer; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.connector.standalone.broker.StandaloneBroker; +import org.apache.eventmesh.connector.standalone.broker.model.TopicMetadata; +import org.apache.eventmesh.connector.standalone.broker.task.SubScribeTask; + +import java.util.List; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; + +public class StandaloneConsumer implements Consumer { + + private StandaloneBroker standaloneBroker; + + private EventListener listener; + + private AtomicBoolean isStarted; + + private final ConcurrentHashMap subscribeTaskTable; + + private ExecutorService consumeExecutorService; + + public StandaloneConsumer(Properties properties) { + this.standaloneBroker = StandaloneBroker.getInstance(); + this.subscribeTaskTable = new ConcurrentHashMap<>(16); + this.isStarted = new AtomicBoolean(false); + this.consumeExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + Runtime.getRuntime().availableProcessors() * 2, + Runtime.getRuntime().availableProcessors() * 2, + "StandaloneConsumerThread" + ); + } + + @Override + public boolean isStarted() { + return isStarted.get(); + } + + @Override + public boolean isClosed() { + return !isStarted.get(); + } + + @Override + public void start() { + isStarted.compareAndSet(false, true); + } + + @Override + public void shutdown() { + isStarted.compareAndSet(true, false); + subscribeTaskTable.forEach(((topic, subScribeTask) -> subScribeTask.shutdown())); + subscribeTaskTable.clear(); + } + + @Override + public void init(Properties keyValue) throws Exception { + + } + + @Override + public void updateOffset(List cloudEvents, AbstractContext context) { + cloudEvents.forEach(cloudEvent -> standaloneBroker.updateOffset( + new TopicMetadata(cloudEvent.getSubject()), (Long) cloudEvent.getExtension("offset")) + ); + + } + + @Override + public void subscribe(String topic) throws Exception { + + if (subscribeTaskTable.containsKey(topic)) { + return; + } + synchronized (subscribeTaskTable) { + standaloneBroker.createTopicIfAbsent(topic); + SubScribeTask subScribeTask = new SubScribeTask(topic, standaloneBroker, listener); + subscribeTaskTable.put(topic, subScribeTask); + consumeExecutorService.execute(subScribeTask); + } + } + + @Override + public void unsubscribe(String topic) { + if (!subscribeTaskTable.containsKey(topic)) { + return; + } + synchronized (subscribeTaskTable) { + SubScribeTask subScribeTask = subscribeTaskTable.get(topic); + subScribeTask.shutdown(); + subscribeTaskTable.remove(topic); + } + } + + @Override + public void registerEventListener(EventListener listener) { + this.listener = listener; + } +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/consumer/StandaloneConsumerAdaptor.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/consumer/StandaloneConsumerAdaptor.java new file mode 100644 index 0000000000..79c5aadd5e --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/consumer/StandaloneConsumerAdaptor.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.consumer.Consumer; + +import java.util.List; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class StandaloneConsumerAdaptor implements Consumer { + + private StandaloneConsumer consumer; + + public StandaloneConsumerAdaptor() { + } + + @Override + public boolean isStarted() { + return consumer.isStarted(); + } + + @Override + public boolean isClosed() { + return consumer.isClosed(); + } + + @Override + public void start() { + consumer.start(); + } + + @Override + public void shutdown() { + consumer.shutdown(); + } + + @Override + public void init(Properties keyValue) throws Exception { + consumer = new StandaloneConsumer(keyValue); + } + + @Override + public void updateOffset(List cloudEvents, AbstractContext context) { + consumer.updateOffset(cloudEvents, context); + } + + @Override + public void subscribe(String topic) throws Exception { + consumer.subscribe(topic); + } + + @Override + public void unsubscribe(String topic) { + consumer.unsubscribe(topic); + } + + @Override + public void registerEventListener(EventListener listener) { + consumer.registerEventListener(listener); + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/producer/StandaloneProducer.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/producer/StandaloneProducer.java new file mode 100644 index 0000000000..c6aaf43a32 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/producer/StandaloneProducer.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.producer; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.ConnectorRuntimeException; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.connector.standalone.broker.StandaloneBroker; +import org.apache.eventmesh.connector.standalone.broker.model.MessageEntity; + +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +import com.google.common.base.Preconditions; + +public class StandaloneProducer { + + private Logger logger = LoggerFactory.getLogger(StandaloneProducer.class); + + private StandaloneBroker standaloneBroker; + + private AtomicBoolean isStarted; + + public StandaloneProducer(Properties properties) { + this.standaloneBroker = StandaloneBroker.getInstance(); + this.isStarted = new AtomicBoolean(false); + } + + public boolean isStarted() { + return isStarted.get(); + } + + public boolean isClosed() { + return !isStarted.get(); + } + + public void start() { + isStarted.compareAndSet(false, true); + } + + public void shutdown() { + isStarted.compareAndSet(true, false); + } + + public StandaloneProducer init(Properties properties) throws Exception { + return new StandaloneProducer(properties); + } + + public SendResult publish(CloudEvent cloudEvent) { + Preconditions.checkNotNull(cloudEvent); + try { + MessageEntity messageEntity = standaloneBroker.putMessage(cloudEvent.getSubject(), cloudEvent); + SendResult sendResult = new SendResult(); + sendResult.setTopic(cloudEvent.getSubject()); + sendResult.setMessageId(String.valueOf(messageEntity.getOffset())); + return sendResult; + } catch (Exception e) { + logger.error("send message error, topic: {}", cloudEvent.getSubject(), e); + throw new ConnectorRuntimeException( + String.format("Send message error, topic: %s", cloudEvent.getSubject())); + } + } + + public void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { + Preconditions.checkNotNull(cloudEvent); + Preconditions.checkNotNull(sendCallback); + + try { + SendResult sendResult = publish(cloudEvent); + sendCallback.onSuccess(sendResult); + } catch (Exception ex) { + OnExceptionContext onExceptionContext = OnExceptionContext.builder() + .messageId(cloudEvent.getId()) + .topic(cloudEvent.getSubject()) + .exception(new ConnectorRuntimeException(ex)) + .build(); + sendCallback.onException(onExceptionContext); + } + } + + public void sendOneway(CloudEvent cloudEvent) { + publish(cloudEvent); + } + + public void sendAsync(CloudEvent cloudEvent, SendCallback sendCallback) { + Preconditions.checkNotNull(cloudEvent, "CloudEvent cannot be null"); + Preconditions.checkNotNull(sendCallback, "Callback cannot be null"); + // todo: current is not async + try { + SendResult sendResult = publish(cloudEvent); + sendCallback.onSuccess(sendResult); + } catch (Exception ex) { + OnExceptionContext onExceptionContext = OnExceptionContext.builder() + .messageId(cloudEvent.getId()) + .topic(cloudEvent.getSubject()) + .exception(new ConnectorRuntimeException(ex)) + .build(); + sendCallback.onException(onExceptionContext); + } + } + + public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception { + throw new ConnectorRuntimeException("Request is not supported"); + } + + public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { + throw new ConnectorRuntimeException("Reply is not supported"); + } + + public void checkTopicExist(String topic) throws Exception { + boolean exist = standaloneBroker.checkTopicExist(topic); + if (!exist) { + throw new ConnectorRuntimeException(String.format("topic:%s is not exist", topic)); + } + } + + public void setExtFields() { + + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/producer/StandaloneProducerAdaptor.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/producer/StandaloneProducerAdaptor.java new file mode 100644 index 0000000000..d85161a54a --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/producer/StandaloneProducerAdaptor.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.producer; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.producer.Producer; + +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +public class StandaloneProducerAdaptor implements Producer { + + private StandaloneProducer standaloneProducer; + + public StandaloneProducerAdaptor() { + } + + @Override + public boolean isStarted() { + return standaloneProducer.isStarted(); + } + + @Override + public boolean isClosed() { + return standaloneProducer.isClosed(); + } + + @Override + public void start() { + standaloneProducer.start(); + } + + @Override + public void shutdown() { + standaloneProducer.shutdown(); + } + + @Override + public void init(Properties properties) throws Exception { + standaloneProducer = new StandaloneProducer(properties); + } + + @Override + public void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { + standaloneProducer.publish(cloudEvent, sendCallback); + } + + @Override + public void sendOneway(CloudEvent cloudEvent) { + standaloneProducer.sendOneway(cloudEvent); + } + + @Override + public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception { + standaloneProducer.request(cloudEvent, rrCallback, timeout); + } + + @Override + public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { + return standaloneProducer.reply(cloudEvent, sendCallback); + } + + @Override + public void checkTopicExist(String topic) throws Exception { + standaloneProducer.checkTopicExist(topic); + } + + @Override + public void setExtFields() { + standaloneProducer.setExtFields(); + } + +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/resource/StandaloneConnectorResourceService.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/resource/StandaloneConnectorResourceService.java new file mode 100644 index 0000000000..877d12f3ba --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/java/org/apache/eventmesh/connector/standalone/resource/StandaloneConnectorResourceService.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.standalone.resource; + +import org.apache.eventmesh.api.connector.ConnectorResourceService; + +public class StandaloneConnectorResourceService implements ConnectorResourceService { + + @Override + public void init() throws Exception { + + } + + @Override + public void release() throws Exception { + + } +} diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.connector.ConnectorResourceService b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.connector.ConnectorResourceService new file mode 100644 index 0000000000..7b8e948112 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.connector.ConnectorResourceService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +standalone=org.apache.eventmesh.connector.standalone.resource.StandaloneConnectorResourceService \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer new file mode 100644 index 0000000000..5ceb0eda96 --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +standalone=org.apache.eventmesh.connector.standalone.consumer.StandaloneConsumerAdaptor \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer new file mode 100644 index 0000000000..1b30d9837b --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +standalone=org.apache.eventmesh.connector.standalone.producer.StandaloneProducerAdaptor \ No newline at end of file diff --git a/eventmesh-connector-plugin/eventmesh-connector-standalone/src/test/java/org/apache/eventmesh/connector/standalone/broker/StandaloneBrokerTest.java b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/test/java/org/apache/eventmesh/connector/standalone/broker/StandaloneBrokerTest.java new file mode 100644 index 0000000000..1e66b0fffd --- /dev/null +++ b/eventmesh-connector-plugin/eventmesh-connector-standalone/src/test/java/org/apache/eventmesh/connector/standalone/broker/StandaloneBrokerTest.java @@ -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 org.apache.eventmesh.connector.standalone.broker; + +import org.apache.eventmesh.connector.standalone.broker.model.MessageEntity; + +import java.net.URI; + +import org.junit.Assert; +import org.junit.Test; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class StandaloneBrokerTest { + + @Test + public void getInstance() { + Assert.assertNotNull(StandaloneBroker.getInstance()); + } + + @Test + public void putMessage() throws InterruptedException { + StandaloneBroker instance = StandaloneBroker.getInstance(); + CloudEvent cloudEvent = CloudEventBuilder.v1() + .withId("test") + .withSource(URI.create("testsource")) + .withType("testType") + .build(); + MessageEntity messageEntity = instance.putMessage("test-topic", cloudEvent); + Assert.assertNotNull(messageEntity); + } + + @Test + public void takeMessage() throws InterruptedException { + StandaloneBroker instance = StandaloneBroker.getInstance(); + CloudEvent cloudEvent = CloudEventBuilder.v1() + .withId("test") + .withSource(URI.create("testsource")) + .withType("testType") + .build(); + instance.putMessage("test-topic", cloudEvent); + CloudEvent message = instance.takeMessage("test-topic"); + Assert.assertNotNull(message); + } + + @Test + public void getMessage() { + } + + @Test + public void testGetMessage() { + } + + @Test + public void checkTopicExist() { + } +} \ No newline at end of file diff --git a/eventmesh-connector-plugin/gradle.properties b/eventmesh-connector-plugin/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-connector-plugin/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-emesher/build.gradle b/eventmesh-emesher/build.gradle deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/eventmesh-examples/bin/http_pub_eventmeshmessage.sh b/eventmesh-examples/bin/http_pub_eventmeshmessage.sh new file mode 100644 index 0000000000..50683185c6 --- /dev/null +++ b/eventmesh-examples/bin/http_pub_eventmeshmessage.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#=========================================================================================== +# Java Environment Setting +#=========================================================================================== +set -e +# The configuration of different servers may be inconsistent, +# adding these configurations can avoid the problem of garbled characters +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +TMP_JAVA_HOME="/nemo/jdk1.8.0_152" + +#detect operating system. +OS=$(uname) + +function is_java8 { + local _java="$1" + [[ -x "$_java" ]] || return 1 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' ]] || return 2 + return 0 +} + + +function get_pid { + local ppid="" + if [ -f ${DEMO_HOME}/bin/pid_http_pub.file ]; then + ppid=$(cat ${DEMO_HOME}/bin/pid_http_pub.file) + else + if [[ $OS =~ Msys ]]; then + # There is a bug on Msys that may not be able to kill the recognized process + ppid=`jps -v | grep -i "org.apache.eventmesh.http.demo.AsyncPublishInstance" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known issue: grep "java" may not be able to accurately identify the java process + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.http.demo.AsyncPublishInstance" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on the Linux server + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $EVENTMESH_HOME | grep -i "org.apache.eventmesh.http.demo.AsyncPublishInstance" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "$ppid"; +} + + +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then + JAVA="$TMP_JAVA_HOME/bin/java" +elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA="$JAVA_HOME/bin/java" +elif is_java8 "/nemo/jdk8/bin/java"; then + JAVA="/nemo/jdk8/bin/java"; +elif is_java8 "/nemo/jdk1.8/bin/java"; then + JAVA="/nemo/jdk1.8/bin/java"; +elif is_java8 "/nemo/jdk/bin/java"; then + JAVA="/nemo/jdk/bin/java"; +elif is_java8 "$(which java)"; then + JAVA="$(which java)" +else + echo -e "ERROR\t java(1.8) not found, operation abort." + exit 9; +fi + +echo "http_pub_demo use java location= "$JAVA + +DEMO_HOME=`cd "./.." && pwd` + +export DEMO_HOME + +export DEMO_LOG_HOME=${DEMO_HOME}/logs + +echo "DEMO_HOME : ${DEMO_HOME}, DEMO_LOG_HOME : ${DEMO_LOG_HOME}" + +function make_logs_dir { + if [ ! -e "${DEMO_LOG_HOME}" ]; then mkdir -p "${DEMO_LOG_HOME}"; fi +} + +error_exit () +{ + echo "ERROR: $1 !!" + exit 1 +} + +export JAVA_HOME + +JAVA_OPT=`cat ${DEMO_HOME}/conf/server.env | grep APP_START_JVM_OPTION::: | awk -F ':::' {'print $2'}` +JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" +JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${DEMO_HOME}/logs/demo_http_pub_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DEMO_HOME}/logs -XX:ErrorFile=${EVENTMESH_HOME}/logs/hs_err_%p.log" +JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" +JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" +JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" +JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" +JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" +JAVA_OPT="${JAVA_OPT} -Dio.netty.leakDetectionLevel=advanced" +JAVA_OPT="${JAVA_OPT} -Dio.netty.allocator.type=pooled" +JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" +JAVA_OPT="${JAVA_OPT} -Dlog4j.configurationFile=${DEMO_HOME}/conf/log4j2.xml" +#JAVA_OPT="${JAVA_OPT} -Deventmesh.log.home=${DEMO_LOG_HOME}" +JAVA_OPT="${JAVA_OPT} -DconfPath=${DEMO_HOME}/conf" +JAVA_OPT="${JAVA_OPT} -Dlog4j2.AsyncQueueFullPolicy=Discard" +JAVA_OPT="${JAVA_OPT} -Drocketmq.client.logUseSlf4j=true" + +pid=$(get_pid) +if [ -n "$pid" ];then + echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." + exit 9; +fi + +make_logs_dir + +echo "using jdk[$JAVA]" >> ${DEMO_LOG_HOME}/demo_http_pub.out + + +DEMO_MAIN=org.apache.eventmesh.http.demo.pub.eventmeshmessage.AsyncPublishInstance +if [ $DOCKER ] +then + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_http_pub.out +else + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_http_pub.out 2>&1 & +echo $!>pid_http_pub.file +fi +exit 0 diff --git a/eventmesh-examples/bin/http_sub.sh b/eventmesh-examples/bin/http_sub.sh new file mode 100644 index 0000000000..eff1a575f7 --- /dev/null +++ b/eventmesh-examples/bin/http_sub.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#=========================================================================================== +# Java Environment Setting +#=========================================================================================== +set -e +# The configuration of different servers may be inconsistent, +# adding these configurations can avoid the problem of garbled characters +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +TMP_JAVA_HOME="/nemo/jdk1.8.0_152" + +#detect operating system. +OS=$(uname) + +function is_java8 { + local _java="$1" + [[ -x "$_java" ]] || return 1 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' ]] || return 2 + return 0 +} + + +function get_pid { + local ppid="" + if [ -f ${DEMO_HOME}/bin/pid_http_sub.file ]; then + ppid=$(cat ${DEMO_HOME}/bin/pid_http_sub.file) + else + if [[ $OS =~ Msys ]]; then + # There is a bug on Msys that may not be able to kill the recognized process + ppid=`jps -v | grep -i "org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known issue: grep "java" may not be able to accurately identify the java process + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on the Linux server + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $EVENTMESH_HOME | grep -i "org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "$ppid"; +} + + +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then + JAVA="$TMP_JAVA_HOME/bin/java" +elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA="$JAVA_HOME/bin/java" +elif is_java8 "/nemo/jdk8/bin/java"; then + JAVA="/nemo/jdk8/bin/java"; +elif is_java8 "/nemo/jdk1.8/bin/java"; then + JAVA="/nemo/jdk1.8/bin/java"; +elif is_java8 "/nemo/jdk/bin/java"; then + JAVA="/nemo/jdk/bin/java"; +elif is_java8 "$(which java)"; then + JAVA="$(which java)" +else + echo -e "ERROR\t java(1.8) not found, operation abort." + exit 9; +fi + +echo "http_sub_demo use java location= "$JAVA + +DEMO_HOME=`cd "./.." && pwd` + +export DEMO_HOME + +export DEMO_LOG_HOME=${DEMO_HOME}/logs + +echo "DEMO_HOME : ${DEMO_HOME}, DEMO_LOG_HOME : ${DEMO_LOG_HOME}" + +function make_logs_dir { + if [ ! -e "${DEMO_LOG_HOME}" ]; then mkdir -p "${DEMO_LOG_HOME}"; fi +} + +error_exit () +{ + echo "ERROR: $1 !!" + exit 1 +} + +export JAVA_HOME + +JAVA_OPT=`cat ${DEMO_HOME}/conf/server.env | grep APP_START_JVM_OPTION::: | awk -F ':::' {'print $2'}` +JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" +JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${DEMO_HOME}/logs/demo_http_sub_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DEMO_HOME}/logs -XX:ErrorFile=${EVENTMESH_HOME}/logs/hs_err_%p.log" +JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" +JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" +JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" +JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" +JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" +JAVA_OPT="${JAVA_OPT} -Dio.netty.leakDetectionLevel=advanced" +JAVA_OPT="${JAVA_OPT} -Dio.netty.allocator.type=pooled" +JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" +JAVA_OPT="${JAVA_OPT} -Dlog4j.configurationFile=${DEMO_HOME}/conf/log4j2.xml" +#JAVA_OPT="${JAVA_OPT} -Deventmesh.log.home=${DEMO_LOG_HOME}" +JAVA_OPT="${JAVA_OPT} -DconfPath=${DEMO_HOME}/conf" +JAVA_OPT="${JAVA_OPT} -Dlog4j2.AsyncQueueFullPolicy=Discard" +JAVA_OPT="${JAVA_OPT} -Drocketmq.client.logUseSlf4j=true" + +pid=$(get_pid) +if [ -n "$pid" ];then + echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." + exit 9; +fi + +make_logs_dir + +echo "using jdk[$JAVA]" >> ${DEMO_LOG_HOME}/demo_http_sub.out + + +DEMO_MAIN=org.apache.eventmesh.http.demo.sub.SpringBootDemoApplication +if [ $DOCKER ] +then + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_http_sub.out +else + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_http_sub.out 2>&1 & +echo $!>pid_http_sub.file +fi +exit 0 diff --git a/eventmesh-examples/bin/tcp_eventmeshmessage_sub.sh b/eventmesh-examples/bin/tcp_eventmeshmessage_sub.sh new file mode 100644 index 0000000000..5a45145932 --- /dev/null +++ b/eventmesh-examples/bin/tcp_eventmeshmessage_sub.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#=========================================================================================== +# Java Environment Setting +#=========================================================================================== +set -e +# The configuration of different servers may be inconsistent, +# adding these configurations can avoid the problem of garbled characters +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +TMP_JAVA_HOME="/nemo/jdk1.8.0_152" + +#detect operating system. +OS=$(uname) + +function is_java8 { + local _java="$1" + [[ -x "$_java" ]] || return 1 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' ]] || return 2 + return 0 +} + + +function get_pid { + local ppid="" + if [ -f ${DEMO_HOME}/bin/pid_tcp_sub.file ]; then + ppid=$(cat ${DEMO_HOME}/bin/pid_tcp_sub.file) + else + if [[ $OS =~ Msys ]]; then + # There is a bug on Msys that may not be able to kill the recognized process + ppid=`jps -v | grep -i "org.apache.eventmesh.tcp.demo.AsyncSubscribe" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known issue: grep "java" may not be able to accurately identify the java process + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.tcp.demo.AsyncSubscribe" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on the Linux server + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $DEMO_HOME | grep -i "org.apache.eventmesh.tcp.demo.AsyncSubscribe" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "$ppid"; +} + + +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then + JAVA="$TMP_JAVA_HOME/bin/java" +elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA="$JAVA_HOME/bin/java" +elif is_java8 "/nemo/jdk8/bin/java"; then + JAVA="/nemo/jdk8/bin/java"; +elif is_java8 "/nemo/jdk1.8/bin/java"; then + JAVA="/nemo/jdk1.8/bin/java"; +elif is_java8 "/nemo/jdk/bin/java"; then + JAVA="/nemo/jdk/bin/java"; +elif is_java8 "$(which java)"; then + JAVA="$(which java)" +else + echo -e "ERROR\t java(1.8) not found, operation abort." + exit 9; +fi + +echo "tcp_sub_demo use java location= "$JAVA + +DEMO_HOME=`cd "./.." && pwd` + +export DEMO_HOME + +export DEMO_LOG_HOME=${DEMO_HOME}/logs + +echo "DEMO_HOME : ${DEMO_HOME}, DEMO_LOG_HOME : ${DEMO_LOG_HOME}" + +function make_logs_dir { + if [ ! -e "${DEMO_LOG_HOME}" ]; then mkdir -p "${DEMO_LOG_HOME}"; fi +} + +error_exit () +{ + echo "ERROR: $1 !!" + exit 1 +} + +export JAVA_HOME + +JAVA_OPT=`cat ${DEMO_HOME}/conf/server.env | grep APP_START_JVM_OPTION::: | awk -F ':::' {'print $2'}` +JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" +JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${DEMO_HOME}/logs/demo_tcp_sub_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DEMO_HOME}/logs -XX:ErrorFile=${DEMO_HOME}/logs/hs_err_%p.log" +JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" +JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" +JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" +JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" +JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" +JAVA_OPT="${JAVA_OPT} -Dio.netty.leakDetectionLevel=advanced" +JAVA_OPT="${JAVA_OPT} -Dio.netty.allocator.type=pooled" +JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" +JAVA_OPT="${JAVA_OPT} -Dlog4j.configurationFile=${DEMO_HOME}/conf/log4j2.xml" +#JAVA_OPT="${JAVA_OPT} -Deventmesh.log.home=${DEMO_LOG_HOME}" +JAVA_OPT="${JAVA_OPT} -DconfPath=${DEMO_HOME}/conf" +JAVA_OPT="${JAVA_OPT} -Dlog4j2.AsyncQueueFullPolicy=Discard" +JAVA_OPT="${JAVA_OPT} -Drocketmq.client.logUseSlf4j=true" + +pid=$(get_pid) +if [ -n "$pid" ];then + echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." + exit 9; +fi + +make_logs_dir + +echo "using jdk[$JAVA]" >> ${DEMO_LOG_HOME}/demo_tcp_sub.out + + +DEMO_MAIN=org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribe +if [ $DOCKER ] +then + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_sub.out +else + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_sub.out 2>&1 & +echo $!>pid_tcp_sub.file +fi +exit 0 diff --git a/eventmesh-examples/bin/tcp_pub_eventmeshmessage.sh b/eventmesh-examples/bin/tcp_pub_eventmeshmessage.sh new file mode 100644 index 0000000000..c5bfc97a6f --- /dev/null +++ b/eventmesh-examples/bin/tcp_pub_eventmeshmessage.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#=========================================================================================== +# Java Environment Setting +#=========================================================================================== +set -e +# The configuration of different servers may be inconsistent, +# adding these configurations can avoid the problem of garbled characters +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +TMP_JAVA_HOME="/nemo/jdk1.8.0_152" + +#detect operating system. +OS=$(uname) + +function is_java8 { + local _java="$1" + [[ -x "$_java" ]] || return 1 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' ]] || return 2 + return 0 +} + + +function get_pid { + local ppid="" + if [ -f ${DEMO_HOME}/bin/pid_tcp_pub.file ]; then + ppid=$(cat ${DEMO_HOME}/bin/pid_tcp_pub.file) + else + if [[ $OS =~ Msys ]]; then + # There is a bug on Msys that may not be able to kill the recognized process + ppid=`jps -v | grep -i "org.apache.eventmesh.tcp.demo.AsyncPublish" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known issue: grep "java" may not be able to accurately identify the java process + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.tcp.demo.AsyncPublish" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on the Linux server + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $EVENTMESH_HOME | grep -i "org.apache.eventmesh.tcp.demo.AsyncPublish" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "ppid"; +} + + +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then + JAVA="$TMP_JAVA_HOME/bin/java" +elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA="$JAVA_HOME/bin/java" +elif is_java8 "/nemo/jdk8/bin/java"; then + JAVA="/nemo/jdk8/bin/java"; +elif is_java8 "/nemo/jdk1.8/bin/java"; then + JAVA="/nemo/jdk1.8/bin/java"; +elif is_java8 "/nemo/jdk/bin/java"; then + JAVA="/nemo/jdk/bin/java"; +elif is_java8 "$(which java)"; then + JAVA="$(which java)" +else + echo -e "ERROR\t java(1.8) not found, operation abort." + exit 9; +fi + +echo "tcp_pub_demo use java location= "$JAVA + +DEMO_HOME=`cd "./.." && pwd` + +export DEMO_HOME + +export DEMO_LOG_HOME=${DEMO_HOME}/logs + +echo "DEMO_HOME : ${DEMO_HOME}, DEMO_LOG_HOME : ${DEMO_LOG_HOME}" + +function make_logs_dir { + if [ ! -e "${DEMO_LOG_HOME}" ]; then mkdir -p "${DEMO_LOG_HOME}"; fi +} + +error_exit () +{ + echo "ERROR: $1 !!" + exit 1 +} + +export JAVA_HOME + +JAVA_OPT=`cat ${DEMO_HOME}/conf/server.env | grep APP_START_JVM_OPTION::: | awk -F ':::' {'print $2'}` +JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" +JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${DEMO_HOME}/logs/demo_tcp_pub_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DEMO_HOME}/logs -XX:ErrorFile=${EVENTMESH_HOME}/logs/hs_err_%p.log" +JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" +JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" +JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" +JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" +JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" +JAVA_OPT="${JAVA_OPT} -Dio.netty.leakDetectionLevel=advanced" +JAVA_OPT="${JAVA_OPT} -Dio.netty.allocator.type=pooled" +JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" +JAVA_OPT="${JAVA_OPT} -Dlog4j.configurationFile=${DEMO_HOME}/conf/log4j2.xml" +#JAVA_OPT="${JAVA_OPT} -Deventmesh.log.home=${DEMO_LOG_HOME}" +JAVA_OPT="${JAVA_OPT} -DconfPath=${DEMO_HOME}/conf" +JAVA_OPT="${JAVA_OPT} -Dlog4j2.AsyncQueueFullPolicy=Discard" +JAVA_OPT="${JAVA_OPT} -Drocketmq.client.logUseSlf4j=true" + +pid=$(get_pid) +if [ -n "$pid" ];then + echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." + exit 9; +fi + +make_logs_dir + +echo "using jdk[$JAVA]" >> ${DEMO_LOG_HOME}/demo_tcp_pub.out + + +DEMO_MAIN=org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublish +if [ $DOCKER ] +then + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_pub.out +else + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_pub.out 2>&1 & +echo $!>pid_tcp_pub.file +fi +exit 0 diff --git a/eventmesh-examples/bin/tcp_pub_eventmeshmessage_broadcast.sh b/eventmesh-examples/bin/tcp_pub_eventmeshmessage_broadcast.sh new file mode 100644 index 0000000000..b7a139564d --- /dev/null +++ b/eventmesh-examples/bin/tcp_pub_eventmeshmessage_broadcast.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#=========================================================================================== +# Java Environment Setting +#=========================================================================================== +set -e +# The configuration of different servers may be inconsistent, +# adding these configurations can avoid the problem of garbled characters +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +TMP_JAVA_HOME="/nemo/jdk1.8.0_152" + +#detect operating system. +OS=$(uname) + +function is_java8 { + local _java="$1" + [[ -x "$_java" ]] || return 1 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' ]] || return 2 + return 0 +} + + +function get_pid { + local ppid="" + if [ -f ${DEMO_HOME}/bin/pid_tcp_pub_broadcast.file ]; then + ppid=$(cat ${DEMO_HOME}/bin/pid_tcp_pub_broadcast.file) + else + if [[ $OS =~ Msys ]]; then + # There is a bug on Msys that may not be able to kill the recognized process + ppid=`jps -v | grep -i "org.apache.eventmesh.tcp.demo.AsyncPublishBroadcast" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known issue: grep "java" may not be able to accurately identify the java process + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.tcp.demo.AsyncPublishBroadcast" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on the Linux server + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $DEMO_HOME | grep -i "org.apache.eventmesh.tcp.demo.AsyncPublishBroadcast" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "$ppid"; +} + + +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then + JAVA="$TMP_JAVA_HOME/bin/java" +elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA="$JAVA_HOME/bin/java" +elif is_java8 "/nemo/jdk8/bin/java"; then + JAVA="/nemo/jdk8/bin/java"; +elif is_java8 "/nemo/jdk1.8/bin/java"; then + JAVA="/nemo/jdk1.8/bin/java"; +elif is_java8 "/nemo/jdk/bin/java"; then + JAVA="/nemo/jdk/bin/java"; +elif is_java8 "$(which java)"; then + JAVA="$(which java)" +else + echo -e "ERROR\t java(1.8) not found, operation abort." + exit 9; +fi + +echo "tcp_pub_demo use java location= "$JAVA + +DEMO_HOME=`cd "./.." && pwd` + +export DEMO_HOME + +export DEMO_LOG_HOME=${DEMO_HOME}/logs + +echo "DEMO_HOME : ${DEMO_HOME}, DEMO_LOG_HOME : ${DEMO_LOG_HOME}" + +function make_logs_dir { + if [ ! -e "${DEMO_LOG_HOME}" ]; then mkdir -p "${DEMO_LOG_HOME}"; fi +} + +error_exit () +{ + echo "ERROR: $1 !!" + exit 1 +} + +export JAVA_HOME + +JAVA_OPT=`cat ${DEMO_HOME}/conf/server.env | grep APP_START_JVM_OPTION::: | awk -F ':::' {'print $2'}` +JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" +JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${DEMO_HOME}/logs/demo_tcp_pub_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DEMO_HOME}/logs -XX:ErrorFile=${DEMO_HOME}/logs/hs_err_%p.log" +JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" +JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" +JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" +JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" +JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" +JAVA_OPT="${JAVA_OPT} -Dio.netty.leakDetectionLevel=advanced" +JAVA_OPT="${JAVA_OPT} -Dio.netty.allocator.type=pooled" +JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" +JAVA_OPT="${JAVA_OPT} -Dlog4j.configurationFile=${DEMO_HOME}/conf/log4j2.xml" +#JAVA_OPT="${JAVA_OPT} -Deventmesh.log.home=${DEMO_LOG_HOME}" +JAVA_OPT="${JAVA_OPT} -DconfPath=${DEMO_HOME}/conf" +JAVA_OPT="${JAVA_OPT} -Dlog4j2.AsyncQueueFullPolicy=Discard" +JAVA_OPT="${JAVA_OPT} -Drocketmq.client.logUseSlf4j=true" + +pid=$(get_pid) +if [ -n "$pid" ];then + echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." + exit 9; +fi + +make_logs_dir + +echo "using jdk[$JAVA]" >> ${DEMO_LOG_HOME}/demo_tcp_pub_broadcast.out + + +DEMO_MAIN=org.apache.eventmesh.tcp.demo.pub.eventmeshmessage.AsyncPublishBroadcast +if [ $DOCKER ] +then + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_pub_broadcast.out +else + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_pub_broadcast.out 2>&1 & +echo $!>pid_tcp_pub_broadcast.file +fi +exit 0 diff --git a/eventmesh-examples/bin/tcp_sub_eventmeshmessage_broadcast.sh b/eventmesh-examples/bin/tcp_sub_eventmeshmessage_broadcast.sh new file mode 100644 index 0000000000..aaa5a34e3a --- /dev/null +++ b/eventmesh-examples/bin/tcp_sub_eventmeshmessage_broadcast.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#=========================================================================================== +# Java Environment Setting +#=========================================================================================== +set -e +# The configuration of different servers may be inconsistent, +# adding these configurations can avoid the problem of garbled characters +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +TMP_JAVA_HOME="/nemo/jdk1.8.0_152" + +#detect operating system. +OS=$(uname) + +function is_java8 { + local _java="$1" + [[ -x "$_java" ]] || return 1 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' ]] || return 2 + return 0 +} + + +function get_pid { + local ppid="" + if [ -f ${EVENTMESH_HOME}/bin/pid_tcp_sub_broadcast.file ]; then + ppid=$(cat ${EVENTMESH_HOME}/bin/pid_tcp_sub_broadcast.file) + else + if [[ $OS =~ Msys ]]; then + # There is a bug on Msys that may not be able to kill the recognized process + ppid=`jps -v | grep -i "org.apache.eventmesh.tcp.demo.AsyncSubscribeBroadcast" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known issue: grep "java" may not be able to accurately identify the java process + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.tcp.demo.AsyncSubscribeBroadcast" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on the Linux server + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $EVENTMESH_HOME | grep -i "org.apache.eventmesh.tcp.demo.AsyncSubscribeBroadcast" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "$ppid"; +} + + +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then + JAVA="$TMP_JAVA_HOME/bin/java" +elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA="$JAVA_HOME/bin/java" +elif is_java8 "/nemo/jdk8/bin/java"; then + JAVA="/nemo/jdk8/bin/java"; +elif is_java8 "/nemo/jdk1.8/bin/java"; then + JAVA="/nemo/jdk1.8/bin/java"; +elif is_java8 "/nemo/jdk/bin/java"; then + JAVA="/nemo/jdk/bin/java"; +elif is_java8 "$(which java)"; then + JAVA="$(which java)" +else + echo -e "ERROR\t java(1.8) not found, operation abort." + exit 9; +fi + +echo "tcp_sub_demo use java location= "$JAVA + +DEMO_HOME=`cd "./.." && pwd` + +export DEMO_HOME + +export DEMO_LOG_HOME=${DEMO_HOME}/logs + +echo "DEMO_HOME : ${DEMO_HOME}, DEMO_LOG_HOME : ${DEMO_LOG_HOME}" + +function make_logs_dir { + if [ ! -e "${DEMO_LOG_HOME}" ]; then mkdir -p "${DEMO_LOG_HOME}"; fi +} + +error_exit () +{ + echo "ERROR: $1 !!" + exit 1 +} + +export JAVA_HOME + +JAVA_OPT=`cat ${DEMO_HOME}/conf/server.env | grep APP_START_JVM_OPTION::: | awk -F ':::' {'print $2'}` +JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" +JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${DEMO_HOME}/logs/demo_tcp_sub_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DEMO_HOME}/logs -XX:ErrorFile=${DEMO_HOME}/logs/hs_err_%p.log" +JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" +JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" +JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" +JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" +JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" +JAVA_OPT="${JAVA_OPT} -Dio.netty.leakDetectionLevel=advanced" +JAVA_OPT="${JAVA_OPT} -Dio.netty.allocator.type=pooled" +JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" +JAVA_OPT="${JAVA_OPT} -Dlog4j.configurationFile=${DEMO_HOME}/conf/log4j2.xml" +#JAVA_OPT="${JAVA_OPT} -Deventmesh.log.home=${DEMO_LOG_HOME}" +JAVA_OPT="${JAVA_OPT} -DconfPath=${DEMO_HOME}/conf" +JAVA_OPT="${JAVA_OPT} -Dlog4j2.AsyncQueueFullPolicy=Discard" +JAVA_OPT="${JAVA_OPT} -Drocketmq.client.logUseSlf4j=true" + +pid=$(get_pid) +if [ -n "$pid" ];then + echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." + exit 9; +fi + +make_logs_dir + +echo "using jdk[$JAVA]" >> ${DEMO_LOG_HOME}/demo_tcp_sub_broadcast.out + + +DEMO_MAIN=org.apache.eventmesh.tcp.demo.sub.eventmeshmessage.AsyncSubscribeBroadcast +if [ $DOCKER ] +then + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_sub_broadcast.out +else + $JAVA $JAVA_OPT -classpath ${DEMO_HOME}/conf:${DEMO_HOME}/apps/*:${DEMO_HOME}/lib/* $DEMO_MAIN >> ${DEMO_LOG_HOME}/demo_tcp_sub_broadcast.out 2>&1 & +echo $!>pid_tcp_sub_broadcast.file +fi +exit 0 diff --git a/eventmesh-examples/build.gradle b/eventmesh-examples/build.gradle new file mode 100644 index 0000000000..ed3d38f02b --- /dev/null +++ b/eventmesh-examples/build.gradle @@ -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. + */ + +def grpcVersion = '1.17.1' + +configurations { + implementation.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' +} + +dependencies { + implementation project(":eventmesh-sdk-java") + implementation project(":eventmesh-common") + implementation project(":eventmesh-connector-plugin:eventmesh-connector-api") + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'io.netty:netty-all' + implementation "io.cloudevents:cloudevents-core" + implementation "io.cloudevents:cloudevents-json-jackson" + implementation "io.openmessaging:openmessaging-api" + + implementation "io.grpc:grpc-protobuf:${grpcVersion}" + implementation "io.grpc:grpc-stub:${grpcVersion}" + implementation "io.grpc:grpc-netty:${grpcVersion}" + implementation "io.grpc:grpc-netty-shaded:${grpcVersion}" + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' +} \ No newline at end of file diff --git a/eventmesh-examples/gradle.properties b/eventmesh-examples/gradle.properties new file mode 100644 index 0000000000..b1312a0905 --- /dev/null +++ b/eventmesh-examples/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/common/ExampleConstants.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/common/ExampleConstants.java new file mode 100644 index 0000000000..2befeebc5d --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/common/ExampleConstants.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common; + +public class ExampleConstants { + + public static final String CONFIG_FILE_NAME = "application.properties"; + public static final String CLOUDEVENT_CONTENT_TYPE = "application/cloudevents+json"; + + public static final String EVENTMESH_IP = "eventmesh.ip"; + public static final String EVENTMESH_HTTP_PORT = "eventmesh.http.port"; + public static final String EVENTMESH_TCP_PORT = "eventmesh.tcp.port"; + public static final String EVENTMESH_GRPC_PORT = "eventmesh.grpc.port"; + + public static final String DEFAULT_EVENTMESH_IP = "127.0.0.1"; + public static final String DEFAULT_EVENTMESH_IP_PORT = "127.0.0.1:10105"; + + public static final String EVENTMESH_GRPC_ASYNC_TEST_TOPIC = "TEST-TOPIC-GRPC-ASYNC"; + public static final String EVENTMESH_GRPC_RR_TEST_TOPIC = "TEST-TOPIC-GRPC-RR"; + public static final String EVENTMESH_GRPC_BROADCAT_TEST_TOPIC = "TEST-TOPIC-GRPC-BROADCAST"; + public static final String EVENTMESH_HTTP_ASYNC_TEST_TOPIC = "TEST-TOPIC-HTTP-ASYNC"; + public static final String EVENTMESH_HTTP_SYNC_TEST_TOPIC = "TEST-TOPIC-HTTP-SYNC"; + public static final String EVENTMESH_TCP_ASYNC_TEST_TOPIC = "TEST-TOPIC-TCP-ASYNC"; + public static final String EVENTMESH_TCP_SYNC_TEST_TOPIC = "TEST-TOPIC-TCP-SYNC"; + public static final String EVENTMESH_TCP_BROADCAST_TEST_TOPIC = "TEST-TOPIC-TCP-BROADCAST"; + + public static final String DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP = "EventMeshTest-producerGroup"; + public static final String DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP = "EventMeshTest-consumerGroup"; + +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsBatchPublishInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsBatchPublishInstance.java new file mode 100644 index 0000000000..54b63f9f8f --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsBatchPublishInstance.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.pub.cloudevents; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.producer.EventMeshGrpcProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.util.Utils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CloudEventsBatchPublishInstance { + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); + + eventMeshGrpcProducer.init(); + + Map content = new HashMap<>(); + content.put("content", "testRequestReplyMessage"); + + List cloudEventList = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + + cloudEventList.add(event); + } + + eventMeshGrpcProducer.publish(cloudEventList); + Thread.sleep(10000); + try (EventMeshGrpcProducer ignore = eventMeshGrpcProducer) { + // ignore + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsPublishInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsPublishInstance.java new file mode 100644 index 0000000000..b026bea7c9 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsPublishInstance.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.pub.cloudevents; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.producer.EventMeshGrpcProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.util.Utils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CloudEventsPublishInstance { + + // This messageSize is also used in SubService.java (Subscriber) + public static final int messageSize = 5; + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); + + eventMeshGrpcProducer.init(); + + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + for (int i = 0; i < messageSize; i++) { + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + eventMeshGrpcProducer.publish(event); + Thread.sleep(1000); + } + Thread.sleep(30000); + try (EventMeshGrpcProducer ignore = eventMeshGrpcProducer) { + // ignore + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsRequestInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsRequestInstance.java new file mode 100644 index 0000000000..961e0a8b70 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/cloudevents/CloudEventsRequestInstance.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.pub.cloudevents; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.producer.EventMeshGrpcProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.util.Utils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CloudEventsRequestInstance { + + // This messageSize is also used in SubService.java (Subscriber) + public static final int messageSize = 5; + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); + + eventMeshGrpcProducer.init(); + + Map content = new HashMap<>(); + content.put("content", "testRequestReplyMessage"); + + for (int i = 0; i < messageSize; i++) { + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_GRPC_RR_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + + eventMeshGrpcProducer.requestReply(event, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + Thread.sleep(1000); + } + Thread.sleep(30000); + try (EventMeshGrpcProducer ignore = eventMeshGrpcProducer) { + // ignore + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/AsyncPublishBroadcast.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/AsyncPublishBroadcast.java new file mode 100644 index 0000000000..685600024d --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/AsyncPublishBroadcast.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.pub.eventmeshmessage; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.producer.EventMeshGrpcProducer; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncPublishBroadcast { + + // This messageSize is also used in SubService.java (Subscriber) + public static final int messageSize = 5; + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); + + eventMeshGrpcProducer.init(); + + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + for (int i = 0; i < messageSize; i++) { + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .content(JsonUtils.serialize(content)) + .topic(ExampleConstants.EVENTMESH_GRPC_BROADCAT_TEST_TOPIC) + .uniqueId(RandomStringUtils.generateNum(30)) + .bizSeqNo(RandomStringUtils.generateNum(30)) + .build() + .addProp(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)); + eventMeshGrpcProducer.publish(eventMeshMessage); + Thread.sleep(1000); + } + Thread.sleep(30000); + try (EventMeshGrpcProducer ignore = eventMeshGrpcProducer) { + // ignore + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/AsyncPublishInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/AsyncPublishInstance.java new file mode 100644 index 0000000000..924c64eefd --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/AsyncPublishInstance.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.pub.eventmeshmessage; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.producer.EventMeshGrpcProducer; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncPublishInstance { + + // This messageSize is also used in SubService.java (Subscriber) + public static final int messageSize = 5; + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); + + eventMeshGrpcProducer.init(); + + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + for (int i = 0; i < messageSize; i++) { + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .content(JsonUtils.serialize(content)) + .topic(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .uniqueId(RandomStringUtils.generateNum(30)) + .bizSeqNo(RandomStringUtils.generateNum(30)) + .build() + .addProp(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)); + eventMeshGrpcProducer.publish(eventMeshMessage); + Thread.sleep(1000); + } + Thread.sleep(30000); + try (EventMeshGrpcProducer ignore = eventMeshGrpcProducer) { + // ignore + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/BatchPublishInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/BatchPublishInstance.java new file mode 100644 index 0000000000..e7e7a17548 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/BatchPublishInstance.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.pub.eventmeshmessage; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.producer.EventMeshGrpcProducer; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class BatchPublishInstance { + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); + + eventMeshGrpcProducer.init(); + + Map content = new HashMap<>(); + content.put("content", "testRequestReplyMessage"); + + List messageList = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + EventMeshMessage message = EventMeshMessage.builder() + .topic(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .content((JsonUtils.serialize(content))) + .uniqueId(RandomStringUtils.generateNum(30)) + .bizSeqNo(RandomStringUtils.generateNum(30)) + .build() + .addProp(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)); + messageList.add(message); + } + + eventMeshGrpcProducer.publish(messageList); + Thread.sleep(10000); + try (EventMeshGrpcProducer ignore = eventMeshGrpcProducer) { + // ignore + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/RequestReplyInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/RequestReplyInstance.java new file mode 100644 index 0000000000..6b56fc7969 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/RequestReplyInstance.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.pub.eventmeshmessage; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.producer.EventMeshGrpcProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RequestReplyInstance { + + // This messageSize is also used in SubService.java (Subscriber) + public static final int messageSize = 5; + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer(eventMeshClientConfig); + + eventMeshGrpcProducer.init(); + + Map content = new HashMap<>(); + content.put("content", "testRequestReplyMessage"); + + for (int i = 0; i < messageSize; i++) { + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .content(JsonUtils.serialize(content)) + .topic(ExampleConstants.EVENTMESH_GRPC_RR_TEST_TOPIC) + .uniqueId(RandomStringUtils.generateNum(30)) + .bizSeqNo(RandomStringUtils.generateNum(30)) + .build() + .addProp(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)); + + eventMeshGrpcProducer.requestReply(eventMeshMessage, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + Thread.sleep(1000); + } + Thread.sleep(30000); + try (EventMeshGrpcProducer ignore = eventMeshGrpcProducer) { + // ignore + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/CloudEventsAsyncSubscribe.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/CloudEventsAsyncSubscribe.java new file mode 100644 index 0000000000..a409389c82 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/CloudEventsAsyncSubscribe.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.sub; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.util.Utils; + +import java.util.Collections; +import java.util.Optional; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CloudEventsAsyncSubscribe implements ReceiveMsgHook { + + public static CloudEventsAsyncSubscribe handler = new CloudEventsAsyncSubscribe(); + + public static void main(String[] args) throws InterruptedException { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + org.apache.eventmesh.common.protocol.SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setTopic(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC); + subscriptionItem.setMode(SubscriptionMode.CLUSTERING); + subscriptionItem.setType(SubscriptionType.ASYNC); + + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + + eventMeshGrpcConsumer.registerListener(handler); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + + Thread.sleep(60000); + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(CloudEvent msg) { + log.info("receive async msg: {}", msg); + return Optional.empty(); + } + + @Override + public String getProtocolType() { + return EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME; + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/CloudEventsSubscribeReply.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/CloudEventsSubscribeReply.java new file mode 100644 index 0000000000..4a9b2aa981 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/CloudEventsSubscribeReply.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.sub; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.util.Utils; + +import java.util.Collections; +import java.util.Optional; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CloudEventsSubscribeReply implements ReceiveMsgHook { + + public static CloudEventsSubscribeReply handler = new CloudEventsSubscribeReply(); + + public static void main(String[] args) throws InterruptedException { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setTopic(ExampleConstants.EVENTMESH_GRPC_RR_TEST_TOPIC); + subscriptionItem.setMode(SubscriptionMode.CLUSTERING); + subscriptionItem.setType(SubscriptionType.SYNC); + + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + + eventMeshGrpcConsumer.registerListener(handler); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + + Thread.sleep(60000); + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(CloudEvent msg) { + log.info("receive request-reply msg: {}", msg); + if (msg != null) { + return Optional.of(msg); + } else { + return Optional.empty(); + } + } + + @Override + public String getProtocolType() { + return EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME; + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshAsyncSubscribe.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshAsyncSubscribe.java new file mode 100644 index 0000000000..b372e079a2 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshAsyncSubscribe.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.sub; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.util.Utils; + +import java.util.Collections; +import java.util.Optional; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventmeshAsyncSubscribe implements ReceiveMsgHook { + + public static EventmeshAsyncSubscribe handler = new EventmeshAsyncSubscribe(); + + public static void main(String[] args) throws InterruptedException { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setTopic(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC); + subscriptionItem.setMode(SubscriptionMode.CLUSTERING); + subscriptionItem.setType(SubscriptionType.ASYNC); + + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + + eventMeshGrpcConsumer.registerListener(handler); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + + Thread.sleep(60000); + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(EventMeshMessage msg) { + log.info("receive async msg: {}", msg); + return Optional.empty(); + } + + @Override + public String getProtocolType() { + return EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME; + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshSubscribeBroadcast.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshSubscribeBroadcast.java new file mode 100644 index 0000000000..28753b4c6c --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshSubscribeBroadcast.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.sub; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.util.Utils; + +import java.util.Collections; +import java.util.Optional; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventmeshSubscribeBroadcast implements ReceiveMsgHook { + + public static EventmeshSubscribeBroadcast handler = new EventmeshSubscribeBroadcast(); + + public static void main(String[] args) throws InterruptedException { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setTopic(ExampleConstants.EVENTMESH_GRPC_BROADCAT_TEST_TOPIC); + subscriptionItem.setMode(SubscriptionMode.BROADCASTING); + subscriptionItem.setType(SubscriptionType.ASYNC); + + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + + eventMeshGrpcConsumer.registerListener(handler); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + + Thread.sleep(60000); + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(EventMeshMessage msg) { + log.info("receive async broadcast msg: {}", msg); + return Optional.empty(); + } + + @Override + public String getProtocolType() { + return EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME; + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshSubscribeReply.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshSubscribeReply.java new file mode 100644 index 0000000000..082dacb9f8 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/EventmeshSubscribeReply.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.sub; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.client.grpc.consumer.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.util.Utils; + +import java.util.Collections; +import java.util.Optional; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventmeshSubscribeReply implements ReceiveMsgHook { + + public static EventmeshSubscribeReply handler = new EventmeshSubscribeReply(); + + public static void main(String[] args) throws InterruptedException { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env("env").idc("idc") + .sys("1234").build(); + + SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setTopic(ExampleConstants.EVENTMESH_GRPC_RR_TEST_TOPIC); + subscriptionItem.setMode(SubscriptionMode.CLUSTERING); + subscriptionItem.setType(SubscriptionType.SYNC); + + EventMeshGrpcConsumer eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + + eventMeshGrpcConsumer.init(); + + eventMeshGrpcConsumer.registerListener(handler); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem)); + + Thread.sleep(60000); + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem)); + } + + @Override + public Optional handle(EventMeshMessage msg) { + log.info("receive request-reply msg: {}", msg); + if (msg != null) { + return Optional.of(msg); + } else { + return Optional.empty(); + } + } + + @Override + public String getProtocolType() { + return EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME; + } +} \ No newline at end of file diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/SpringBootDemoApplication.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/SpringBootDemoApplication.java new file mode 100644 index 0000000000..0168b4f727 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/SpringBootDemoApplication.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.sub.app; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) +public class SpringBootDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoApplication.class, args); + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/controller/SubController.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/controller/SubController.java new file mode 100644 index 0000000000..57aaa401d7 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/controller/SubController.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.grpc.sub.app.controller; + +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.grpc.sub.app.service.SubService; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.provider.EventFormatProvider; + +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@RestController +@RequestMapping("/sub") +public class SubController { + + @Autowired + private SubService subService; + + @RequestMapping(value = "/test", method = RequestMethod.POST) + public String subTest(HttpServletRequest request) { + String protocolType = request.getHeader(ProtocolKey.PROTOCOL_TYPE); + String content = request.getParameter("content"); + log.info("=======receive message======= {}", content); + Map contentMap = JsonUtils.deserialize(content, HashMap.class); + if (StringUtils.equals(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME, protocolType)) { + String contentType = request.getHeader(ProtocolKey.CONTENT_TYPE); + + CloudEvent event = EventFormatProvider.getInstance().resolveFormat(contentType) + .deserialize(content.getBytes(StandardCharsets.UTF_8)); + String data = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + log.info("=======receive data======= {}", data); + } + + subService.consumeMessage(content); + + Map map = new HashMap<>(); + map.put("retCode", 1); + return JsonUtils.serialize(map); + } + +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/service/SubService.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/service/SubService.java new file mode 100644 index 0000000000..f48dad1d2d --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/app/service/SubService.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.grpc.sub.app.service; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.grpc.pub.eventmeshmessage.AsyncPublishInstance; +import org.apache.eventmesh.util.Utils; + +import java.util.Collections; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; + +import javax.annotation.PreDestroy; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; + +@Component +public class SubService implements InitializingBean { + + public static Logger logger = LoggerFactory.getLogger(SubService.class); + + private EventMeshGrpcConsumer eventMeshGrpcConsumer; + + final Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + + final SubscriptionItem subscriptionItem = new SubscriptionItem(); + + final String localIp = IPUtils.getLocalAddress(); + final String localPort = properties.getProperty("server.port"); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); + final String url = "http://" + localIp + ":" + localPort + "/sub/test"; + final String env = "P"; + final String idc = "FT"; + final String subsys = "1234"; + + // CountDownLatch size is the same as messageSize in AsyncPublishInstance.java (Publisher) + private CountDownLatch countDownLatch = new CountDownLatch(AsyncPublishInstance.messageSize); + + @Override + public void afterPropertiesSet() throws Exception { + + EventMeshGrpcClientConfig eventMeshClientConfig = EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env(env).idc(idc) + .sys(subsys).build(); + + eventMeshGrpcConsumer = new EventMeshGrpcConsumer(eventMeshClientConfig); + eventMeshGrpcConsumer.init(); + + subscriptionItem.setTopic(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC); + subscriptionItem.setMode(SubscriptionMode.CLUSTERING); + subscriptionItem.setType(SubscriptionType.ASYNC); + + eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem), url); + + // Wait for all messaged to be consumed + Thread stopThread = new Thread(() -> { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + logger.info("stopThread start...."); + throw new RuntimeException(); + }); + stopThread.start(); + } + + @PreDestroy + public void cleanup() { + logger.info("start destory ...."); + try { + eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem), url); + } catch (Exception e) { + e.printStackTrace(); + } + try (final EventMeshGrpcConsumer ignore = eventMeshGrpcConsumer) { + // close consumer + } catch (Exception e) { + e.printStackTrace(); + } + logger.info("end destory."); + } + + /** + * Count the message already consumed + */ + public void consumeMessage(String msg) { + logger.info("consume message: {}", msg); + countDownLatch.countDown(); + logger.info("remaining number of messages to be consumed: {}", countDownLatch.getCount()); + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/cloudevents/AsyncPublishInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/cloudevents/AsyncPublishInstance.java new file mode 100644 index 0000000000..73cd4c09fc --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/cloudevents/AsyncPublishInstance.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.http.demo.pub.cloudevents; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.util.Utils; + +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncPublishInstance { + + public static final int MESSAGE_SIZE = 1; + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshHttpPort = properties.getProperty(ExampleConstants.EVENTMESH_HTTP_PORT); + + // if has multi value, can config as: 127.0.0.1:10105;127.0.0.2:10105 + String eventMeshIPPort = ExampleConstants.DEFAULT_EVENTMESH_IP_PORT; + if (StringUtils.isNotBlank(eventMeshIp) || StringUtils.isNotBlank(eventMeshHttpPort)) { + eventMeshIPPort = eventMeshIp + ":" + eventMeshHttpPort; + } + + // Both the producer and consumer require an instance of EventMeshHttpClientConfig class + // that specifies the configuration of EventMesh HTTP client. + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())) + .userName("eventmesh") + .password("pass") + .build(); + + try (EventMeshHttpProducer eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig)) { + for (int i = 0; i < MESSAGE_SIZE; i++) { + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + eventMeshHttpProducer.publish(event); + log.info("publish event success content: {}", content); + } + Thread.sleep(30000); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/AsyncPublishInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/AsyncPublishInstance.java new file mode 100644 index 0000000000..1d56dd534d --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/AsyncPublishInstance.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.http.demo.pub.eventmeshmessage; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.util.Utils; + +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncPublishInstance { + + // This messageSize is also used in SubService.java (Subscriber) + public static final int messageSize = 5; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshHttpPort = properties.getProperty(ExampleConstants.EVENTMESH_HTTP_PORT); + + final String eventMeshIPPort; + if (StringUtils.isBlank(eventMeshIp) || StringUtils.isBlank(eventMeshHttpPort)) { + // if has multi value, can config as: 127.0.0.1:10105;127.0.0.2:10105 + eventMeshIPPort = ExampleConstants.DEFAULT_EVENTMESH_IP_PORT; + } else { + eventMeshIPPort = eventMeshIp + ":" + eventMeshHttpPort; + } + + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())) + .userName("eventmesh") + .password("pass") + .build(); + + try (EventMeshHttpProducer eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig)) { + for (int i = 0; i < messageSize; i++) { + Map content = new HashMap<>(); + content.put("content", "testPublishMessage"); + + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .bizSeqNo(RandomStringUtils.generateNum(30)) + .content(JsonUtils.serialize(content)) + .topic(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC) + .uniqueId(RandomStringUtils.generateNum(30)) + .build() + .addProp(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)); + eventMeshHttpProducer.publish(eventMeshMessage); + } + Thread.sleep(30000); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/AsyncSyncRequestInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/AsyncSyncRequestInstance.java new file mode 100644 index 0000000000..c3f0ff4f87 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/AsyncSyncRequestInstance.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.http.demo.pub.eventmeshmessage; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.client.http.producer.RRCallback; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.util.Utils; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Properties; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncSyncRequestInstance { + + public static void main(String[] args) throws Exception { + + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + Preconditions.checkNotNull(properties, ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshHttpPort = properties.getProperty(ExampleConstants.EVENTMESH_HTTP_PORT); + + EventMeshHttpProducer eventMeshHttpProducer = null; + try { + String eventMeshIPPort = eventMeshIp + ":" + eventMeshHttpPort; + if (StringUtils.isBlank(eventMeshIPPort)) { + // if has multi value, can config as: 127.0.0.1:10105;127.0.0.2:10105 + eventMeshIPPort = ExampleConstants.DEFAULT_EVENTMESH_IP_PORT; + } + + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())).build(); + + eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + + final long startTime = System.currentTimeMillis(); + final EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .bizSeqNo(RandomStringUtils.generateNum(30)) + .content("testAsyncMessage") + .topic(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC) + .uniqueId(RandomStringUtils.generateNum(30)).build(); + + eventMeshHttpProducer.request(eventMeshMessage, new RRCallback() { + @Override + public void onSuccess(EventMeshMessage o) { + log.debug("sendmsg: {}, return: {}, cost: {} ms", eventMeshMessage.getContent(), o.getContent(), + System.currentTimeMillis() - startTime); + } + + @Override + public void onException(Throwable e) { + log.debug("send msg failed", e); + } + }, 3000); + + Thread.sleep(2000); + } catch (Exception e) { + log.warn("async send msg failed", e); + } + + Thread.sleep(30000); + try (final EventMeshHttpProducer ignore = eventMeshHttpProducer) { + // close producer + } catch (Exception e1) { + log.warn("producer shutdown exception", e1); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/SyncRequestInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/SyncRequestInstance.java new file mode 100644 index 0000000000..a9140cb624 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/pub/eventmeshmessage/SyncRequestInstance.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.http.demo.pub.eventmeshmessage; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import org.apache.commons.lang3.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SyncRequestInstance { + + public static Logger logger = LoggerFactory.getLogger(SyncRequestInstance.class); + + public static void main(String[] args) throws Exception { + + EventMeshHttpProducer eventMeshHttpProducer = null; + String eventMeshIPPort = ExampleConstants.DEFAULT_EVENTMESH_IP_PORT; + String topic = ExampleConstants.EVENTMESH_HTTP_SYNC_TEST_TOPIC; + + try { + if (args.length > 0 && StringUtils.isNotBlank(args[0])) { + eventMeshIPPort = args[0]; + } + if (args.length > 1 && StringUtils.isNotBlank(args[1])) { + topic = args[1]; + } + + if (StringUtils.isBlank(eventMeshIPPort)) { + // if has multi value, can config as: 127.0.0.1:10105;127.0.0.2:10105 + eventMeshIPPort = ExampleConstants.DEFAULT_EVENTMESH_IP_PORT; + } + + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .producerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_PRODUCER_GROUP) + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())).build(); + + eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + + long startTime = System.currentTimeMillis(); + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .bizSeqNo(RandomStringUtils.generateNum(30)) + .content("contentStr with special protocal") + .topic(topic) + .uniqueId(RandomStringUtils.generateNum(30)).build(); + + EventMeshMessage rsp = eventMeshHttpProducer.request(eventMeshMessage, 10000); + if (logger.isDebugEnabled()) { + logger.debug("sendmsg: {}, return: {}, cost:{} ms", eventMeshMessage.getContent(), rsp.getContent(), + System.currentTimeMillis() - startTime); + } + } catch (Exception e) { + logger.warn("send msg failed", e); + } + + Thread.sleep(30000); + try (final EventMeshHttpProducer close = eventMeshHttpProducer) { + // close producer + } catch (Exception e1) { + logger.warn("producer shutdown exception", e1); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/SpringBootDemoApplication.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/SpringBootDemoApplication.java new file mode 100644 index 0000000000..57a4c5baf4 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/SpringBootDemoApplication.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.http.demo.sub; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) +public class SpringBootDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoApplication.class, args); + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/controller/SubController.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/controller/SubController.java new file mode 100644 index 0000000000..e0708a3419 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/controller/SubController.java @@ -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 org.apache.eventmesh.http.demo.sub.controller; + +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.http.demo.sub.service.SubService; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@RestController +@RequestMapping("/sub") +public class SubController { + + @Autowired + private SubService subService; + + @RequestMapping(value = "/test", method = RequestMethod.POST) + public String subTest(HttpServletRequest request) { + String content = request.getParameter("content"); + log.info("receive message: {}", content); + Map contentMap = JsonUtils.deserialize(content, HashMap.class); + if (StringUtils.equals(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME, contentMap.get(ProtocolKey.PROTOCOL_TYPE))) { + CloudEvent event = EventFormatProvider.getInstance() + .resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(content.getBytes(StandardCharsets.UTF_8)); + String data = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + log.info("receive data: {}", data); + } + + subService.consumeMessage(content); + + Map map = new HashMap<>(); + map.put("retCode", 1); + return JsonUtils.serialize(map); + } + +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/service/SubService.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/service/SubService.java new file mode 100644 index 0000000000..d2aab6f738 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/service/SubService.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.http.demo.sub.service; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.consumer.EventMeshHttpConsumer; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.http.demo.pub.eventmeshmessage.AsyncPublishInstance; +import org.apache.eventmesh.util.Utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; + +import javax.annotation.PreDestroy; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; + +import com.google.common.collect.Lists; + +@Component +public class SubService implements InitializingBean { + + public static Logger logger = LoggerFactory.getLogger(SubService.class); + + private EventMeshHttpConsumer eventMeshHttpConsumer; + + final Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + + final List topicList = Lists.newArrayList( + new SubscriptionItem(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC) + ); + final String localIp = IPUtils.getLocalAddress(); + final String localPort = properties.getProperty("server.port"); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshHttpPort = properties.getProperty(ExampleConstants.EVENTMESH_HTTP_PORT); + final String url = "http://" + localIp + ":" + localPort + "/sub/test"; + final String env = "P"; + final String idc = "FT"; + final String subsys = "1234"; + + // CountDownLatch size is the same as messageSize in AsyncPublishInstance.java (Publisher) + private CountDownLatch countDownLatch = new CountDownLatch(AsyncPublishInstance.messageSize); + + @Override + public void afterPropertiesSet() throws Exception { + + final String eventMeshIPPort = eventMeshIp + ":" + eventMeshHttpPort; + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .env(env) + .idc(idc) + .ip(IPUtils.getLocalAddress()) + .sys(subsys) + .pid(String.valueOf(ThreadUtils.getPID())).build(); + + eventMeshHttpConsumer = new EventMeshHttpConsumer(eventMeshClientConfig); + eventMeshHttpConsumer.heartBeat(topicList, url); + eventMeshHttpConsumer.subscribe(topicList, url); + + // Wait for all messaged to be consumed + Thread stopThread = new Thread(() -> { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + logger.info("stopThread start...."); + throw new RuntimeException(); + }); + stopThread.start(); + } + + @PreDestroy + public void cleanup() { + logger.info("start destory ...."); + try { + List unSubList = new ArrayList<>(); + for (SubscriptionItem item : topicList) { + unSubList.add(item.getTopic()); + } + eventMeshHttpConsumer.unsubscribe(unSubList, url); + } catch (Exception e) { + e.printStackTrace(); + } + try (final EventMeshHttpConsumer ignore = eventMeshHttpConsumer) { + // close consumer + } catch (Exception e) { + e.printStackTrace(); + } + logger.info("end destory."); + } + + /** + * Count the message already consumed + */ + public void consumeMessage(String msg) { + logger.info("consume message: {}", msg); + countDownLatch.countDown(); + logger.info("remaining number: {} of messages to be consumed", countDownLatch.getCount()); + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/common/EventMeshTestUtils.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/common/EventMeshTestUtils.java new file mode 100644 index 0000000000..db3182a446 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/common/EventMeshTestUtils.java @@ -0,0 +1,199 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.common; + +import static org.apache.eventmesh.common.protocol.tcp.Command.RESPONSE_TO_SERVER; + +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.common.MessageUtils; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class EventMeshTestUtils { + + private static final int seqLength = 10; + + // generate pub-client + public static UserAgent generateClient1() { + UserAgent agent = UserAgent.builder() + .env("test") + .host("127.0.0.1") + .password(generateRandomString(8)) + .username("PU4283") + .group("EventmeshTestGroup") + .path("/data/app/umg_proxy") + .port(8362) + .subsystem("5023") + .pid(32893) + .version("2.0.11") + .idc("FT") + .build(); + return MessageUtils.generatePubClient(agent); + } + + // generate sub-client + public static UserAgent generateClient2() { + UserAgent agent = UserAgent.builder() + .env("test") + .host("127.0.0.1") + .password(generateRandomString(8)) + .username("PU4283") + .group("EventmeshTestGroup") + .path("/data/app/umg_proxy") + .port(9362) + .subsystem("5017") + .pid(42893) + .version("2.0.11") + .idc("FT") + .build(); + return MessageUtils.generateSubClient(agent); + } + + public static Package syncRR() { + Package msg = new Package(); + msg.setHeader(new Header(Command.REQUEST_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateSyncRRMqMsg()); + return msg; + } + + public static Package asyncRR() { + Package msg = new Package(); + msg.setHeader(new Header(Command.REQUEST_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateAsyncRRMqMsg()); + return msg; + } + + public static Package asyncMessage() { + Package msg = new Package(); + msg.setHeader(new Header(Command.ASYNC_MESSAGE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateAsyncEventMqMsg()); + return msg; + } + + public static Package broadcastMessage() { + Package msg = new Package(); + msg.setHeader(new Header(Command.BROADCAST_MESSAGE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateBroadcastMqMsg()); + return msg; + } + + public static Package rrResponse(EventMeshMessage request) { + Package msg = new Package(); + msg.setHeader(new Header(RESPONSE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(request); + return msg; + } + + public static EventMeshMessage generateSyncRRMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC); + mqMsg.getProperties().put("msgtype", "persistent"); + mqMsg.getProperties().put("ttl", "300000"); + mqMsg.getProperties().put("keys", generateRandomString(16)); + mqMsg.setBody("testSyncRR"); + return mqMsg; + } + + + private static EventMeshMessage generateAsyncRRMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC); + mqMsg.getProperties().put("replyto", "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI"); + mqMsg.getProperties().put("ttl", "300000"); + mqMsg.getProperties().put("propertymessagereplyto", "notnull"); + mqMsg.setBody("testAsyncRR"); + return mqMsg; + } + + public static EventMeshMessage generateAsyncEventMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC); + mqMsg.getProperties().put("replyto", "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI"); + mqMsg.getProperties().put("ttl", "30000"); + mqMsg.getProperties().put("propertymessagereplyto", "notnull"); + mqMsg.setBody("testAsyncMessage"); + return mqMsg; + } + + public static EventMeshMessage generateBroadcastMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC); + mqMsg.getProperties().put("replyto", "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI"); + mqMsg.getProperties().put("ttl", "30000"); + mqMsg.getProperties().put("propertymessagereplyto", "notnull"); + mqMsg.setBody("testAsyncMessage"); + return mqMsg; + } + + private static String generateRandomString(int length) { + StringBuilder builder = new StringBuilder(length); + for (int i = 0; i < length; i++) { + builder.append((char) ThreadLocalRandom.current().nextInt(48, 57)); + } + return builder.toString(); + } + + public static CloudEvent generateCloudEventV1Async() { + Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType("application/cloudevents+json") + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension("ttl", "30000") + .build(); + return event; + } + + public static CloudEvent generateCloudEventV1SyncRR() { + Map content = new HashMap<>(); + content.put("content", "testSyncRR"); + + CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC) + .withSource(URI.create("/")) + .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) + .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.serialize(content).getBytes(StandardCharsets.UTF_8)) + .withExtension("ttl", "30000") + .withExtension("msgtype", "persistent") + .withExtension("keys", generateRandomString(16)) + .build(); + return event; + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/cloudevents/AsyncPublish.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/cloudevents/AsyncPublish.java new file mode 100644 index 0000000000..3cca2341c0 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/cloudevents/AsyncPublish.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.pub.cloudevents; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class AsyncPublish { + + public static Logger logger = LoggerFactory.getLogger(AsyncPublish.class); + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + try { + UserAgent userAgent = EventMeshTestUtils.generateClient1(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + client = + EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); + client.init(); + + for (int i = 0; i < 2; i++) { + CloudEvent event = EventMeshTestUtils.generateCloudEventV1Async(); + logger.info("begin send async msg[{}]: {}", i, event); + client.publish(event, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + + Thread.sleep(1000); + } + Thread.sleep(2000); + } catch (Exception e) { + logger.warn("AsyncPublish failed", e); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/cloudevents/SyncRequest.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/cloudevents/SyncRequest.java new file mode 100644 index 0000000000..2dceddfcf3 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/cloudevents/SyncRequest.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.pub.cloudevents; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.nio.charset.StandardCharsets; +import java.util.Properties; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SyncRequest { + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient1(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try { + client = EventMeshTCPClientFactory.createEventMeshTCPClient( + eventMeshTcpClientConfig, CloudEvent.class); + client.init(); + + CloudEvent event = EventMeshTestUtils.generateCloudEventV1SyncRR(); + log.info("begin send rr msg: {}", event); + Package response = client.rr(event, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + CloudEvent replyEvent = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(response.getBody().toString().getBytes(StandardCharsets.UTF_8)); + String content = new String(replyEvent.getData().toBytes(), StandardCharsets.UTF_8); + log.info("receive rr reply: {}|{}", response, content); + + } catch (Exception e) { + log.warn("SyncRequest failed", e); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/AsyncPublish.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/AsyncPublish.java new file mode 100644 index 0000000000..5a61c2d317 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/AsyncPublish.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.pub.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AsyncPublish { + + public static Logger logger = LoggerFactory.getLogger(AsyncPublish.class); + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + try { + UserAgent userAgent = EventMeshTestUtils.generateClient1(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + client = + EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, EventMeshMessage.class); + client.init(); + + for (int i = 0; i < 5; i++) { + EventMeshMessage eventMeshMessage = EventMeshTestUtils.generateAsyncEventMqMsg(); + + logger.info("begin send async msg[{}]: {}", i, eventMeshMessage); + client.publish(eventMeshMessage, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + + Thread.sleep(1000); + } + Thread.sleep(2000); + } catch (Exception e) { + logger.warn("AsyncPublish failed", e); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/AsyncPublishBroadcast.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/AsyncPublishBroadcast.java new file mode 100644 index 0000000000..b84701b3a0 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/AsyncPublishBroadcast.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.pub.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AsyncPublishBroadcast { + + public static Logger logger = LoggerFactory.getLogger(AsyncPublishBroadcast.class); + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient1(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try (final EventMeshTCPClient client = + EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, EventMeshMessage.class)) { + client.init(); + + EventMeshMessage eventMeshMessage = EventMeshTestUtils.generateBroadcastMqMsg(); + logger.info("begin send broadcast msg: {}", eventMeshMessage); + client.broadcast(eventMeshMessage, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + + Thread.sleep(2000); + + } catch (Exception e) { + logger.warn("AsyncPublishBroadcast failed", e); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/SyncRequest.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/SyncRequest.java new file mode 100644 index 0000000000..582c6f7ca9 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/pub/eventmeshmessage/SyncRequest.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.pub.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SyncRequest { + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient1(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try { + client = EventMeshTCPClientFactory.createEventMeshTCPClient( + eventMeshTcpClientConfig, EventMeshMessage.class); + client.init(); + + EventMeshMessage eventMeshMessage = EventMeshTestUtils.generateSyncRRMqMsg(); + log.info("begin send rr msg: {}", eventMeshMessage); + Package response = client.rr(eventMeshMessage, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + log.info("receive rr reply: {}", response); + + } catch (Exception e) { + log.warn("SyncRequest failed", e); + } + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/cloudevents/AsyncSubscribe.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/cloudevents/AsyncSubscribe.java new file mode 100644 index 0000000000..a4f46a606c --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/cloudevents/AsyncSubscribe.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.sub.cloudevents; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncSubscribe implements ReceiveMsgHook { + + public static AsyncSubscribe handler = new AsyncSubscribe(); + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient2(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try { + client = EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); + client.init(); + + client.subscribe(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC); + client.registerSubBusiHandler(handler); + + client.listen(); + } catch (Exception e) { + log.warn("AsyncSubscribe failed", e); + } + } + + @Override + public Optional handle(CloudEvent msg) { + String content = new String(msg.getData().toBytes(), StandardCharsets.UTF_8); + log.info("receive async msg: {}|{}", msg, content); + return Optional.empty(); + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/cloudevents/SyncResponse.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/cloudevents/SyncResponse.java new file mode 100644 index 0000000000..8314b59926 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/cloudevents/SyncResponse.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.sub.cloudevents; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SyncResponse implements ReceiveMsgHook { + + public static SyncResponse handler = new SyncResponse(); + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient2(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try { + client = EventMeshTCPClientFactory + .createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); + client.init(); + + client.subscribe(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.SYNC); + // Synchronize RR messages + client.registerSubBusiHandler(handler); + + client.listen(); + + } catch (Exception e) { + log.warn("SyncResponse failed", e); + } + } + + @Override + public Optional handle(CloudEvent event) { + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + log.info("receive sync rr msg: {}|{}", event, content); + return Optional.of(event); + } + +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/AsyncSubscribe.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/AsyncSubscribe.java new file mode 100644 index 0000000000..8a3c325ddb --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/AsyncSubscribe.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.sub.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.Optional; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncSubscribe implements ReceiveMsgHook { + + public static AsyncSubscribe handler = new AsyncSubscribe(); + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient2(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try { + client = + EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, EventMeshMessage.class); + client.init(); + + client.subscribe(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC, SubscriptionMode.CLUSTERING, + SubscriptionType.ASYNC); + client.registerSubBusiHandler(handler); + + client.listen(); + + } catch (Exception e) { + log.warn("AsyncSubscribe failed", e); + } + } + + @Override + public Optional handle(EventMeshMessage msg) { + log.info("receive async msg: {}", msg); + return Optional.empty(); + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/AsyncSubscribeBroadcast.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/AsyncSubscribeBroadcast.java new file mode 100644 index 0000000000..2a26947e5a --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/AsyncSubscribeBroadcast.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.sub.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.Optional; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncSubscribeBroadcast implements ReceiveMsgHook { + + public static AsyncSubscribeBroadcast handler = new AsyncSubscribeBroadcast(); + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient2(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try (EventMeshTCPClient client = EventMeshTCPClientFactory.createEventMeshTCPClient( + eventMeshTcpClientConfig, EventMeshMessage.class)) { + client.init(); + + client.subscribe(ExampleConstants.EVENTMESH_TCP_BROADCAST_TEST_TOPIC, SubscriptionMode.BROADCASTING, SubscriptionType.ASYNC); + client.registerSubBusiHandler(handler); + + client.listen(); + + } catch (Exception e) { + log.warn("AsyncSubscribeBroadcast failed", e); + } + } + + @Override + public Optional handle(EventMeshMessage msg) { + log.info("receive broadcast msg: {}", msg); + return Optional.empty(); + } + +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/SyncResponse.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/SyncResponse.java new file mode 100644 index 0000000000..34517ad270 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/demo/sub/eventmeshmessage/SyncResponse.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.tcp.demo.sub.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.tcp.common.EventMeshTestUtils; +import org.apache.eventmesh.util.Utils; + +import java.util.Optional; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SyncResponse implements ReceiveMsgHook { + + public static SyncResponse handler = new SyncResponse(); + + private static EventMeshTCPClient client; + + public static void main(String[] args) throws Exception { + Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final int eventMeshTcpPort = Integer.parseInt(properties.getProperty(ExampleConstants.EVENTMESH_TCP_PORT)); + UserAgent userAgent = EventMeshTestUtils.generateClient2(); + EventMeshTCPClientConfig eventMeshTcpClientConfig = EventMeshTCPClientConfig.builder() + .host(eventMeshIp) + .port(eventMeshTcpPort) + .userAgent(userAgent) + .build(); + try { + client = EventMeshTCPClientFactory + .createEventMeshTCPClient(eventMeshTcpClientConfig, EventMeshMessage.class); + client.init(); + + client.subscribe(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.SYNC); + // Synchronize RR messages + client.registerSubBusiHandler(handler); + + client.listen(); + + } catch (Exception e) { + log.warn("SyncResponse failed", e); + } + } + + @Override + public Optional handle(EventMeshMessage msg) { + log.info("receive sync rr msg: {}", msg); + return Optional.ofNullable(msg); + } + +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/util/Utils.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/util/Utils.java new file mode 100644 index 0000000000..003ac5f610 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/util/Utils.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.util; + +import org.apache.eventmesh.common.ExampleConstants; + +import org.apache.commons.lang3.SystemUtils; + +import java.io.InputStream; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.Properties; + +public class Utils { + + /** + * Get local IP address + * + */ + public static String getLocalIP() throws UnknownHostException { + if (isWindowsOS()) { + return InetAddress.getLocalHost().getHostAddress(); + } else { + return getLinuxLocalIp(); + } + } + + /** + * Determine whether the operating system is Windows + * + * @return + */ + public static boolean isWindowsOS() { + return SystemUtils.IS_OS_WINDOWS; + } + + /** + * Get local IP address under Linux system + * + * @return IP address + */ + private static String getLinuxLocalIp() { + String ip = ""; + try { + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { + NetworkInterface intf = en.nextElement(); + String name = intf.getName(); + if (!name.contains("docker") && !name.contains("lo")) { + for (Enumeration enumIpAddr = intf.getInetAddresses(); + enumIpAddr.hasMoreElements(); ) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress()) { + String ipaddress = inetAddress.getHostAddress(); + if (!ipaddress.contains("::") && !ipaddress.contains("0:0:") + && !ipaddress.contains("fe80")) { + ip = ipaddress; + } + } + } + } + } + } catch (SocketException ex) { + ip = ExampleConstants.DEFAULT_EVENTMESH_IP; + ex.printStackTrace(); + } + return ip; + } + + /** + * @param fileName + * @return Properties + */ + public static Properties readPropertiesFile(String fileName) { + try (final InputStream inputStream = Utils.class.getClassLoader().getResourceAsStream(fileName)) { + Properties properties = new Properties(); + properties.load(inputStream); + return properties; + } catch (Exception e) { + throw new IllegalArgumentException(String.format("File: %s is not exist", fileName)); + } + } + +} diff --git a/eventmesh-examples/src/main/resources/application.properties b/eventmesh-examples/src/main/resources/application.properties new file mode 100644 index 0000000000..51640d82b3 --- /dev/null +++ b/eventmesh-examples/src/main/resources/application.properties @@ -0,0 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +server.port=8088 +eventmesh.ip=127.0.0.1 +eventmesh.http.port=10105 +eventmesh.tcp.port=10000 +eventmesh.grpc.port=10205 \ No newline at end of file diff --git a/eventmesh-examples/src/main/resources/log4j2.xml b/eventmesh-examples/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..87bd36cde3 --- /dev/null +++ b/eventmesh-examples/src/main/resources/log4j2.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eventmesh-examples/src/main/resources/server.env b/eventmesh-examples/src/main/resources/server.env new file mode 100644 index 0000000000..3bef8c5fcf --- /dev/null +++ b/eventmesh-examples/src/main/resources/server.env @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +APP_START_JVM_OPTION:::-server -Xms64M -Xmx128M -Xmn64m -XX:SurvivorRatio=4 -Duser.language=zh diff --git a/eventmesh-governance/build.gradle b/eventmesh-governance/build.gradle deleted file mode 100644 index 11bbc47bf2..0000000000 --- a/eventmesh-governance/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - id 'java' -} - -group 'cn.webank.defibus' -version '1.0.0' - -repositories { - mavenCentral() -} - -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' -} diff --git a/eventmesh-metrics-plugin/build.gradle b/eventmesh-metrics-plugin/build.gradle new file mode 100644 index 0000000000..d973dcedae --- /dev/null +++ b/eventmesh-metrics-plugin/build.gradle @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/build.gradle b/eventmesh-metrics-plugin/eventmesh-metrics-api/build.gradle new file mode 100644 index 0000000000..c64ce2f79c --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/build.gradle @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + api project(":eventmesh-spi") + implementation project(":eventmesh-common") + + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' +} \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/gradle.properties b/eventmesh-metrics-plugin/eventmesh-metrics-api/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/MetricsPluginFactory.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/MetricsPluginFactory.java new file mode 100644 index 0000000000..309a88cb3a --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/MetricsPluginFactory.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.api; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class MetricsPluginFactory { + + /** + * Get {@code MetricsRegistry}. + * + * @param metricsRegistryType + * @return + */ + public static MetricsRegistry getMetricsRegistry(String metricsRegistryType) { + checkNotNull(metricsRegistryType, "MetricsRegistryType cannot be null"); + + MetricsRegistry metricsRegistry = EventMeshExtensionFactory.getExtension(MetricsRegistry.class, metricsRegistryType); + return checkNotNull(metricsRegistry, "MetricsRegistryType: " + metricsRegistryType + " is not supported"); + } +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/MetricsRegistry.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/MetricsRegistry.java new file mode 100644 index 0000000000..6a1bf2ef09 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/MetricsRegistry.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.api; + +import org.apache.eventmesh.metrics.api.model.Metric; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * The top-level interface of metrics registry, used to register different metrics. + * It should have multiple sub implementation, e.g. JVM, Prometheus, i.g. + * + * @since 1.4.0 + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.METRICS) +public interface MetricsRegistry { + + /** + * Start the metrics registry. + */ + void start(); + + /** + * Close the metrics registry. + */ + void showdown(); + + /** + * Register a new Metric, if the metric is already exist, it will do nothing. + * + * @param metric + */ + void register(Metric metric); + + /** + * Remove a metric, if the metric is not exist, it will do nothing. + * + * @param metric + */ + void unRegister(Metric metric); +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/HttpSummaryMetrics.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/HttpSummaryMetrics.java new file mode 100644 index 0000000000..c8c90f6c3c --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/HttpSummaryMetrics.java @@ -0,0 +1,457 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.api.model; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicLong; + +import lombok.extern.slf4j.Slf4j; + +// todo: split this class +@Slf4j +public class HttpSummaryMetrics implements Metric { + + private static final int STATIC_PERIOD = 30 * 1000; + + public HttpSummaryMetrics(final ThreadPoolExecutor batchMsgExecutor, + final ThreadPoolExecutor sendMsgExecutor, + final ThreadPoolExecutor pushMsgExecutor, + final DelayQueue httpFailedQueue) { + this.batchMsgExecutor = batchMsgExecutor; + this.sendMsgExecutor = sendMsgExecutor; + this.pushMsgExecutor = pushMsgExecutor; + this.httpFailedQueue = httpFailedQueue; + } + + public static final String EVENTMESH_MONITOR_FORMAT_HTTP = "{\"maxHTTPTPS\":\"%.1f\",\"avgHTTPTPS\":\"%.1f\"," + //EVENTMESH tps related to accepting external http requests + + "\"maxHTTPCOST\":\"%s\",\"avgHTTPCOST\":\"%.1f\",\"avgHTTPBodyDecodeCost\":\"%.1f\", " + + "\"httpDiscard\":\"%s\"}"; + + private float wholeCost = 0f; + + private AtomicLong wholeRequestNum = new AtomicLong(0); + + //cumulative value + private AtomicLong httpDiscard = new AtomicLong(0); + + private AtomicLong maxCost = new AtomicLong(0); + + private AtomicLong httpRequestPerSecond = new AtomicLong(0); + + private LinkedList httpRequestTPSSnapshots = new LinkedList<>(); + + public float avgHTTPCost() { + float cost = (wholeRequestNum.longValue() == 0L) ? 0f : wholeCost / wholeRequestNum.longValue(); + return cost; + } + + public long maxHTTPCost() { + long cost = maxCost.longValue(); + return cost; + } + + public long getHttpDiscard() { + return httpDiscard.longValue(); + } + + public void recordHTTPRequest() { + httpRequestPerSecond.incrementAndGet(); + } + + public void recordHTTPDiscard() { + httpDiscard.incrementAndGet(); + } + + public void snapshotHTTPTPS() { + Integer tps = httpRequestPerSecond.intValue(); + httpRequestTPSSnapshots.add(tps); + httpRequestPerSecond.set(0); + if (httpRequestTPSSnapshots.size() > STATIC_PERIOD / 1000) { + httpRequestTPSSnapshots.removeFirst(); + } + } + + public float maxHTTPTPS() { + float tps = Collections.max(httpRequestTPSSnapshots); + return tps; + } + + public float avgHTTPTPS() { + float tps = avg(httpRequestTPSSnapshots); + return tps; + } + + public void recordHTTPReqResTimeCost(long cost) { + wholeRequestNum.incrementAndGet(); + wholeCost = wholeCost + cost; + if (cost > maxCost.longValue()) { + maxCost.set(cost); + } + } + + public void httpStatInfoClear() { + wholeRequestNum.set(0L); + wholeCost = 0f; + maxCost.set(0L); + httpDecodeNum.set(0L); + httpDecodeTimeCost = 0f; + } + + private float httpDecodeTimeCost = 0f; + + private AtomicLong httpDecodeNum = new AtomicLong(0); + + public void recordDecodeTimeCost(long cost) { + httpDecodeNum.incrementAndGet(); + httpDecodeTimeCost = httpDecodeTimeCost + cost; + } + + public float avgHTTPBodyDecodeCost() { + float cost = (httpDecodeNum.longValue() == 0L) ? 0f : httpDecodeTimeCost / httpDecodeNum.longValue(); + return cost; + } + + + ////////////////////////////////////////////////////////////////////////// + public static final String EVENTMESH_MONITOR_FORMAT_BATCHSENDMSG = "{\"maxBatchSendMsgTPS\":\"%.1f\",\"avgBatchSendMsgTPS\":\"%.1f\"," + + " \"sum\":\"%s\", \"sumFail\":\"%s\", \"sumFailRate\":\"%.2f\", \"discard\":\"%s\"}"; + + private AtomicLong sendBatchMsgNumPerSecond = new AtomicLong(0); + + private AtomicLong sendBatchMsgNumSum = new AtomicLong(0); + + private AtomicLong sendBatchMsgFailNumSum = new AtomicLong(0); + + // This is a cumulative value + private AtomicLong sendBatchMsgDiscardNumSum = new AtomicLong(0); + + public void recordSendBatchMsgDiscard(long delta) { + sendBatchMsgDiscardNumSum.addAndGet(delta); + } + + private LinkedList sendBatchMsgTPSSnapshots = new LinkedList(); + + public void snapshotSendBatchMsgTPS() { + Integer tps = sendBatchMsgNumPerSecond.intValue(); + sendBatchMsgTPSSnapshots.add(tps); + sendBatchMsgNumPerSecond.set(0); + if (sendBatchMsgTPSSnapshots.size() > STATIC_PERIOD / 1000) { + sendBatchMsgTPSSnapshots.removeFirst(); + } + } + + public float maxSendBatchMsgTPS() { + float tps = Collections.max(sendBatchMsgTPSSnapshots); + return tps; + } + + public float avgSendBatchMsgTPS() { + float tps = avg(sendBatchMsgTPSSnapshots); + return tps; + } + + public void recordSendBatchMsg(long delta) { + sendBatchMsgNumPerSecond.addAndGet(delta); + sendBatchMsgNumSum.addAndGet(delta); + } + + public void recordSendBatchMsgFailed(long delta) { + sendBatchMsgFailNumSum.getAndAdd(delta); + } + + public long getSendBatchMsgNumSum() { + return sendBatchMsgNumSum.longValue(); + } + + public long getSendBatchMsgFailNumSum() { + return sendBatchMsgFailNumSum.longValue(); + } + + public float getSendBatchMsgFailRate() { + return (sendBatchMsgNumSum.longValue() == 0L) ? 0f : sendBatchMsgFailNumSum.floatValue() / sendBatchMsgNumSum.longValue(); + } + + public void cleanSendBatchStat() { + sendBatchMsgNumSum.set(0L); + sendBatchMsgFailNumSum.set(0L); + } + + public long getSendBatchMsgDiscardNumSum() { + return sendBatchMsgDiscardNumSum.longValue(); + } + + ////////////////////////////////////////////////////////////////////////// + public static final String EVENTMESH_MONITOR_FORMAT_SENDMSG = "{\"maxSendMsgTPS\":\"%.1f\",\"avgSendMsgTPS\":\"%.1f\"," + + " \"sum\":\"%s\", \"sumFail\":\"%s\", \"sumFailRate\":\"%.2f\", \"replyMsg\":\"%s\", \"replyFail\":\"%s\"}"; + + private AtomicLong sendMsgNumSum = new AtomicLong(0); + + private AtomicLong sendMsgFailNumSum = new AtomicLong(0); + + private AtomicLong replyMsgNumSum = new AtomicLong(0); + + private AtomicLong replyMsgFailNumSum = new AtomicLong(0); + + private AtomicLong sendMsgNumPerSecond = new AtomicLong(0); + + private LinkedList sendMsgTPSSnapshots = new LinkedList(); + + public void snapshotSendMsgTPS() { + Integer tps = sendMsgNumPerSecond.intValue(); + sendMsgTPSSnapshots.add(tps); + sendMsgNumPerSecond.set(0); + if (sendMsgTPSSnapshots.size() > STATIC_PERIOD / 1000) { + sendMsgTPSSnapshots.removeFirst(); + } + } + + public float maxSendMsgTPS() { + float tps = Collections.max(sendMsgTPSSnapshots); + return tps; + } + + public float avgSendMsgTPS() { + float tps = avg(sendMsgTPSSnapshots); + return tps; + } + + public void recordSendMsg() { + sendMsgNumPerSecond.incrementAndGet(); + sendMsgNumSum.incrementAndGet(); + } + + public void recordReplyMsg() { + replyMsgNumSum.incrementAndGet(); + } + + public void recordReplyMsgFailed() { + replyMsgFailNumSum.incrementAndGet(); + } + + public long getReplyMsgNumSum() { + return replyMsgNumSum.longValue(); + } + + public long getReplyMsgFailNumSum() { + return replyMsgFailNumSum.longValue(); + } + + public long getSendMsgNumSum() { + return sendMsgNumSum.longValue(); + } + + public long getSendMsgFailNumSum() { + return sendMsgFailNumSum.longValue(); + } + + public float getSendMsgFailRate() { + return (sendMsgNumSum.longValue() == 0L) ? 0f : sendMsgFailNumSum.floatValue() / sendMsgNumSum.longValue(); + } + + public void recordSendMsgFailed() { + sendMsgFailNumSum.incrementAndGet(); + } + + public void cleanSendMsgStat() { + sendMsgNumSum.set(0L); + replyMsgNumSum.set(0L); + sendMsgFailNumSum.set(0L); + replyMsgFailNumSum.set(0L); + } + + //////////////////////////////////////////////////////////////////////////// + public static final String EVENTMESH_MONITOR_FORMAT_PUSHMSG = "{\"maxPushMsgTPS\":\"%.1f\",\"avgPushMsgTPS\":\"%.1f\"," + + " \"sum\":\"%s\", \"sumFail\":\"%s\", \"sumFailRate\":\"%.1f\", \"maxClientLatency\":\"%.1f\", \"avgClientLatency\":\"%.1f\"}"; + + private float wholePushCost = 0f; + + private AtomicLong wholePushRequestNum = new AtomicLong(0); + + private AtomicLong maxHttpPushLatency = new AtomicLong(0); + + private AtomicLong pushMsgNumPerSecond = new AtomicLong(0); + + private LinkedList pushMsgTPSSnapshots = new LinkedList(); + + private AtomicLong httpPushMsgNumSum = new AtomicLong(0); + + private AtomicLong httpPushFailNumSum = new AtomicLong(0); + + public void snapshotPushMsgTPS() { + Integer tps = pushMsgNumPerSecond.intValue(); + pushMsgTPSSnapshots.add(tps); + pushMsgNumPerSecond.set(0); + if (pushMsgTPSSnapshots.size() > STATIC_PERIOD / 1000) { + pushMsgTPSSnapshots.removeFirst(); + } + } + + public void recordHTTPPushTimeCost(long cost) { + wholePushRequestNum.incrementAndGet(); + wholePushCost = wholePushCost + cost; + if (cost > maxHttpPushLatency.longValue()) { + maxHttpPushLatency.set(cost); + } + } + + public float avgHTTPPushLatency() { + return (wholePushRequestNum.longValue() == 0L) ? 0f : wholePushCost / wholePushRequestNum.longValue(); + } + + public float maxHTTPPushLatency() { + return maxHttpPushLatency.floatValue(); + } + + public float maxPushMsgTPS() { + float tps = Collections.max(pushMsgTPSSnapshots); + return tps; + } + + public float avgPushMsgTPS() { + float tps = avg(pushMsgTPSSnapshots); + return tps; + } + + public void recordPushMsg() { + pushMsgNumPerSecond.incrementAndGet(); + httpPushMsgNumSum.incrementAndGet(); + } + + public long getHttpPushMsgNumSum() { + return httpPushMsgNumSum.longValue(); + } + + public long getHttpPushFailNumSum() { + return httpPushFailNumSum.longValue(); + } + + public float getHttpPushMsgFailRate() { + return (httpPushMsgNumSum.longValue() == 0L) ? 0f : httpPushFailNumSum.floatValue() / httpPushMsgNumSum.longValue(); + } + + public void recordHttpPushMsgFailed() { + sendMsgFailNumSum.incrementAndGet(); + } + + public void cleanHttpPushMsgStat() { + httpPushFailNumSum.set(0L); + httpPushMsgNumSum.set(0L); + wholeRequestNum.set(0L); + wholeCost = 0f; + maxCost.set(0L); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public static final String EVENTMESH_MONITOR_FORMAT_BLOCKQ = "{\"batchMsgQ\":\"%s\",\"sendMsgQ\":\"%s\"," + + "\"pushMsgQ\":\"%s\",\"httpRetryQ\":\"%s\"}"; + + /////////////////////////////////////////////////////////////////////////// + public static final String EVENTMESH_MONITOR_FORMAT_MQ_CLIENT = "{\"batchAvgSend2MQCost\":\"%.1f\", " + + "\"avgSend2MQCost\":\"%.1f\", \"avgReply2MQCost\":\"%.1f\"}"; + + private float batchSend2MQWholeCost = 0f; + + private AtomicLong batchSend2MQNum = new AtomicLong(0); + + private float send2MQWholeCost = 0f; + + private AtomicLong send2MQNum = new AtomicLong(0); + + private float reply2MQWholeCost = 0f; + + private AtomicLong reply2MQNum = new AtomicLong(0); + + public void recordBatchSendMsgCost(long cost) { + batchSend2MQNum.incrementAndGet(); + batchSend2MQWholeCost = batchSend2MQWholeCost + cost; + } + + public float avgBatchSendMsgCost() { + float cost = (batchSend2MQNum.intValue() == 0) ? 0f : batchSend2MQWholeCost / batchSend2MQNum.intValue(); + return cost; + } + + public void recordSendMsgCost(long cost) { + send2MQNum.incrementAndGet(); + send2MQWholeCost = send2MQWholeCost + cost; + } + + public float avgSendMsgCost() { + float cost = (send2MQNum.intValue() == 0) ? 0f : send2MQWholeCost / send2MQNum.intValue(); + return cost; + } + + public void recordReplyMsgCost(long cost) { + reply2MQNum.incrementAndGet(); + reply2MQWholeCost = reply2MQWholeCost + cost; + } + + public float avgReplyMsgCost() { + float cost = (reply2MQNum.intValue() == 0) ? 0f : reply2MQWholeCost / reply2MQNum.intValue(); + return cost; + } + + public void send2MQStatInfoClear() { + batchSend2MQWholeCost = 0f; + batchSend2MQNum.set(0L); + send2MQWholeCost = 0f; + send2MQNum.set(0L); + reply2MQWholeCost = 0f; + reply2MQNum.set(0L); + } + + // execute metrics + private final ThreadPoolExecutor batchMsgExecutor; + + private final ThreadPoolExecutor sendMsgExecutor; + + private final ThreadPoolExecutor pushMsgExecutor; + + private final DelayQueue httpFailedQueue; + + public int getBatchMsgQueueSize() { + return batchMsgExecutor.getQueue().size(); + } + + public int getSendMsgQueueSize() { + return sendMsgExecutor.getQueue().size(); + } + + public int getPushMsgQueueSize() { + return pushMsgExecutor.getQueue().size(); + } + + public int getHttpRetryQueueSize() { + return httpFailedQueue.size(); + } + + + private float avg(LinkedList linkedList) { + if (linkedList.isEmpty()) { + return 0.0f; + } + + int sum = linkedList.stream().reduce(Integer::sum).get(); + return (float) sum / linkedList.size(); + } + +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/Metric.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/Metric.java new file mode 100644 index 0000000000..ab8903ba62 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/Metric.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.api.model; + +/** + * Top-level metric, all metrics should implement this interface. + */ +public interface Metric { +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/TcpSummaryMetrics.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/TcpSummaryMetrics.java new file mode 100644 index 0000000000..674e5425b0 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/TcpSummaryMetrics.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.api.model; + +import java.util.concurrent.atomic.AtomicInteger; + +import lombok.Data; + +@Data +public class TcpSummaryMetrics implements Metric { + private final AtomicInteger client2eventMeshMsgNum; + private final AtomicInteger eventMesh2mqMsgNum; + private final AtomicInteger mq2eventMeshMsgNum; + private final AtomicInteger eventMesh2clientMsgNum; + + private int client2eventMeshTPS; + private int eventMesh2clientTPS; + private int eventMesh2mqTPS; + private int mq2eventMeshTPS; + private int subTopicNum; + + private int allConnections; + + private int retrySize; + + public TcpSummaryMetrics() { + this.client2eventMeshMsgNum = new AtomicInteger(0); + this.eventMesh2mqMsgNum = new AtomicInteger(0); + this.mq2eventMeshMsgNum = new AtomicInteger(0); + this.eventMesh2clientMsgNum = new AtomicInteger(0); + } + + public int client2eventMeshMsgNum() { + return client2eventMeshMsgNum.get(); + } + + public int eventMesh2mqMsgNum() { + return eventMesh2mqMsgNum.get(); + } + + public int mq2eventMeshMsgNum() { + return mq2eventMeshMsgNum.get(); + } + + public int eventMesh2clientMsgNum() { + return eventMesh2clientMsgNum.get(); + } + + public int getClient2eventMeshTPS() { + return client2eventMeshTPS; + } + + public void setClient2eventMeshTPS(int client2eventMeshTPS) { + this.client2eventMeshTPS = client2eventMeshTPS; + } + + public int getEventMesh2clientTPS() { + return eventMesh2clientTPS; + } + + public void setEventMesh2clientTPS(int eventMesh2clientTPS) { + this.eventMesh2clientTPS = eventMesh2clientTPS; + } + + public int getEventMesh2mqTPS() { + return eventMesh2mqTPS; + } + + public void setEventMesh2mqTPS(int eventMesh2mqTPS) { + this.eventMesh2mqTPS = eventMesh2mqTPS; + } + + public int getMq2eventMeshTPS() { + return mq2eventMeshTPS; + } + + public void setMq2eventMeshTPS(int mq2eventMeshTPS) { + this.mq2eventMeshTPS = mq2eventMeshTPS; + } + + public int getAllTPS() { + return client2eventMeshTPS + eventMesh2clientTPS; + } + + public int getSubTopicNum() { + return subTopicNum; + } + + public void setSubTopicNum(int subTopicNum) { + this.subTopicNum = subTopicNum; + } + + public int getAllConnections() { + return allConnections; + } + + public void setAllConnections(int allConnections) { + this.allConnections = allConnections; + } + + public void setRetrySize(int retrySize) { + this.retrySize = retrySize; + } + + public int getRetrySize() { + return retrySize; + } +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/build.gradle b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/build.gradle new file mode 100644 index 0000000000..2257341b38 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/build.gradle @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation project(":eventmesh-metrics-plugin:eventmesh-metrics-api") + implementation project(":eventmesh-common") + implementation 'org.slf4j:slf4j-api' + implementation 'org.apache.commons:commons-lang3' + implementation 'com.google.guava:guava' + + // todo:Can we remove some dependency? + implementation 'io.opentelemetry:opentelemetry-api' + implementation 'io.opentelemetry:opentelemetry-sdk' + implementation 'io.opentelemetry:opentelemetry-sdk-metrics' + implementation 'io.opentelemetry:opentelemetry-exporter-prometheus' + implementation 'io.prometheus:simpleclient' + implementation 'io.prometheus:simpleclient_httpserver' + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' +} \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/gradle.properties b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/gradle.properties new file mode 100644 index 0000000000..117de99e0e --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=metrics +pluginName=prometheus \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/PrometheusMetricsRegistry.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/PrometheusMetricsRegistry.java new file mode 100644 index 0000000000..d96a07b9ee --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/PrometheusMetricsRegistry.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.prometheus; + +import org.apache.eventmesh.metrics.api.MetricsRegistry; +import org.apache.eventmesh.metrics.api.model.HttpSummaryMetrics; +import org.apache.eventmesh.metrics.api.model.Metric; +import org.apache.eventmesh.metrics.api.model.TcpSummaryMetrics; +import org.apache.eventmesh.metrics.prometheus.config.PrometheusConfiguration; +import org.apache.eventmesh.metrics.prometheus.metrics.PrometheusHttpExporter; +import org.apache.eventmesh.metrics.prometheus.metrics.PrometheusTcpExporter; + +import java.io.IOException; + +import io.opentelemetry.exporter.prometheus.PrometheusCollector; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.prometheus.client.exporter.HTTPServer; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PrometheusMetricsRegistry implements MetricsRegistry { + + private volatile HTTPServer prometheusHttpServer; + + @Override + public void start() { + if (prometheusHttpServer == null) { + synchronized (PrometheusMetricsRegistry.class) { + if (prometheusHttpServer == null) { + SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder().buildAndRegisterGlobal(); + PrometheusCollector + .builder().setMetricProducer(sdkMeterProvider).buildAndRegister(); + int port = PrometheusConfiguration.getEventMeshPrometheusPort(); + try { + //Use the daemon thread to start an HTTP server to serve the default Prometheus registry. + prometheusHttpServer = new HTTPServer(port, true); + } catch (IOException e) { + log.error("failed to start prometheus server, port: {} due to {}", port, e.getMessage()); + } + } + } + } + + } + + @Override + public void showdown() { + if (prometheusHttpServer != null) { + prometheusHttpServer.stop(); + } + } + + @Override + public void register(Metric metric) { + if (metric == null) { + throw new IllegalArgumentException("Metric cannot be null"); + } + if (metric instanceof HttpSummaryMetrics) { + PrometheusHttpExporter.export("apache-eventmesh", (HttpSummaryMetrics) metric); + } + + if (metric instanceof TcpSummaryMetrics) { + PrometheusTcpExporter.export("apache-eventmesh", (TcpSummaryMetrics) metric); + } + } + + @Override + public void unRegister(Metric metric) { + // todo: need to split the current metrics + } +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/config/PrometheusConfiguration.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/config/PrometheusConfiguration.java new file mode 100644 index 0000000000..0f9b48e158 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/config/PrometheusConfiguration.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.prometheus.config; + +import org.apache.eventmesh.common.Constants; + +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@UtilityClass +public class PrometheusConfiguration { + + private static final String CONFIG_FILE = "prometheus.properties"; + private static final Properties properties = new Properties(); + + private int eventMeshPrometheusPort = 19090; + + static { + loadProperties(); + initializeConfig(); + } + + public static int getEventMeshPrometheusPort() { + return eventMeshPrometheusPort; + } + + private void initializeConfig() { + String eventMeshPrometheusPortStr = properties.getProperty("eventMesh.metrics.prometheus.port"); + if (StringUtils.isNotEmpty(eventMeshPrometheusPortStr)) { + eventMeshPrometheusPort = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshPrometheusPortStr)); + } + } + + /** + * Load properties file from classpath and conf home. + * The properties defined in conf home will override classpath. + */ + private void loadProperties() { + try (InputStream resourceAsStream = PrometheusConfiguration.class.getResourceAsStream(File.separator + CONFIG_FILE)) { + if (resourceAsStream != null) { + properties.load(resourceAsStream); + } + } catch (IOException e) { + throw new RuntimeException(String.format("Load %s file from classpath error", CONFIG_FILE)); + } + try { + String configPath = Constants.EVENTMESH_CONF_HOME + File.separator + CONFIG_FILE; + if (new File(configPath).exists()) { + properties.load(new BufferedReader(new FileReader(configPath))); + } + } catch (IOException e) { + throw new IllegalArgumentException(String.format("Cannot load %s file from conf", CONFIG_FILE)); + } + } + +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusHttpExporter.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusHttpExporter.java new file mode 100644 index 0000000000..0f87aa8eaf --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusHttpExporter.java @@ -0,0 +1,298 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.prometheus.metrics; + +import org.apache.eventmesh.metrics.api.model.HttpSummaryMetrics; + +import io.opentelemetry.api.metrics.GlobalMeterProvider; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.common.Labels; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class PrometheusHttpExporter { + + public static void export(String name, HttpSummaryMetrics summaryMetrics) { + Meter meter = GlobalMeterProvider.getMeter(name); + //maxHTTPTPS + meter + .doubleValueObserverBuilder("eventmesh.http.request.tps.max") + .setDescription("max TPS of HTTP.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.maxHTTPTPS(), Labels.empty())) + .build(); + + //avgHTTPTPS + meter + .doubleValueObserverBuilder("eventmesh.http.request.tps.avg") + .setDescription("avg TPS of HTTP.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgHTTPTPS(), Labels.empty())) + .build(); + + //maxHTTPCost + meter + .longValueObserverBuilder("eventmesh.http.request.cost.max") + .setDescription("max cost of HTTP.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.maxHTTPCost(), Labels.empty())) + .build(); + + //avgHTTPCost + meter + .doubleValueObserverBuilder("eventmesh.http.request.cost.avg") + .setDescription("avg cost of HTTP.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgHTTPCost(), Labels.empty())) + .build(); + + //avgHTTPBodyDecodeCost + meter + .doubleValueObserverBuilder("eventmesh.http.body.decode.cost.avg") + .setDescription("avg body decode cost of HTTP.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgHTTPBodyDecodeCost(), Labels.empty())) + .build(); + + //httpDiscard + meter + .longValueObserverBuilder("eventmesh.http.request.discard.num") + .setDescription("http request discard num.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getHttpDiscard(), Labels.empty())) + .build(); + + //maxBatchSendMsgTPS + meter + .doubleValueObserverBuilder("eventmesh.batch.send.message.tps.max") + .setDescription("max of batch send message tps.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.maxSendBatchMsgTPS(), Labels.empty())) + .build(); + + //avgBatchSendMsgTPS + meter + .doubleValueObserverBuilder("eventmesh.batch.send.message.tps.avg") + .setDescription("avg of batch send message tps.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgSendBatchMsgTPS(), Labels.empty())) + .build(); + + //sum + meter + .doubleValueObserverBuilder("eventmesh.batch.send.message.num") + .setDescription("sum of batch send message number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendBatchMsgNumSum(), Labels.empty())) + .build(); + + //sumFail + meter + .doubleValueObserverBuilder("eventmesh.batch.send.message.fail.num") + .setDescription("sum of batch send message fail message number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendBatchMsgFailNumSum(), Labels.empty())) + .build(); + + //sumFailRate + meter + .doubleValueObserverBuilder("eventmesh.batch.send.message.fail.rate") + .setDescription("send batch message fail rate.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendBatchMsgFailRate(), Labels.empty())) + .build(); + + //discard + meter + .doubleValueObserverBuilder("eventmesh.batch.send.message.discard.num") + .setDescription("sum of send batch message discard number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendBatchMsgDiscardNumSum(), Labels.empty())) + .build(); + + //maxSendMsgTPS + meter + .doubleValueObserverBuilder("eventmesh.send.message.tps.max") + .setDescription("max of send message tps.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.maxSendMsgTPS(), Labels.empty())) + .build(); + + //avgSendMsgTPS + meter + .doubleValueObserverBuilder("eventmesh.send.message.tps.avg") + .setDescription("avg of send message tps.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgSendMsgTPS(), Labels.empty())) + .build(); + + //sum + meter + .doubleValueObserverBuilder("eventmesh.send.message.num") + .setDescription("sum of send message number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendMsgNumSum(), Labels.empty())) + .build(); + + //sumFail + meter + .doubleValueObserverBuilder("eventmesh.send.message.fail.num") + .setDescription("sum of send message fail number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendMsgFailNumSum(), Labels.empty())) + .build(); + + //sumFailRate + meter + .doubleValueObserverBuilder("eventmesh.send.message.fail.rate") + .setDescription("send message fail rate.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendMsgFailRate(), Labels.empty())) + .build(); + + //replyMsg + meter + .doubleValueObserverBuilder("eventmesh.reply.message.num") + .setDescription("sum of reply message number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getReplyMsgNumSum(), Labels.empty())) + .build(); + + //replyFail + meter + .doubleValueObserverBuilder("eventmesh.reply.message.fail.num") + .setDescription("sum of reply message fail number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getReplyMsgFailNumSum(), Labels.empty())) + .build(); + + //maxPushMsgTPS + meter + .doubleValueObserverBuilder("eventmesh.push.message.tps.max") + .setDescription("max of push message tps.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.maxPushMsgTPS(), Labels.empty())) + .build(); + + //avgPushMsgTPS + meter + .doubleValueObserverBuilder("eventmesh.push.message.tps.avg") + .setDescription("avg of push message tps.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgPushMsgTPS(), Labels.empty())) + .build(); + + //sum + meter + .doubleValueObserverBuilder("eventmesh.http.push.message.num") + .setDescription("sum of http push message number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getHttpPushMsgNumSum(), Labels.empty())) + .build(); + + //sumFail + meter + .doubleValueObserverBuilder("eventmesh.http.push.message.fail.num") + .setDescription("sum of http push message fail number.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getHttpPushFailNumSum(), Labels.empty())) + .build(); + + //sumFailRate + meter + .doubleValueObserverBuilder("eventmesh.http.push.message.fail.rate") + .setDescription("http push message fail rate.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getHttpPushMsgFailRate(), Labels.empty())) + .build(); + + //maxClientLatency + meter + .doubleValueObserverBuilder("eventmesh.http.push.latency.max") + .setDescription("max of http push latency.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.maxHTTPPushLatency(), Labels.empty())) + .build(); + + //avgClientLatency + meter + .doubleValueObserverBuilder("eventmesh.http.push.latency.avg") + .setDescription("avg of http push latency.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgHTTPPushLatency(), Labels.empty())) + .build(); + + //batchMsgQ + meter + .longValueObserverBuilder("eventmesh.batch.message.queue.size") + .setDescription("size of batch message queue.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getBatchMsgQueueSize(), Labels.empty())) + .build(); + + //sendMsgQ + meter + .longValueObserverBuilder("eventmesh.send.message.queue.size") + .setDescription("size of send message queue.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getSendMsgQueueSize(), Labels.empty())) + .build(); + + //pushMsgQ + meter + .longValueObserverBuilder("eventmesh.push.message.queue.size") + .setDescription("size of push message queue.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getPushMsgQueueSize(), Labels.empty())) + .build(); + + //httpRetryQ + meter + .longValueObserverBuilder("eventmesh.http.retry.queue.size") + .setDescription("size of http retry queue.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.getHttpRetryQueueSize(), Labels.empty())) + .build(); + + //batchAvgSend2MQCost + meter + .doubleValueObserverBuilder("eventmesh.batch.send.message.cost.avg") + .setDescription("avg of batch send message cost.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgBatchSendMsgCost(), Labels.empty())) + .build(); + + //avgSend2MQCost + meter + .doubleValueObserverBuilder("eventmesh.send.message.cost.avg") + .setDescription("avg of send message cost.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgSendMsgCost(), Labels.empty())) + .build(); + + //avgReply2MQCost + meter + .doubleValueObserverBuilder("eventmesh.reply.message.cost.avg") + .setDescription("avg of reply message cost.") + .setUnit("HTTP") + .setUpdater(result -> result.observe(summaryMetrics.avgReplyMsgCost(), Labels.empty())) + .build(); + } + +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusTcpExporter.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusTcpExporter.java new file mode 100644 index 0000000000..01edb55496 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusTcpExporter.java @@ -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 org.apache.eventmesh.metrics.prometheus.metrics; + +import org.apache.eventmesh.metrics.api.model.TcpSummaryMetrics; + +import io.opentelemetry.api.metrics.GlobalMeterProvider; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.common.Labels; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class PrometheusTcpExporter { + + public static void export(final String meterName, final TcpSummaryMetrics summaryMetrics) { + final Meter meter = GlobalMeterProvider.getMeter(meterName); + //retryQueueSize + meter.doubleValueObserverBuilder("eventmesh.tcp.retry.queue.size") + .setDescription("get size of retry queue.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getRetrySize(), Labels.empty())) + .build(); + + //client2eventMeshTPS + meter.doubleValueObserverBuilder("eventmesh.tcp.server.tps") + .setDescription("get tps of client to eventMesh.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getClient2eventMeshTPS(), Labels.empty())) + .build(); + + //eventMesh2mqTPS + meter.doubleValueObserverBuilder("eventmesh.tcp.mq.provider.tps") + .setDescription("get tps of eventMesh to mq.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getEventMesh2mqTPS(), Labels.empty())) + .build(); + + //mq2eventMeshTPS + meter.doubleValueObserverBuilder("eventmesh.tcp.mq.consumer.tps") + .setDescription("get tps of mq to eventMesh.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getMq2eventMeshTPS(), Labels.empty())) + .build(); + + //eventMesh2clientTPS + meter.doubleValueObserverBuilder("eventmesh.tcp.client.tps") + .setDescription("get tps of eventMesh to client.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getEventMesh2clientTPS(), Labels.empty())) + .build(); + + //allTPS + meter.doubleValueObserverBuilder("eventmesh.tcp.all.tps") + .setDescription("get all TPS.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getAllTPS(), Labels.empty())) + .build(); + + //EventMeshTcpConnectionHandler.connections + meter.doubleValueObserverBuilder("eventmesh.tcp.connection.num") + .setDescription("EventMeshTcpConnectionHandler.connections.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getAllConnections(), Labels.empty())) + .build(); + + //subTopicNum + meter.doubleValueObserverBuilder("eventmesh.tcp.sub.topic.num") + .setDescription("get sub topic num.") + .setUnit("TCP") + .setUpdater(result -> result.observe(summaryMetrics.getSubTopicNum(), Labels.empty())) + .build(); + } +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.metrics.api.MetricsRegistry b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.metrics.api.MetricsRegistry new file mode 100644 index 0000000000..839794f97a --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.metrics.api.MetricsRegistry @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +prometheus=org.apache.eventmesh.metrics.prometheus.PrometheusMetricsRegistry \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/prometheus.properties b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/prometheus.properties new file mode 100644 index 0000000000..efb8c32a61 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/prometheus.properties @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# You can get the export metrics by this port +eventMesh.metrics.prometheus.port=19090 \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/prometheus.yml b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/prometheus.yml new file mode 100644 index 0000000000..8703ea250d --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/resources/prometheus.yml @@ -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. +# + +global: + scrape_interval: 15s + scrape_timeout: 10s + evaluation_interval: 15s +alerting: + alertmanagers: + - static_configs: + - targets: [] + scheme: http + timeout: 10s + api_version: v1 +scrape_configs: +- job_name: prometheus + honor_timestamps: true + scrape_interval: 15s + scrape_timeout: 10s + metrics_path: /metrics + scheme: http + static_configs: + - targets: + - localhost:9090 +- job_name: EventMesh_HTTP_export_test + honor_timestamps: true + scrape_interval: 15s + scrape_timeout: 10s + metrics_path: /metrics + scheme: http + static_configs: + - targets: + - 127.0.0.1:19090 diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/test/java/org/apache/eventmesh/metrics/prometheus/config/PrometheusConfigurationTest.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/test/java/org/apache/eventmesh/metrics/prometheus/config/PrometheusConfigurationTest.java new file mode 100644 index 0000000000..12a3f8a0ef --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/test/java/org/apache/eventmesh/metrics/prometheus/config/PrometheusConfigurationTest.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.metrics.prometheus.config; + +import org.junit.Assert; +import org.junit.Test; + +public class PrometheusConfigurationTest { + + @Test + public void getEventMeshPrometheusPort() { + int eventMeshPrometheusPort = PrometheusConfiguration.getEventMeshPrometheusPort(); + Assert.assertEquals(19090, eventMeshPrometheusPort); + } +} \ No newline at end of file diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/test/resources/prometheus.properties b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/test/resources/prometheus.properties new file mode 100644 index 0000000000..d4fb5a13c3 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/test/resources/prometheus.properties @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +eventMesh.metrics.prometheus.port=19090 \ No newline at end of file diff --git a/eventmesh-metrics-plugin/gradle.properties b/eventmesh-metrics-plugin/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-metrics-plugin/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-api/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-api/build.gradle new file mode 100644 index 0000000000..ab24959cf9 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-api/build.gradle @@ -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. + */ + +dependencies { + api project(":eventmesh-spi") + api project(":eventmesh-common") + + implementation "io.cloudevents:cloudevents-core" + + testImplementation project(":eventmesh-spi") + testImplementation project(":eventmesh-common") + + testImplementation "io.cloudevents:cloudevents-core" + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' +} \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/ProtocolAdaptor.java b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/ProtocolAdaptor.java new file mode 100644 index 0000000000..b6d5c83a47 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/ProtocolAdaptor.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.api; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.List; + +import io.cloudevents.CloudEvent; + +/** + * Protocol transformer SPI interface, all protocol plugin should implementation. + * + *

All protocol stored in EventMesh is {@link CloudEvent}. + * + * @since 1.3.0 + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.PROTOCOL) +public interface ProtocolAdaptor { + + /** + * transform protocol to {@link CloudEvent}. + * + * @param protocol input protocol + * @return cloud event + */ + CloudEvent toCloudEvent(T protocol) throws ProtocolHandleException; + + /** + * transform protocol to {@link CloudEvent} list. + * + * @param protocol input protocol + * @return list cloud event + */ + List toBatchCloudEvent(T protocol) throws ProtocolHandleException; + + /** + * Transform {@link CloudEvent} to target protocol. + * + * @param cloudEvent clout event + * @return target protocol + */ + ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException; + + /** + * Get protocol type. + * + * @return protocol type, protocol type should not be null + */ + String getProtocolType(); + +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/ProtocolPluginFactory.java b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/ProtocolPluginFactory.java new file mode 100644 index 0000000000..1d2cd40426 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/ProtocolPluginFactory.java @@ -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 org.apache.eventmesh.protocol.api; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import lombok.experimental.UtilityClass; + +/** + * A factory to get Protocol plugin instance. + * + * @since 1.3.0 + */ +@UtilityClass +public class ProtocolPluginFactory { + + private static final Map> PROTOCOL_ADAPTOR_MAP = + new ConcurrentHashMap<>(16); + + /** + * Get protocol adaptor by name. + * + * @param protocolType protocol type + * @return protocol adaptor + * @throws IllegalArgumentException if protocol not found + */ + @SuppressWarnings("unchecked") + public static ProtocolAdaptor getProtocolAdaptor(String protocolType) { + ProtocolAdaptor protocolAdaptor = PROTOCOL_ADAPTOR_MAP.computeIfAbsent( + protocolType, + (type) -> EventMeshExtensionFactory.getExtension(ProtocolAdaptor.class, type) + ); + if (protocolAdaptor == null) { + throw new IllegalArgumentException( + String.format("Cannot find the Protocol adaptor: %s", protocolType) + ); + } + return protocolAdaptor; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/exception/ProtocolHandleException.java b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/exception/ProtocolHandleException.java new file mode 100644 index 0000000000..27f823a449 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/main/java/org/apache/eventmesh/protocol/api/exception/ProtocolHandleException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.api.exception; + +/** + * Protocol Handle exception, will be thrown in protocol handling. + * + * @since 1.3.0 + */ +public class ProtocolHandleException extends Exception { + + public ProtocolHandleException(String message) { + super(message); + } + + public ProtocolHandleException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle new file mode 100644 index 0000000000..9f3b904951 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + implementation "io.cloudevents:cloudevents-core" + implementation "com.google.guava:guava" + implementation "io.cloudevents:cloudevents-json-jackson" + implementation "io.grpc:grpc-protobuf:1.17.1" +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/gradle.properties b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/gradle.properties new file mode 100644 index 0000000000..b3e1265f26 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=protocol +pluginName=cloudevents \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/CloudEventsProtocolAdaptor.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/CloudEventsProtocolAdaptor.java new file mode 100644 index 0000000000..5763e60ece --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/CloudEventsProtocolAdaptor.java @@ -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 org.apache.eventmesh.protocol.cloudevents; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.common.BatchMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; +import org.apache.eventmesh.protocol.cloudevents.resolver.grpc.GrpcMessageProtocolResolver; +import org.apache.eventmesh.protocol.cloudevents.resolver.http.SendMessageBatchProtocolResolver; +import org.apache.eventmesh.protocol.cloudevents.resolver.http.SendMessageBatchV2ProtocolResolver; +import org.apache.eventmesh.protocol.cloudevents.resolver.http.SendMessageRequestProtocolResolver; +import org.apache.eventmesh.protocol.cloudevents.resolver.tcp.TcpMessageProtocolResolver; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +import com.google.common.base.Preconditions; + +/** + * CloudEvents protocol adaptor, used to transform CloudEvents message to CloudEvents message. + * + * @since 1.3.0 + */ +public class CloudEventsProtocolAdaptor + implements ProtocolAdaptor { + + @Override + public CloudEvent toCloudEvent(ProtocolTransportObject cloudEvent) throws ProtocolHandleException { + + if (cloudEvent instanceof Package) { + Package tcpPackage = (Package) cloudEvent; + Header header = tcpPackage.getHeader(); + String cloudEventJson = tcpPackage.getBody().toString(); + + return deserializeTcpProtocol(header, cloudEventJson); + + } else if (cloudEvent instanceof HttpCommand) { + org.apache.eventmesh.common.protocol.http.header.Header header = ((HttpCommand) cloudEvent).getHeader(); + Body body = ((HttpCommand) cloudEvent).getBody(); + String requestCode = ((HttpCommand) cloudEvent).getRequestCode(); + + return deserializeHttpProtocol(requestCode, header, body); + } else if (cloudEvent instanceof SimpleMessageWrapper) { + SimpleMessage simpleMessage = ((SimpleMessageWrapper) cloudEvent).getMessage(); + return GrpcMessageProtocolResolver.buildEvent(simpleMessage); + } else { + throw new ProtocolHandleException(String.format("protocol class: %s", cloudEvent.getClass())); + } + } + + private CloudEvent deserializeTcpProtocol(Header header, String cloudEventJson) throws ProtocolHandleException { + return TcpMessageProtocolResolver.buildEvent(header, cloudEventJson); + } + + private CloudEvent deserializeHttpProtocol(String requestCode, + org.apache.eventmesh.common.protocol.http.header.Header header, + Body body) throws ProtocolHandleException { + + if (String.valueOf(RequestCode.MSG_BATCH_SEND.getRequestCode()).equals(requestCode)) { + return SendMessageBatchProtocolResolver.buildEvent(header, body); + } else if (String.valueOf(RequestCode.MSG_BATCH_SEND_V2.getRequestCode()).equals(requestCode)) { + return SendMessageBatchV2ProtocolResolver.buildEvent(header, body); + } else if (String.valueOf(RequestCode.MSG_SEND_SYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestProtocolResolver.buildEvent(header, body); + } else if (String.valueOf(RequestCode.MSG_SEND_ASYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestProtocolResolver.buildEvent(header, body); + } else { + throw new ProtocolHandleException(String.format("unsupported requestCode: %s", requestCode)); + } + + } + + @Override + public List toBatchCloudEvent(ProtocolTransportObject protocol) + throws ProtocolHandleException { + if (protocol instanceof BatchMessageWrapper) { + BatchMessage batchMessage = ((BatchMessageWrapper) protocol).getMessage(); + return GrpcMessageProtocolResolver.buildBatchEvents(batchMessage); + } else { + throw new ProtocolHandleException(String.format("protocol class: %s", protocol.getClass())); + } + } + + @Override + public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException { + String protocolDesc = cloudEvent.getExtension(Constants.PROTOCOL_DESC).toString(); + if (StringUtils.equals("http", protocolDesc)) { + HttpCommand httpCommand = new HttpCommand(); + Body body = new Body() { + final Map map = new HashMap<>(); + + @Override + public Map toMap() { + byte[] eventByte = + EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE).serialize(cloudEvent); + map.put("content", new String(eventByte, StandardCharsets.UTF_8)); + return map; + } + }; + body.toMap(); + httpCommand.setBody(body); + return httpCommand; + } else if (StringUtils.equals("tcp", protocolDesc)) { + Package pkg = new Package(); + String dataContentType = cloudEvent.getDataContentType(); + Preconditions.checkNotNull(dataContentType, "DateContentType cannot be null"); + EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(dataContentType); + Preconditions.checkNotNull(eventFormat, + String.format("DateContentType:%s is not supported", dataContentType)); + pkg.setBody(eventFormat.serialize(cloudEvent)); + return pkg; + } else if (StringUtils.equals("grpc", protocolDesc)) { + return GrpcMessageProtocolResolver.buildSimpleMessage(cloudEvent); + } else { + throw new ProtocolHandleException(String.format("Unsupported protocolDesc: %s", protocolDesc)); + } + + } + + @Override + public String getProtocolType() { + return CloudEventsProtocolConstant.PROTOCOL_NAME; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/CloudEventsProtocolConstant.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/CloudEventsProtocolConstant.java new file mode 100644 index 0000000000..7c26920626 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/CloudEventsProtocolConstant.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.cloudevents; + +public enum CloudEventsProtocolConstant { + ; + public static final String PROTOCOL_NAME = "cloudevents"; +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/WebHookProtocolAdaptor.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/WebHookProtocolAdaptor.java new file mode 100644 index 0000000000..691f0b81c8 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/WebHookProtocolAdaptor.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.cloudevents; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.WebhookProtocolTransportObject; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class WebHookProtocolAdaptor implements ProtocolAdaptor { + + @Override + public CloudEvent toCloudEvent(WebhookProtocolTransportObject protocol) throws ProtocolHandleException { + return CloudEventBuilder.v1() + .withId(protocol.getCloudEventId()) + .withSubject(protocol.getCloudEventName()) + .withSource(URI.create(protocol.getCloudEventSource())) + .withDataContentType(protocol.getDataContentType()) + .withType(protocol.getEventType()) + .withData(protocol.getBody()) + .build(); + } + + @Override + public List toBatchCloudEvent(WebhookProtocolTransportObject protocol) throws ProtocolHandleException { + List cloudEventList = new ArrayList(); + return cloudEventList; + } + + @Override + public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException { + return null; + } + + @Override + public String getProtocolType() { + return "webhookProtocolAdaptor"; + } + +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/grpc/GrpcMessageProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/grpc/GrpcMessageProtocolResolver.java new file mode 100644 index 0000000000..6424c72482 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/grpc/GrpcMessageProtocolResolver.java @@ -0,0 +1,233 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.cloudevents.resolver.grpc; + +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; + +public class GrpcMessageProtocolResolver { + + public static CloudEvent buildEvent(SimpleMessage message) { + String cloudEventJson = message.getContent(); + + String contentType = message.getPropertiesOrDefault(ProtocolKey.CONTENT_TYPE, "application/cloudevents+json"); + EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(contentType); + CloudEvent event = eventFormat.deserialize(cloudEventJson.getBytes(StandardCharsets.UTF_8)); + + RequestHeader header = message.getHeader(); + String env = StringUtils.isEmpty(header.getEnv()) ? event.getExtension(ProtocolKey.ENV).toString() : header.getEnv(); + String idc = StringUtils.isEmpty(header.getIdc()) ? event.getExtension(ProtocolKey.IDC).toString() : header.getIdc(); + String ip = StringUtils.isEmpty(header.getIp()) ? event.getExtension(ProtocolKey.IP).toString() : header.getIp(); + String pid = StringUtils.isEmpty(header.getPid()) ? event.getExtension(ProtocolKey.PID).toString() : header.getPid(); + String sys = StringUtils.isEmpty(header.getSys()) ? event.getExtension(ProtocolKey.SYS).toString() : header.getSys(); + + String language = StringUtils.isEmpty(header.getLanguage()) + ? event.getExtension(ProtocolKey.LANGUAGE).toString() : header.getLanguage(); + + String protocolType = StringUtils.isEmpty(header.getProtocolType()) + ? event.getExtension(ProtocolKey.PROTOCOL_TYPE).toString() : header.getProtocolType(); + + String protocolDesc = StringUtils.isEmpty(header.getProtocolDesc()) + ? event.getExtension(ProtocolKey.PROTOCOL_DESC).toString() : header.getProtocolDesc(); + + String protocolVersion = StringUtils.isEmpty(header.getProtocolVersion()) + ? event.getExtension(ProtocolKey.PROTOCOL_VERSION).toString() : header.getProtocolVersion(); + + String uniqueId = StringUtils.isEmpty(message.getUniqueId()) + ? event.getExtension(ProtocolKey.UNIQUE_ID).toString() : message.getUniqueId(); + + String seqNum = StringUtils.isEmpty(message.getSeqNum()) + ? event.getExtension(ProtocolKey.SEQ_NUM).toString() : message.getSeqNum(); + + String topic = StringUtils.isEmpty(message.getTopic()) ? event.getSubject() : message.getTopic(); + + String username = StringUtils.isEmpty(header.getUsername()) ? event.getExtension(ProtocolKey.USERNAME).toString() : header.getUsername(); + String passwd = StringUtils.isEmpty(header.getPassword()) ? event.getExtension(ProtocolKey.PASSWD).toString() : header.getPassword(); + String ttl = StringUtils.isEmpty(message.getTtl()) ? event.getExtension(ProtocolKey.TTL).toString() : message.getTtl(); + + String producerGroup = StringUtils.isEmpty(message.getProducerGroup()) + ? event.getExtension(ProtocolKey.PRODUCERGROUP).toString() : message.getProducerGroup(); + + CloudEventBuilder eventBuilder; + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + eventBuilder = CloudEventBuilder.v1(event); + } else { + eventBuilder = CloudEventBuilder.v03(event); + } + + eventBuilder.withSubject(topic) + .withExtension(ProtocolKey.ENV, env) + .withExtension(ProtocolKey.IDC, idc) + .withExtension(ProtocolKey.IP, ip) + .withExtension(ProtocolKey.PID, pid) + .withExtension(ProtocolKey.SYS, sys) + .withExtension(ProtocolKey.USERNAME, username) + .withExtension(ProtocolKey.PASSWD, passwd) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(ProtocolKey.SEQ_NUM, seqNum) + .withExtension(ProtocolKey.UNIQUE_ID, uniqueId) + .withExtension(ProtocolKey.PRODUCERGROUP, producerGroup) + .withExtension(ProtocolKey.TTL, ttl); + + message.getPropertiesMap().forEach((k, v) -> eventBuilder.withExtension(k, v)); + + return eventBuilder.build(); + } + + public static SimpleMessageWrapper buildSimpleMessage(CloudEvent cloudEvent) { + String env = cloudEvent.getExtension(ProtocolKey.ENV) == null ? "env" : cloudEvent.getExtension(ProtocolKey.ENV).toString(); + String idc = cloudEvent.getExtension(ProtocolKey.IDC) == null ? "idc" : cloudEvent.getExtension(ProtocolKey.IDC).toString(); + String ip = cloudEvent.getExtension(ProtocolKey.IP) == null ? "127.0.0.1" : cloudEvent.getExtension(ProtocolKey.IP).toString(); + String pid = cloudEvent.getExtension(ProtocolKey.PID) == null ? "123" : cloudEvent.getExtension(ProtocolKey.PID).toString(); + String sys = cloudEvent.getExtension(ProtocolKey.SYS) == null ? "sys123" : cloudEvent.getExtension(ProtocolKey.SYS).toString(); + String userName = cloudEvent.getExtension(ProtocolKey.USERNAME) == null ? "user" : cloudEvent.getExtension(ProtocolKey.USERNAME).toString(); + String passwd = cloudEvent.getExtension(ProtocolKey.PASSWD) == null ? "pass" : cloudEvent.getExtension(ProtocolKey.PASSWD).toString(); + String language = cloudEvent.getExtension(ProtocolKey.LANGUAGE) == null ? "JAVA" : cloudEvent.getExtension(ProtocolKey.LANGUAGE).toString(); + String protocol = cloudEvent.getExtension(ProtocolKey.PROTOCOL_TYPE) == null ? "protocol" : + cloudEvent.getExtension(ProtocolKey.PROTOCOL_TYPE).toString(); + String protocolDesc = cloudEvent.getExtension(ProtocolKey.PROTOCOL_DESC) == null ? "protocolDesc" : + cloudEvent.getExtension(ProtocolKey.PROTOCOL_DESC).toString(); + String protocolVersion = cloudEvent.getExtension(ProtocolKey.PROTOCOL_VERSION) == null ? "1.0" : + cloudEvent.getExtension(ProtocolKey.PROTOCOL_VERSION).toString(); + String seqNum = cloudEvent.getExtension(ProtocolKey.SEQ_NUM) == null ? "" : cloudEvent.getExtension(ProtocolKey.SEQ_NUM).toString(); + String uniqueId = cloudEvent.getExtension(ProtocolKey.UNIQUE_ID) == null ? "" : cloudEvent.getExtension(ProtocolKey.UNIQUE_ID).toString(); + String producerGroup = cloudEvent.getExtension(ProtocolKey.PRODUCERGROUP) == null ? "producerGroup" : + cloudEvent.getExtension(ProtocolKey.PRODUCERGROUP).toString(); + String ttl = cloudEvent.getExtension(ProtocolKey.TTL) == null ? "3000" : cloudEvent.getExtension(ProtocolKey.TTL).toString(); + + RequestHeader header = RequestHeader.newBuilder() + .setEnv(env).setIdc(idc) + .setIp(ip).setPid(pid) + .setSys(sys).setUsername(userName).setPassword(passwd) + .setLanguage(language).setProtocolType(protocol) + .setProtocolDesc(protocolDesc).setProtocolVersion(protocolVersion) + .build(); + + String contentType = cloudEvent.getDataContentType(); + EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(contentType); + + SimpleMessage.Builder messageBuilder = SimpleMessage.newBuilder() + .setHeader(header) + .setContent(new String(eventFormat.serialize(cloudEvent), StandardCharsets.UTF_8)) + .setProducerGroup(producerGroup) + .setSeqNum(seqNum) + .setUniqueId(uniqueId) + .setTopic(cloudEvent.getSubject()) + .setTtl(ttl) + .putProperties(ProtocolKey.CONTENT_TYPE, contentType); + + for (String key : cloudEvent.getExtensionNames()) { + messageBuilder.putProperties(key, cloudEvent.getExtension(key).toString()); + } + + SimpleMessage simpleMessage = messageBuilder.build(); + + return new SimpleMessageWrapper(simpleMessage); + } + + public static List buildBatchEvents(BatchMessage batchMessage) { + List cloudEvents = new ArrayList<>(); + + RequestHeader header = batchMessage.getHeader(); + + for (BatchMessage.MessageItem item : batchMessage.getMessageItemList()) { + String cloudEventJson = item.getContent(); + + String contentType = item.getPropertiesOrDefault(ProtocolKey.CONTENT_TYPE, "application/cloudevents+json"); + EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(contentType); + CloudEvent event = eventFormat.deserialize(cloudEventJson.getBytes(StandardCharsets.UTF_8)); + + String env = StringUtils.isEmpty(header.getEnv()) ? event.getExtension(ProtocolKey.ENV).toString() : header.getEnv(); + String idc = StringUtils.isEmpty(header.getIdc()) ? event.getExtension(ProtocolKey.IDC).toString() : header.getIdc(); + String ip = StringUtils.isEmpty(header.getIp()) ? event.getExtension(ProtocolKey.IP).toString() : header.getIp(); + String pid = StringUtils.isEmpty(header.getPid()) ? event.getExtension(ProtocolKey.PID).toString() : header.getPid(); + String sys = StringUtils.isEmpty(header.getSys()) ? event.getExtension(ProtocolKey.SYS).toString() : header.getSys(); + + String language = StringUtils.isEmpty(header.getLanguage()) + ? event.getExtension(ProtocolKey.LANGUAGE).toString() : header.getLanguage(); + + String protocolType = StringUtils.isEmpty(header.getProtocolType()) + ? event.getExtension(ProtocolKey.PROTOCOL_TYPE).toString() : header.getProtocolType(); + + String protocolDesc = StringUtils.isEmpty(header.getProtocolDesc()) + ? event.getExtension(ProtocolKey.PROTOCOL_DESC).toString() : header.getProtocolDesc(); + + String protocolVersion = StringUtils.isEmpty(header.getProtocolVersion()) + ? event.getExtension(ProtocolKey.PROTOCOL_VERSION).toString() : header.getProtocolVersion(); + + String username = StringUtils.isEmpty(header.getUsername()) ? event.getExtension(ProtocolKey.USERNAME).toString() : header.getUsername(); + String passwd = StringUtils.isEmpty(header.getPassword()) ? event.getExtension(ProtocolKey.PASSWD).toString() : header.getPassword(); + + String seqNum = StringUtils.isEmpty(item.getSeqNum()) ? event.getExtension(ProtocolKey.SEQ_NUM).toString() : item.getSeqNum(); + String uniqueId = StringUtils.isEmpty(item.getUniqueId()) ? event.getExtension(ProtocolKey.UNIQUE_ID).toString() : item.getUniqueId(); + + String topic = StringUtils.isEmpty(batchMessage.getTopic()) ? event.getSubject() : batchMessage.getTopic(); + + String producerGroup = StringUtils.isEmpty(batchMessage.getProducerGroup()) + ? event.getExtension(ProtocolKey.PRODUCERGROUP).toString() : batchMessage.getProducerGroup(); + String ttl = StringUtils.isEmpty(item.getTtl()) ? event.getExtension(ProtocolKey.TTL).toString() : item.getTtl(); + + CloudEventBuilder eventBuilder; + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + eventBuilder = CloudEventBuilder.v1(event); + } else { + eventBuilder = CloudEventBuilder.v03(event); + } + + eventBuilder.withSubject(topic) + .withExtension(ProtocolKey.ENV, env) + .withExtension(ProtocolKey.IDC, idc) + .withExtension(ProtocolKey.IP, ip) + .withExtension(ProtocolKey.PID, pid) + .withExtension(ProtocolKey.SYS, sys) + .withExtension(ProtocolKey.USERNAME, username) + .withExtension(ProtocolKey.PASSWD, passwd) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(ProtocolKey.SEQ_NUM, seqNum) + .withExtension(ProtocolKey.UNIQUE_ID, uniqueId) + .withExtension(ProtocolKey.PRODUCERGROUP, producerGroup) + .withExtension(ProtocolKey.TTL, ttl); + + item.getPropertiesMap().forEach((k, v) -> eventBuilder.withExtension(k, v)); + + cloudEvents.add(eventBuilder.build()); + } + return cloudEvents; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageBatchProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageBatchProtocolResolver.java new file mode 100644 index 0000000000..d27fdcdb1c --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageBatchProtocolResolver.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.cloudevents.resolver.http; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import io.cloudevents.CloudEvent; + +public class SendMessageBatchProtocolResolver { + public static CloudEvent buildEvent(Header header, Body body) { + return null; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageBatchV2ProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageBatchV2ProtocolResolver.java new file mode 100644 index 0000000000..095095f3fe --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageBatchV2ProtocolResolver.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.cloudevents.resolver.http; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchV2RequestBody; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchV2RequestHeader; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +public class SendMessageBatchV2ProtocolResolver { + public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHandleException { + try { + SendMessageBatchV2RequestHeader sendMessageBatchV2RequestHeader = (SendMessageBatchV2RequestHeader) header; + SendMessageBatchV2RequestBody sendMessageBatchV2RequestBody = (SendMessageBatchV2RequestBody) body; + + String protocolType = sendMessageBatchV2RequestHeader.getProtocolType(); + String protocolDesc = sendMessageBatchV2RequestHeader.getProtocolDesc(); + String protocolVersion = sendMessageBatchV2RequestHeader.getProtocolVersion(); + + String code = sendMessageBatchV2RequestHeader.getCode(); + String env = sendMessageBatchV2RequestHeader.getEnv(); + String idc = sendMessageBatchV2RequestHeader.getIdc(); + String ip = sendMessageBatchV2RequestHeader.getIp(); + String pid = sendMessageBatchV2RequestHeader.getPid(); + String sys = sendMessageBatchV2RequestHeader.getSys(); + String username = sendMessageBatchV2RequestHeader.getUsername(); + String passwd = sendMessageBatchV2RequestHeader.getPasswd(); + ProtocolVersion version = sendMessageBatchV2RequestHeader.getVersion(); + String language = sendMessageBatchV2RequestHeader.getLanguage(); + + String producerGroup = sendMessageBatchV2RequestBody.getProducerGroup(); + String content = sendMessageBatchV2RequestBody.getMsg(); + + CloudEvent event = null; + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + event = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(content.getBytes(StandardCharsets.UTF_8)); + event = CloudEventBuilder.from(event) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageBatchV2RequestBody.PRODUCERGROUP, producerGroup) + .build(); + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + event = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(content.getBytes(StandardCharsets.UTF_8)); + event = CloudEventBuilder.from(event) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageBatchV2RequestBody.PRODUCERGROUP, producerGroup) + .build(); + } + return event; + } catch (Exception e) { + throw new ProtocolHandleException(e.getMessage(), e.getCause()); + } + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageRequestProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageRequestProtocolResolver.java new file mode 100644 index 0000000000..8bfde60d32 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/http/SendMessageRequestProtocolResolver.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.cloudevents.resolver.http; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageRequestHeader; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +public class SendMessageRequestProtocolResolver { + + public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHandleException { + try { + SendMessageRequestHeader sendMessageRequestHeader = (SendMessageRequestHeader) header; + SendMessageRequestBody sendMessageRequestBody = (SendMessageRequestBody) body; + + String protocolType = sendMessageRequestHeader.getProtocolType(); + String protocolDesc = sendMessageRequestHeader.getProtocolDesc(); + String protocolVersion = sendMessageRequestHeader.getProtocolVersion(); + + String code = sendMessageRequestHeader.getCode(); + String env = sendMessageRequestHeader.getEnv(); + String idc = sendMessageRequestHeader.getIdc(); + String ip = sendMessageRequestHeader.getIp(); + String pid = sendMessageRequestHeader.getPid(); + String sys = sendMessageRequestHeader.getSys(); + String username = sendMessageRequestHeader.getUsername(); + String passwd = sendMessageRequestHeader.getPasswd(); + ProtocolVersion version = sendMessageRequestHeader.getVersion(); + String language = sendMessageRequestHeader.getLanguage(); + + String producerGroup = sendMessageRequestBody.getProducerGroup(); + String content = sendMessageRequestBody.getContent(); + + CloudEvent event = null; + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + event = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(content.getBytes(StandardCharsets.UTF_8)); + event = CloudEventBuilder.v1(event) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageRequestBody.PRODUCERGROUP, producerGroup) + .build(); + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + event = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(content.getBytes(StandardCharsets.UTF_8)); + event = CloudEventBuilder.v03(event) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageRequestBody.PRODUCERGROUP, producerGroup) + .build(); + } + return event; + } catch (Exception e) { + throw new ProtocolHandleException(e.getMessage(), e.getCause()); + } + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/tcp/TcpMessageProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/tcp/TcpMessageProtocolResolver.java new file mode 100644 index 0000000000..82b338882d --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/tcp/TcpMessageProtocolResolver.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.cloudevents.resolver.tcp; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; +import org.apache.eventmesh.protocol.cloudevents.CloudEventsProtocolConstant; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +import com.google.common.base.Preconditions; + +public class TcpMessageProtocolResolver { + + public static CloudEvent buildEvent(Header header, String cloudEventJson) + throws ProtocolHandleException { + CloudEventBuilder cloudEventBuilder; + + String protocolType = header.getProperty(Constants.PROTOCOL_TYPE).toString(); + String protocolVersion = header.getProperty(Constants.PROTOCOL_VERSION).toString(); + String protocolDesc = header.getProperty(Constants.PROTOCOL_DESC).toString(); + + if (StringUtils.isBlank(protocolType) + || StringUtils.isBlank(protocolVersion) + || StringUtils.isBlank(protocolDesc)) { + throw new ProtocolHandleException( + String.format("invalid protocol params protocolType %s|protocolVersion %s|protocolDesc %s", + protocolType, protocolVersion, protocolDesc)); + } + + if (!StringUtils.equals(CloudEventsProtocolConstant.PROTOCOL_NAME, protocolType)) { + throw new ProtocolHandleException(String.format("Unsupported protocolType: %s", protocolType)); + } + + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + // todo:resolve different format + EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + Preconditions + .checkNotNull(eventFormat, String.format("EventFormat: %s is not supported", JsonFormat.CONTENT_TYPE)); + CloudEvent event = eventFormat.deserialize(cloudEventJson.getBytes(StandardCharsets.UTF_8)); + cloudEventBuilder = CloudEventBuilder.v1(event); + for (String propKey : header.getProperties().keySet()) { + cloudEventBuilder.withExtension(propKey, header.getProperty(propKey).toString()); + } + + return cloudEventBuilder.build(); + + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + // todo:resolve different format + CloudEvent event = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(cloudEventJson.getBytes(StandardCharsets.UTF_8)); + cloudEventBuilder = CloudEventBuilder.v03(event); + + for (String propKey : header.getProperties().keySet()) { + cloudEventBuilder.withExtension(propKey, header.getProperty(propKey).toString()); + } + + return cloudEventBuilder.build(); + } else { + throw new ProtocolHandleException(String.format("Unsupported protocolVersion: %s", protocolVersion)); + } + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor new file mode 100644 index 0000000000..e38fb694c9 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cloudevents=org.apache.eventmesh.protocol.cloudevents.CloudEventsProtocolAdaptor +webhookProtocolAdaptor=org.apache.eventmesh.protocol.cloudevents.WebHookProtocolAdaptor \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-grpc/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/build.gradle new file mode 100644 index 0000000000..72c17de017 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/build.gradle @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'java' + id 'com.google.protobuf' version '0.8.17' +} + +repositories { + mavenCentral() +} + +def grpcVersion = '1.17.1' // CURRENT_GRPC_VERSION +def protobufVersion = '3.5.1' +def protocVersion = protobufVersion + +dependencies { + implementation "io.grpc:grpc-protobuf:${grpcVersion}" + implementation "io.grpc:grpc-stub:${grpcVersion}" + implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}" + implementation "javax.annotation:javax.annotation-api:1.3.2" + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' +} + +protobuf { + protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" } + plugins { + grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } + } + generateProtoTasks { + all()*.plugins { + grpc {} + } + } +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-client.proto b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-client.proto new file mode 100644 index 0000000000..f5125a9e4e --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-client.proto @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; + +package eventmesh.common.protocol.grpc; + +option java_multiple_files = true; +option java_package = "org.apache.eventmesh.common.protocol.grpc.protos"; +option java_outer_classname = "EventmeshGrpc"; + +message RequestHeader { + string env = 1; + string region = 2; + string idc = 3; + string ip = 4; + string pid = 5; + string sys = 6; + string username = 7; + string password = 8; + string language = 9; + string protocolType = 10; + string protocolVersion = 11; + string protocolDesc = 12; +} + +message SimpleMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + string content = 4; + string ttl = 5; + string uniqueId = 6; + string seqNum = 7; + string tag = 8; + map properties = 9; +} + +message BatchMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + + message MessageItem { + string content = 1; + string ttl = 2; + string uniqueId = 3; + string seqNum = 4; + string tag = 5; + map properties = 6; + } + + repeated MessageItem messageItem = 4; +} + +message Response { + string respCode = 1; + string respMsg = 2; + string respTime = 3; +} + +message Subscription { + RequestHeader header = 1; + string consumerGroup = 2; + + message SubscriptionItem { + enum SubscriptionMode { + CLUSTERING = 0; + BROADCASTING = 1; + } + + enum SubscriptionType { + ASYNC = 0; + SYNC = 1; + } + + string topic = 1; + SubscriptionMode mode = 2; + SubscriptionType type = 3; + } + + repeated SubscriptionItem subscriptionItems = 3; + string url = 4; + + message Reply { + string producerGroup = 1; + string topic = 2; + string content = 3; + string ttl = 4; + string uniqueId = 5; + string seqNum = 6; + string tag = 7; + map properties = 8; + } + + Reply reply = 5; +} + +message Heartbeat { + enum ClientType { + PUB = 0; + SUB = 1; + } + + RequestHeader header = 1; + ClientType clientType = 2; + string producerGroup = 3; + string consumerGroup = 4; + + message HeartbeatItem { + string topic = 1; + string url = 2; + } + + repeated HeartbeatItem heartbeatItems = 5; +} + +service PublisherService { + // Async event publish + rpc publish(SimpleMessage) returns (Response); + + // Sync event publish + rpc requestReply(SimpleMessage) returns (SimpleMessage); + + // Async batch event publish + rpc batchPublish(BatchMessage) returns (Response); +} + +service ConsumerService { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + rpc subscribe(Subscription) returns (Response); + + // The subscribed event will be delivered through stream of Message + rpc subscribeStream(stream Subscription) returns (stream SimpleMessage); + + rpc unsubscribe(Subscription) returns (Response); +} + +service HeartbeatService { + rpc heartbeat(Heartbeat) returns (Response); +} \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-http/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-http/build.gradle new file mode 100644 index 0000000000..9f3b904951 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-http/build.gradle @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + implementation "io.cloudevents:cloudevents-core" + implementation "com.google.guava:guava" + implementation "io.cloudevents:cloudevents-json-jackson" + implementation "io.grpc:grpc-protobuf:1.17.1" +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-http/gradle.properties b/eventmesh-protocol-plugin/eventmesh-protocol-http/gradle.properties new file mode 100644 index 0000000000..df907207e2 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-http/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=protocol +pluginName=http \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/HttpProtocolAdaptor.java b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/HttpProtocolAdaptor.java new file mode 100644 index 0000000000..ad7ff7f5d7 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/HttpProtocolAdaptor.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.http; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; +import org.apache.eventmesh.protocol.http.resolver.HttpRequestProtocolResolver; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import io.cloudevents.CloudEvent; + +import com.fasterxml.jackson.core.type.TypeReference; + +/** + * CloudEvents protocol adaptor, used to transform CloudEvents message to CloudEvents message. + * + * @since 1.3.0 + */ +public class HttpProtocolAdaptor + implements ProtocolAdaptor { + + @Override + public CloudEvent toCloudEvent(ProtocolTransportObject protocolTransportObject) throws ProtocolHandleException { + + if (protocolTransportObject instanceof HttpEventWrapper) { + HttpEventWrapper httpEventWrapper = (HttpEventWrapper) protocolTransportObject; + String requestURI = httpEventWrapper.getRequestURI(); + + return deserializeProtocol(requestURI, httpEventWrapper); + + } else { + throw new ProtocolHandleException(String.format("protocol class: %s", protocolTransportObject.getClass())); + } + } + + private CloudEvent deserializeProtocol(String requestURI, HttpEventWrapper httpEventWrapper) throws ProtocolHandleException { + + if (requestURI.startsWith(RequestURI.PUBLISH.getRequestURI()) || requestURI.startsWith(RequestURI.PUBLISH_BRIDGE.getRequestURI())) { + return HttpRequestProtocolResolver.buildEvent(httpEventWrapper); + } else { + throw new ProtocolHandleException(String.format("unsupported requestURI: %s", requestURI)); + } + + } + + @Override + public List toBatchCloudEvent(ProtocolTransportObject protocol) + throws ProtocolHandleException { + return null; + } + + @Override + public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException { + String protocolDesc = cloudEvent.getExtension(Constants.PROTOCOL_DESC).toString(); + HttpEventWrapper httpEventWrapper = new HttpEventWrapper(); + Map sysHeaderMap = new HashMap<>(); + // ce attributes + Set attributeNames = cloudEvent.getAttributeNames(); + // ce extensions + Set extensionNames = cloudEvent.getExtensionNames(); + for (String attributeName : attributeNames) { + sysHeaderMap.put(attributeName, cloudEvent.getAttribute(attributeName)); + } + for (String extensionName : extensionNames) { + sysHeaderMap.put(extensionName, cloudEvent.getExtension(extensionName)); + } + httpEventWrapper.setSysHeaderMap(sysHeaderMap); + // ce data + Map dataContentMap = JsonUtils.deserialize(new String(cloudEvent.getData().toBytes()), + new TypeReference>() {}); + + String requestHeader = JsonUtils.serialize(dataContentMap.get("headers")); + byte[] requestBody = JsonUtils.serialize(dataContentMap.get("body")).getBytes(StandardCharsets.UTF_8); + Map requestHeaderMap = JsonUtils.deserialize(requestHeader, new TypeReference>() { + }); + String requestURI = dataContentMap.get("path").toString(); + String httpMethod = dataContentMap.get("method").toString(); + + httpEventWrapper.setHeaderMap(requestHeaderMap); + httpEventWrapper.setBody(requestBody); + httpEventWrapper.setRequestURI(requestURI); + httpEventWrapper.setHttpMethod(httpMethod); + return httpEventWrapper; + + } + + @Override + public String getProtocolType() { + return HttpProtocolConstant.PROTOCOL_NAME; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/HttpProtocolConstant.java b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/HttpProtocolConstant.java new file mode 100644 index 0000000000..0e70bd7d5a --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/HttpProtocolConstant.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.http; + +public enum HttpProtocolConstant { + ; + public static final String PROTOCOL_NAME = "http"; + + public static final String DATA_CONTENT_TYPE = "application/json"; + + public static final String CONSTANTS_DEFAULT_SOURCE = "/"; + public static final String CONSTANTS_DEFAULT_TYPE = "http_request"; + public static final String CONSTANTS_DEFAULT_SUBJECT = "TOPIC-HTTP-REQUEST"; + + public static final String CONSTANTS_KEY_ID = "id"; + public static final String CONSTANTS_KEY_SOURCE = "source"; + public static final String CONSTANTS_KEY_TYPE = "type"; + public static final String CONSTANTS_KEY_SUBJECT = "subject"; + public static final String CONSTANTS_KEY_HEADERS = "headers"; + public static final String CONSTANTS_KEY_BODY = "body"; + public static final String CONSTANTS_KEY_PATH = "path"; + public static final String CONSTANTS_KEY_METHOD = "method"; +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/resolver/HttpRequestProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/resolver/HttpRequestProtocolResolver.java new file mode 100644 index 0000000000..d3b5b547fb --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/java/org/apache/eventmesh/protocol/http/resolver/HttpRequestProtocolResolver.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.http.resolver; + +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; +import org.apache.eventmesh.protocol.http.HttpProtocolConstant; + +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.v1.CloudEventBuilder; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class HttpRequestProtocolResolver { + + public static CloudEvent buildEvent(HttpEventWrapper httpEventWrapper) throws ProtocolHandleException { + + try { + CloudEventBuilder builder = new CloudEventBuilder(); + + Map requestHeaderMap = httpEventWrapper.getHeaderMap(); + + Map sysHeaderMap = httpEventWrapper.getSysHeaderMap(); + + String id = sysHeaderMap.getOrDefault(HttpProtocolConstant.CONSTANTS_KEY_ID, UUID.randomUUID()).toString(); + + String source = + sysHeaderMap.getOrDefault(HttpProtocolConstant.CONSTANTS_KEY_SOURCE, HttpProtocolConstant.CONSTANTS_DEFAULT_SOURCE).toString(); + + String type = sysHeaderMap.getOrDefault(HttpProtocolConstant.CONSTANTS_KEY_TYPE, HttpProtocolConstant.CONSTANTS_DEFAULT_TYPE).toString(); + + String subject = + sysHeaderMap.getOrDefault(HttpProtocolConstant.CONSTANTS_KEY_SUBJECT, HttpProtocolConstant.CONSTANTS_DEFAULT_SUBJECT).toString(); + + // with attributes + builder.withId(id) + .withType(type) + .withSource(URI.create(HttpProtocolConstant.CONSTANTS_KEY_SOURCE + ":" + source)) + .withSubject(subject) + .withDataContentType(HttpProtocolConstant.DATA_CONTENT_TYPE); + + // with extensions + for (String extensionKey : sysHeaderMap.keySet()) { + if (StringUtils.equals(HttpProtocolConstant.CONSTANTS_KEY_ID, extensionKey) + || StringUtils.equals(HttpProtocolConstant.CONSTANTS_KEY_SOURCE, extensionKey) + || StringUtils.equals(HttpProtocolConstant.CONSTANTS_KEY_TYPE, extensionKey) + || StringUtils.equals(HttpProtocolConstant.CONSTANTS_KEY_SUBJECT, extensionKey)) { + continue; + } + String lowerExtensionKey = extensionKey.toLowerCase(); + builder.withExtension(lowerExtensionKey, sysHeaderMap.get(extensionKey).toString()); + } + + byte[] requestBody = httpEventWrapper.getBody(); + + Map requestBodyMap = JsonUtils.deserialize(new String(requestBody), new TypeReference>() { + }); + + String requestURI = httpEventWrapper.getRequestURI(); + + Map data = new HashMap<>(); + data.put(HttpProtocolConstant.CONSTANTS_KEY_HEADERS, requestHeaderMap); + data.put(HttpProtocolConstant.CONSTANTS_KEY_BODY, requestBodyMap); + data.put(HttpProtocolConstant.CONSTANTS_KEY_PATH, requestURI); + data.put(HttpProtocolConstant.CONSTANTS_KEY_METHOD, httpEventWrapper.getHttpMethod()); + // with data + builder = builder.withData(JsonUtils.serialize(data).getBytes(StandardCharsets.UTF_8)); + return builder.build(); + } catch (Exception e) { + throw new ProtocolHandleException(e.getMessage(), e.getCause()); + } + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor new file mode 100644 index 0000000000..bb7d76b8df --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +http=org.apache.eventmesh.protocol.http.HttpProtocolAdaptor \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-http/src/test/java/org/apache/eventmesh/protocol/http/HttpProtocolAdaptorTest.java b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/test/java/org/apache/eventmesh/protocol/http/HttpProtocolAdaptorTest.java new file mode 100644 index 0000000000..c7ead7d312 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-http/src/test/java/org/apache/eventmesh/protocol/http/HttpProtocolAdaptorTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.http; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; + +import org.junit.Assert; +import org.junit.Test; + +public class HttpProtocolAdaptorTest { + + @Test + public void loadPlugin() { + ProtocolAdaptor protocolAdaptor = + ProtocolPluginFactory.getProtocolAdaptor(HttpProtocolConstant.PROTOCOL_NAME); + + Assert.assertNotNull(protocolAdaptor); + Assert.assertEquals( + HttpProtocolConstant.PROTOCOL_NAME, protocolAdaptor.getProtocolType()); + Assert.assertEquals(HttpProtocolAdaptor.class, protocolAdaptor.getClass()); + } +} \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/build.gradle new file mode 100644 index 0000000000..b20c6837a3 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/build.gradle @@ -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. + */ + +dependencies { + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + implementation "io.cloudevents:cloudevents-core" + implementation "io.grpc:grpc-protobuf:1.17.1" + + testImplementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + testImplementation "io.cloudevents:cloudevents-core" +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/gradle.properties b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/gradle.properties new file mode 100644 index 0000000000..07476be28a --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=protocol +pluginName=eventmeshmessage \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolAdaptor.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolAdaptor.java new file mode 100644 index 0000000000..df60c39604 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolAdaptor.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.common.BatchMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; +import org.apache.eventmesh.protocol.meshmessage.resolver.grpc.GrpcMessageProtocolResolver; +import org.apache.eventmesh.protocol.meshmessage.resolver.http.SendMessageBatchProtocolResolver; +import org.apache.eventmesh.protocol.meshmessage.resolver.http.SendMessageBatchV2ProtocolResolver; +import org.apache.eventmesh.protocol.meshmessage.resolver.http.SendMessageRequestProtocolResolver; +import org.apache.eventmesh.protocol.meshmessage.resolver.tcp.TcpMessageProtocolResolver; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.cloudevents.CloudEvent; + +public class MeshMessageProtocolAdaptor implements ProtocolAdaptor { + + @Override + public CloudEvent toCloudEvent(ProtocolTransportObject protocol) throws ProtocolHandleException { + if (protocol instanceof Package) { + Package tcpPackage = (Package) protocol; + Header header = tcpPackage.getHeader(); + String bodyJson = (String) tcpPackage.getBody(); + + return deserializeTcpProtocol(header, bodyJson); + + } else if (protocol instanceof HttpCommand) { + org.apache.eventmesh.common.protocol.http.header.Header header = ((HttpCommand) protocol).getHeader(); + Body body = ((HttpCommand) protocol).getBody(); + String requestCode = ((HttpCommand) protocol).getRequestCode(); + + return deserializeHttpProtocol(requestCode, header, body); + } else if (protocol instanceof SimpleMessageWrapper) { + SimpleMessage message = ((SimpleMessageWrapper) protocol).getMessage(); + return deserializeGrpcProtocol(message); + } else { + throw new ProtocolHandleException(String.format("protocol class: %s", protocol.getClass())); + } + } + + private CloudEvent deserializeGrpcProtocol(SimpleMessage message) + throws ProtocolHandleException { + return GrpcMessageProtocolResolver.buildEvent(message); + } + + private CloudEvent deserializeTcpProtocol(Header header, String bodyJson) throws ProtocolHandleException { + return TcpMessageProtocolResolver.buildEvent(header, JsonUtils.deserialize(bodyJson, EventMeshMessage.class)); + } + + private CloudEvent deserializeHttpProtocol(String requestCode, + org.apache.eventmesh.common.protocol.http.header.Header header, + Body body) throws ProtocolHandleException { + + if (String.valueOf(RequestCode.MSG_BATCH_SEND.getRequestCode()).equals(requestCode)) { + return SendMessageBatchProtocolResolver.buildEvent(header, body); + } else if (String.valueOf(RequestCode.MSG_BATCH_SEND_V2.getRequestCode()).equals(requestCode)) { + return SendMessageBatchV2ProtocolResolver.buildEvent(header, body); + } else if (String.valueOf(RequestCode.MSG_SEND_SYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestProtocolResolver.buildEvent(header, body); + } else if (String.valueOf(RequestCode.MSG_SEND_ASYNC.getRequestCode()).equals(requestCode)) { + return SendMessageRequestProtocolResolver.buildEvent(header, body); + } else { + throw new ProtocolHandleException(String.format("unsupported requestCode: %s", requestCode)); + } + + } + + @Override + public List toBatchCloudEvent(ProtocolTransportObject protocol) throws ProtocolHandleException { + if (protocol instanceof BatchMessageWrapper) { + BatchMessage batchMessage = ((BatchMessageWrapper) protocol).getMessage(); + return GrpcMessageProtocolResolver.buildBatchEvents(batchMessage); + } else { + throw new ProtocolHandleException(String.format("protocol class: %s", protocol.getClass())); + } + } + + @Override + public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException { + String protocolDesc = cloudEvent.getExtension(Constants.PROTOCOL_DESC).toString(); + + if (StringUtils.equals("http", protocolDesc)) { + HttpCommand httpCommand = new HttpCommand(); + Body body = new Body() { + final Map map = new HashMap<>(); + + @Override + public Map toMap() { + map.put("content", new String(cloudEvent.getData().toBytes(), StandardCharsets.UTF_8)); + return map; + } + }; + body.toMap(); + httpCommand.setBody(body); + return httpCommand; + } else if (StringUtils.equals("grpc", protocolDesc)) { + return GrpcMessageProtocolResolver.buildSimpleMessage(cloudEvent); + } else if (StringUtils.equals("tcp", protocolDesc)) { + return TcpMessageProtocolResolver.buildEventMeshMessage(cloudEvent); + } else { + throw new ProtocolHandleException(String.format("Unsupported protocolDesc: %s", protocolDesc)); + } + } + + @Override + public String getProtocolType() { + return MeshMessageProtocolConstant.PROTOCOL_NAME; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolConstant.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolConstant.java new file mode 100644 index 0000000000..0a667f63f0 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolConstant.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage; + +public enum MeshMessageProtocolConstant { + ; + public static final String PROTOCOL_NAME = "eventmeshmessage"; +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/grpc/GrpcMessageProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/grpc/GrpcMessageProtocolResolver.java new file mode 100644 index 0000000000..47b4278ca7 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/grpc/GrpcMessageProtocolResolver.java @@ -0,0 +1,268 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage.resolver.grpc; + +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage.MessageItem; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class GrpcMessageProtocolResolver { + + public static CloudEvent buildEvent(SimpleMessage message) throws ProtocolHandleException { + try { + RequestHeader requestHeader = message.getHeader(); + + String protocolType = requestHeader.getProtocolType(); + String protocolDesc = requestHeader.getProtocolDesc(); + String protocolVersion = requestHeader.getProtocolVersion(); + + String env = requestHeader.getEnv(); + String idc = requestHeader.getIdc(); + String ip = requestHeader.getIp(); + String pid = requestHeader.getPid(); + String sys = requestHeader.getSys(); + String username = requestHeader.getUsername(); + String passwd = requestHeader.getPassword(); + String language = requestHeader.getLanguage(); + + String content = message.getContent(); + + CloudEvent event = null; + CloudEventBuilder cloudEventBuilder; + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v1(); + + cloudEventBuilder = cloudEventBuilder.withId(message.getSeqNum()) + .withSubject(message.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.ENV, env) + .withExtension(ProtocolKey.IDC, idc) + .withExtension(ProtocolKey.IP, ip) + .withExtension(ProtocolKey.PID, pid) + .withExtension(ProtocolKey.SYS, sys) + .withExtension(ProtocolKey.USERNAME, username) + .withExtension(ProtocolKey.PASSWD, passwd) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(ProtocolKey.SEQ_NUM, message.getSeqNum()) + .withExtension(ProtocolKey.UNIQUE_ID, message.getUniqueId()) + .withExtension(ProtocolKey.PRODUCERGROUP, message.getProducerGroup()) + .withExtension(ProtocolKey.TTL, message.getTtl()); + + for (Map.Entry entry : message.getPropertiesMap().entrySet()) { + cloudEventBuilder.withExtension(entry.getKey(), entry.getValue()); + } + if (StringUtils.isNotEmpty(message.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(ProtocolKey.TAG, message.getTag()); + } + event = cloudEventBuilder.build(); + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v03(); + cloudEventBuilder = cloudEventBuilder.withId(message.getSeqNum()) + .withSubject(message.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.ENV, env) + .withExtension(ProtocolKey.IDC, idc) + .withExtension(ProtocolKey.IP, ip) + .withExtension(ProtocolKey.PID, pid) + .withExtension(ProtocolKey.SYS, sys) + .withExtension(ProtocolKey.USERNAME, username) + .withExtension(ProtocolKey.PASSWD, passwd) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(ProtocolKey.SEQ_NUM, message.getSeqNum()) + .withExtension(ProtocolKey.UNIQUE_ID, message.getUniqueId()) + .withExtension(ProtocolKey.PRODUCERGROUP, message.getProducerGroup()) + .withExtension(ProtocolKey.TTL, message.getTtl()); + + for (Map.Entry entry : message.getPropertiesMap().entrySet()) { + cloudEventBuilder.withExtension(entry.getKey(), entry.getValue()); + } + if (StringUtils.isNotEmpty(message.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(ProtocolKey.TAG, message.getTag()); + } + event = cloudEventBuilder.build(); + } + return event; + } catch (Exception e) { + throw new ProtocolHandleException(e.getMessage(), e.getCause()); + } + } + + public static List buildBatchEvents(BatchMessage message) { + List events = new LinkedList<>(); + RequestHeader requestHeader = message.getHeader(); + + String protocolType = requestHeader.getProtocolType(); + String protocolDesc = requestHeader.getProtocolDesc(); + String protocolVersion = requestHeader.getProtocolVersion(); + + String env = requestHeader.getEnv(); + String idc = requestHeader.getIdc(); + String ip = requestHeader.getIp(); + String pid = requestHeader.getPid(); + String sys = requestHeader.getSys(); + String username = requestHeader.getUsername(); + String passwd = requestHeader.getPassword(); + String language = requestHeader.getLanguage(); + + for (MessageItem item : message.getMessageItemList()) { + String content = item.getContent(); + + CloudEvent event = null; + CloudEventBuilder cloudEventBuilder; + + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v1(); + + cloudEventBuilder = cloudEventBuilder.withId(item.getSeqNum()) + .withSubject(message.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.ENV, env) + .withExtension(ProtocolKey.IDC, idc) + .withExtension(ProtocolKey.IP, ip) + .withExtension(ProtocolKey.PID, pid) + .withExtension(ProtocolKey.SYS, sys) + .withExtension(ProtocolKey.USERNAME, username) + .withExtension(ProtocolKey.PASSWD, passwd) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(ProtocolKey.SEQ_NUM, item.getSeqNum()) + .withExtension(ProtocolKey.UNIQUE_ID, item.getUniqueId()) + .withExtension(ProtocolKey.PRODUCERGROUP, message.getProducerGroup()) + .withExtension(ProtocolKey.TTL, item.getTtl()); + + for (Map.Entry entry : item.getPropertiesMap().entrySet()) { + cloudEventBuilder.withExtension(entry.getKey(), entry.getValue()); + } + if (StringUtils.isNotEmpty(item.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(ProtocolKey.TAG, item.getTag()); + } + event = cloudEventBuilder.build(); + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v03(); + cloudEventBuilder = cloudEventBuilder.withId(item.getSeqNum()) + .withSubject(message.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.ENV, env) + .withExtension(ProtocolKey.IDC, idc) + .withExtension(ProtocolKey.IP, ip) + .withExtension(ProtocolKey.PID, pid) + .withExtension(ProtocolKey.SYS, sys) + .withExtension(ProtocolKey.USERNAME, username) + .withExtension(ProtocolKey.PASSWD, passwd) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(ProtocolKey.SEQ_NUM, item.getSeqNum()) + .withExtension(ProtocolKey.UNIQUE_ID, item.getUniqueId()) + .withExtension(ProtocolKey.PRODUCERGROUP, message.getProducerGroup()) + .withExtension(ProtocolKey.TTL, item.getTtl()); + + for (Map.Entry entry : item.getPropertiesMap().entrySet()) { + cloudEventBuilder.withExtension(entry.getKey(), entry.getValue()); + } + if (StringUtils.isNotEmpty(item.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(ProtocolKey.TAG, item.getTag()); + } + event = cloudEventBuilder.build(); + } + events.add(event); + } + + return events; + } + + public static SimpleMessageWrapper buildSimpleMessage(CloudEvent cloudEvent) { + String env = cloudEvent.getExtension(ProtocolKey.ENV) == null ? "env" : cloudEvent.getExtension(ProtocolKey.ENV).toString(); + String idc = cloudEvent.getExtension(ProtocolKey.IDC) == null ? "idc" : cloudEvent.getExtension(ProtocolKey.IDC).toString(); + String ip = cloudEvent.getExtension(ProtocolKey.IP) == null ? "ip" : cloudEvent.getExtension(ProtocolKey.IP).toString(); + String pid = cloudEvent.getExtension(ProtocolKey.PID) == null ? "33" : cloudEvent.getExtension(ProtocolKey.PID).toString(); + String sys = cloudEvent.getExtension(ProtocolKey.SYS) == null ? "sys" : cloudEvent.getExtension(ProtocolKey.SYS).toString(); + String userName = cloudEvent.getExtension(ProtocolKey.USERNAME) == null ? "user" : cloudEvent.getExtension(ProtocolKey.USERNAME).toString(); + String passwd = cloudEvent.getExtension(ProtocolKey.PASSWD) == null ? "pass" : cloudEvent.getExtension(ProtocolKey.PASSWD).toString(); + String language = cloudEvent.getExtension(ProtocolKey.LANGUAGE) == null ? "JAVA" : cloudEvent.getExtension(ProtocolKey.LANGUAGE).toString(); + String protocol = cloudEvent.getExtension(ProtocolKey.PROTOCOL_TYPE) == null ? "" : + cloudEvent.getExtension(ProtocolKey.PROTOCOL_TYPE).toString(); + String protocolDesc = cloudEvent.getExtension(ProtocolKey.PROTOCOL_DESC) == null ? "" : + cloudEvent.getExtension(ProtocolKey.PROTOCOL_DESC).toString(); + String protocolVersion = cloudEvent.getExtension(ProtocolKey.PROTOCOL_VERSION) == null ? "" : + cloudEvent.getExtension(ProtocolKey.PROTOCOL_VERSION).toString(); + String seqNum = cloudEvent.getExtension(ProtocolKey.SEQ_NUM) == null ? "" : cloudEvent.getExtension(ProtocolKey.SEQ_NUM).toString(); + String uniqueId = cloudEvent.getExtension(ProtocolKey.UNIQUE_ID) == null ? "" : cloudEvent.getExtension(ProtocolKey.UNIQUE_ID).toString(); + String producerGroup = cloudEvent.getExtension(ProtocolKey.PRODUCERGROUP) == null ? "" : + cloudEvent.getExtension(ProtocolKey.PRODUCERGROUP).toString(); + String ttl = cloudEvent.getExtension(ProtocolKey.TTL) == null ? "4000" : cloudEvent.getExtension(ProtocolKey.TTL).toString(); + + RequestHeader header = RequestHeader.newBuilder() + .setEnv(env).setIdc(idc) + .setIp(ip).setPid(pid) + .setSys(sys).setUsername(userName).setPassword(passwd) + .setLanguage(language).setProtocolType(protocol) + .setProtocolDesc(protocolDesc).setProtocolVersion(protocolVersion) + .build(); + + SimpleMessage.Builder messageBuilder = SimpleMessage.newBuilder() + .setHeader(header) + .setContent(new String(cloudEvent.getData().toBytes(), StandardCharsets.UTF_8)) + .setProducerGroup(producerGroup) + .setSeqNum(seqNum) + .setUniqueId(uniqueId) + .setTopic(cloudEvent.getSubject()) + .setTtl(ttl); + + for (String key : cloudEvent.getExtensionNames()) { + messageBuilder.putProperties(key, cloudEvent.getExtension(key).toString()); + } + + SimpleMessage simpleMessage = messageBuilder.build(); + + return new SimpleMessageWrapper(simpleMessage); + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageBatchProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageBatchProtocolResolver.java new file mode 100644 index 0000000000..e5762dc354 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageBatchProtocolResolver.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage.resolver.http; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.header.Header; + +import io.cloudevents.CloudEvent; + +public class SendMessageBatchProtocolResolver { + public static CloudEvent buildEvent(Header header, Body body) { + return null; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageBatchV2ProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageBatchV2ProtocolResolver.java new file mode 100644 index 0000000000..eefe660a37 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageBatchV2ProtocolResolver.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage.resolver.http; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchV2RequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchV2RequestHeader; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class SendMessageBatchV2ProtocolResolver { + public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHandleException { + try { + SendMessageBatchV2RequestHeader sendMessageBatchV2RequestHeader = (SendMessageBatchV2RequestHeader) header; + SendMessageBatchV2RequestBody sendMessageBatchV2RequestBody = (SendMessageBatchV2RequestBody) body; + + String protocolType = sendMessageBatchV2RequestHeader.getProtocolType(); + String protocolDesc = sendMessageBatchV2RequestHeader.getProtocolDesc(); + String protocolVersion = sendMessageBatchV2RequestHeader.getProtocolVersion(); + + String code = sendMessageBatchV2RequestHeader.getCode(); + String env = sendMessageBatchV2RequestHeader.getEnv(); + String idc = sendMessageBatchV2RequestHeader.getIdc(); + String ip = sendMessageBatchV2RequestHeader.getIp(); + String pid = sendMessageBatchV2RequestHeader.getPid(); + String sys = sendMessageBatchV2RequestHeader.getSys(); + String username = sendMessageBatchV2RequestHeader.getUsername(); + String passwd = sendMessageBatchV2RequestHeader.getPasswd(); + ProtocolVersion version = sendMessageBatchV2RequestHeader.getVersion(); + String language = sendMessageBatchV2RequestHeader.getLanguage(); + + String content = sendMessageBatchV2RequestBody.getMsg(); + + CloudEvent event = null; + CloudEventBuilder cloudEventBuilder; + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v1(); + + cloudEventBuilder = cloudEventBuilder.withId(sendMessageBatchV2RequestBody.getBizSeqNo()) + .withSubject(sendMessageBatchV2RequestBody.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageBatchV2RequestBody.BIZSEQNO, sendMessageBatchV2RequestBody.getBizSeqNo()) + .withExtension(SendMessageBatchV2RequestBody.PRODUCERGROUP, sendMessageBatchV2RequestBody.getProducerGroup()) + .withExtension(SendMessageBatchV2RequestBody.TTL, sendMessageBatchV2RequestBody.getTtl()); + if (StringUtils.isNotEmpty(sendMessageBatchV2RequestBody.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(SendMessageRequestBody.TAG, sendMessageBatchV2RequestBody.getTag()); + } + event = cloudEventBuilder.build(); + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v03(); + cloudEventBuilder = cloudEventBuilder.withId(sendMessageBatchV2RequestBody.getBizSeqNo()) + .withSubject(sendMessageBatchV2RequestBody.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageBatchV2RequestBody.BIZSEQNO, sendMessageBatchV2RequestBody.getBizSeqNo()) + .withExtension(SendMessageBatchV2RequestBody.PRODUCERGROUP, sendMessageBatchV2RequestBody.getProducerGroup()) + .withExtension(SendMessageBatchV2RequestBody.TTL, sendMessageBatchV2RequestBody.getTtl()); + if (StringUtils.isNotEmpty(sendMessageBatchV2RequestBody.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(SendMessageRequestBody.TAG, sendMessageBatchV2RequestBody.getTag()); + } + event = cloudEventBuilder.build(); + } + return event; + } catch (Exception e) { + throw new ProtocolHandleException(e.getMessage(), e.getCause()); + } + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageRequestProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageRequestProtocolResolver.java new file mode 100644 index 0000000000..215f2e38ce --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/http/SendMessageRequestProtocolResolver.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage.resolver.http; + +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageRequestHeader; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class SendMessageRequestProtocolResolver { + + public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHandleException { + try { + SendMessageRequestHeader sendMessageRequestHeader = (SendMessageRequestHeader) header; + SendMessageRequestBody sendMessageRequestBody = (SendMessageRequestBody) body; + + String protocolType = sendMessageRequestHeader.getProtocolType(); + String protocolDesc = sendMessageRequestHeader.getProtocolDesc(); + String protocolVersion = sendMessageRequestHeader.getProtocolVersion(); + + String code = sendMessageRequestHeader.getCode(); + String env = sendMessageRequestHeader.getEnv(); + String idc = sendMessageRequestHeader.getIdc(); + String ip = sendMessageRequestHeader.getIp(); + String pid = sendMessageRequestHeader.getPid(); + String sys = sendMessageRequestHeader.getSys(); + String username = sendMessageRequestHeader.getUsername(); + String passwd = sendMessageRequestHeader.getPasswd(); + ProtocolVersion version = sendMessageRequestHeader.getVersion(); + String language = sendMessageRequestHeader.getLanguage(); + + String content = sendMessageRequestBody.getContent(); + + CloudEvent event = null; + CloudEventBuilder cloudEventBuilder; + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v1(); + + cloudEventBuilder = cloudEventBuilder.withId(sendMessageRequestBody.getBizSeqNo()) + .withSubject(sendMessageRequestBody.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageRequestBody.BIZSEQNO, sendMessageRequestBody.getBizSeqNo()) + .withExtension(SendMessageRequestBody.UNIQUEID, sendMessageRequestBody.getUniqueId()) + .withExtension(SendMessageRequestBody.PRODUCERGROUP, + sendMessageRequestBody.getProducerGroup()) + .withExtension(SendMessageRequestBody.TTL, sendMessageRequestBody.getTtl()); + if (StringUtils.isNotEmpty(sendMessageRequestBody.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(SendMessageRequestBody.TAG, sendMessageRequestBody.getTag()); + } + if (sendMessageRequestBody.getExtFields() != null && sendMessageRequestBody.getExtFields().size() > 0) { + for (Map.Entry entry : sendMessageRequestBody.getExtFields().entrySet()) { + cloudEventBuilder = cloudEventBuilder.withExtension(entry.getKey(), entry.getValue()); + } + } + event = cloudEventBuilder.build(); + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v03(); + cloudEventBuilder = cloudEventBuilder.withId(sendMessageRequestBody.getBizSeqNo()) + .withSubject(sendMessageRequestBody.getTopic()) + .withType("eventmeshmessage") + .withSource(URI.create("/")) + .withData(content.getBytes(StandardCharsets.UTF_8)) + .withExtension(ProtocolKey.REQUEST_CODE, code) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP, ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID, pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, passwd) + .withExtension(ProtocolKey.VERSION, version.getVersion()) + .withExtension(ProtocolKey.LANGUAGE, language) + .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) + .withExtension(ProtocolKey.PROTOCOL_DESC, protocolDesc) + .withExtension(ProtocolKey.PROTOCOL_VERSION, protocolVersion) + .withExtension(SendMessageRequestBody.BIZSEQNO, sendMessageRequestBody.getBizSeqNo()) + .withExtension(SendMessageRequestBody.UNIQUEID, sendMessageRequestBody.getUniqueId()) + .withExtension(SendMessageRequestBody.PRODUCERGROUP, + sendMessageRequestBody.getProducerGroup()) + .withExtension(SendMessageRequestBody.TTL, sendMessageRequestBody.getTtl()); + if (StringUtils.isNotEmpty(sendMessageRequestBody.getTag())) { + cloudEventBuilder = cloudEventBuilder.withExtension(SendMessageRequestBody.TAG, sendMessageRequestBody.getTag()); + } + if (sendMessageRequestBody.getExtFields() != null && sendMessageRequestBody.getExtFields().size() > 0) { + for (Map.Entry entry : sendMessageRequestBody.getExtFields().entrySet()) { + cloudEventBuilder = cloudEventBuilder.withExtension(entry.getKey(), entry.getValue()); + } + } + event = cloudEventBuilder.build(); + } + return event; + } catch (Exception e) { + throw new ProtocolHandleException(e.getMessage(), e.getCause()); + } + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/tcp/TcpMessageProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/tcp/TcpMessageProtocolResolver.java new file mode 100644 index 0000000000..6e199cad9e --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/tcp/TcpMessageProtocolResolver.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage.resolver.tcp; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; +import org.apache.eventmesh.protocol.meshmessage.MeshMessageProtocolConstant; + +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class TcpMessageProtocolResolver { + + + public static CloudEvent buildEvent(Header header, EventMeshMessage message) throws ProtocolHandleException { + + CloudEventBuilder cloudEventBuilder; + + String protocolType = header.getProperty(Constants.PROTOCOL_TYPE).toString(); + String protocolVersion = header.getProperty(Constants.PROTOCOL_VERSION).toString(); + String protocolDesc = header.getProperty(Constants.PROTOCOL_DESC).toString(); + + if (StringUtils.isBlank(protocolType) + || StringUtils.isBlank(protocolVersion) + || StringUtils.isBlank(protocolDesc)) { + throw new ProtocolHandleException(String.format("invalid protocol params protocolType %s|protocolVersion %s|protocolDesc %s", + protocolType, protocolVersion, protocolDesc)); + } + + if (!StringUtils.equals(MeshMessageProtocolConstant.PROTOCOL_NAME, protocolType)) { + throw new ProtocolHandleException(String.format("Unsupported protocolType: %s", protocolType)); + } + + String topic = message.getTopic(); + + String content = message.getBody(); + + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v1(); + + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + cloudEventBuilder = CloudEventBuilder.v03(); + + } else { + throw new ProtocolHandleException(String.format("Unsupported protocolVersion: %s", protocolVersion)); + } + + cloudEventBuilder = cloudEventBuilder + .withId(header.getSeq()) + .withSource(URI.create("/")) + .withType("eventmeshmessage") + .withSubject(topic) + .withData(content.getBytes(StandardCharsets.UTF_8)); + + for (String propKey : header.getProperties().keySet()) { + try { + cloudEventBuilder.withExtension(propKey, header.getProperty(propKey).toString()); + } catch (Exception e) { + throw new ProtocolHandleException(String.format("Abnormal propKey: %s", propKey), e); + } + } + + for (String propKey : message.getProperties().keySet()) { + try { + cloudEventBuilder.withExtension(propKey, message.getProperties().get(propKey)); + } catch (Exception e) { + throw new ProtocolHandleException(String.format("Abnormal propKey: %s", propKey), e); + } + } + + return cloudEventBuilder.build(); + + } + + public static Package buildEventMeshMessage(CloudEvent cloudEvent) { + EventMeshMessage eventMeshMessage = new EventMeshMessage(); + eventMeshMessage.setTopic(cloudEvent.getSubject()); + eventMeshMessage.setBody(new String(cloudEvent.getData().toBytes(), StandardCharsets.UTF_8)); + + Map prop = new HashMap<>(); + for (String extKey : cloudEvent.getExtensionNames()) { + prop.put(extKey, cloudEvent.getExtension(extKey).toString()); + } + eventMeshMessage.setProperties(prop); + + Package pkg = new Package(); + pkg.setBody(eventMeshMessage); + + return pkg; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor new file mode 100644 index 0000000000..45ffc15eac --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +eventmeshmessage=org.apache.eventmesh.protocol.meshmessage.MeshMessageProtocolAdaptor \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/test/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolAdaptorTest.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/test/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolAdaptorTest.java new file mode 100644 index 0000000000..d67c58071a --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/test/java/org/apache/eventmesh/protocol/meshmessage/MeshMessageProtocolAdaptorTest.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.meshmessage; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; + +import org.junit.Assert; +import org.junit.Test; + +public class MeshMessageProtocolAdaptorTest { + + @Test + public void loadPlugin() { + ProtocolAdaptor protocolAdaptor = + ProtocolPluginFactory.getProtocolAdaptor(MeshMessageProtocolConstant.PROTOCOL_NAME); + Assert.assertNotNull(protocolAdaptor); + + Assert.assertEquals( + MeshMessageProtocolConstant.PROTOCOL_NAME, protocolAdaptor.getProtocolType() + ); + } + + @Test + public void getProtocolType() { + } +} \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/build.gradle new file mode 100644 index 0000000000..7a5ebcc4fb --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/build.gradle @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + implementation "io.cloudevents:cloudevents-core" + implementation "io.openmessaging:openmessaging-api" + + testImplementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + testImplementation "io.cloudevents:cloudevents-core" + testImplementation "io.openmessaging:openmessaging-api" +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/gradle.properties b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/gradle.properties new file mode 100644 index 0000000000..c414dfbd58 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=protocol +pluginName=openmessage \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolAdaptor.java b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolAdaptor.java new file mode 100644 index 0000000000..0e2d525049 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolAdaptor.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.openmessage; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import java.util.List; + +import io.cloudevents.CloudEvent; +import io.openmessaging.api.Message; + +/** + * OpenMessage protocol adaptor, used to transform protocol between + * {@link CloudEvent} with {@link Message}. + * + * @since 1.3.0 + */ +public class OpenMessageProtocolAdaptor implements ProtocolAdaptor { + + @Override + public CloudEvent toCloudEvent(ProtocolTransportObject message) { + return null; + } + + @Override + public List toBatchCloudEvent(ProtocolTransportObject protocol) throws ProtocolHandleException { + return null; + } + + @Override + public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) { + return null; + } + + @Override + public String getProtocolType() { + return OpenMessageProtocolConstant.PROTOCOL_NAME; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolConstant.java b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolConstant.java new file mode 100644 index 0000000000..9073addc59 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolConstant.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.openmessage; + +public enum OpenMessageProtocolConstant { + ; + + public static final String PROTOCOL_NAME = "openmessage"; + +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor new file mode 100644 index 0000000000..f29201a91b --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +openmessage=org.apache.eventmesh.protocol.openmessage.OpenMessageProtocolAdaptor \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/test/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolAdaptorTest.java b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/test/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolAdaptorTest.java new file mode 100644 index 0000000000..b0c49707fa --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-openmessage/src/test/java/org/apache/eventmesh/protocol/openmessage/OpenMessageProtocolAdaptorTest.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.protocol.openmessage; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; + +import org.junit.Assert; +import org.junit.Test; + +public class OpenMessageProtocolAdaptorTest { + + @Test + public void loadPlugin() { + ProtocolAdaptor protocolAdaptor = + ProtocolPluginFactory.getProtocolAdaptor(OpenMessageProtocolConstant.PROTOCOL_NAME); + + Assert.assertNotNull(protocolAdaptor); + Assert.assertEquals( + OpenMessageProtocolConstant.PROTOCOL_NAME, protocolAdaptor.getProtocolType() + ); + Assert.assertEquals(OpenMessageProtocolAdaptor.class, protocolAdaptor.getClass()); + } +} \ No newline at end of file diff --git a/eventmesh-registry-plugin/build.gradle b/eventmesh-registry-plugin/build.gradle new file mode 100644 index 0000000000..2944f98194 --- /dev/null +++ b/eventmesh-registry-plugin/build.gradle @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/build.gradle b/eventmesh-registry-plugin/eventmesh-registry-api/build.gradle new file mode 100644 index 0000000000..0d410425ba --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-api/build.gradle @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { + api project(":eventmesh-spi") + + testImplementation project(":eventmesh-spi") +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/exception/RegistryException.java b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/exception/RegistryException.java new file mode 100644 index 0000000000..893f8ff25c --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/exception/RegistryException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.exception; + +/** + * RegistryException + */ +public class RegistryException extends RuntimeException { + + public RegistryException(String message) { + super(message); + } + + public RegistryException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/RegistryService.java b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/RegistryService.java new file mode 100644 index 0000000000..c38bf7a4a4 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/RegistryService.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.registry; + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.List; +import java.util.Map; + +/** + * RegistryService + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.REGISTRY) +public interface RegistryService { + + void init() throws RegistryException; + + void start() throws RegistryException; + + void shutdown() throws RegistryException; + + List findEventMeshInfoByCluster(String clusterName) throws RegistryException; + + List findAllEventMeshInfo() throws RegistryException; + + Map> findEventMeshClientDistributionData( + String clusterName, String group, String purpose) throws RegistryException; + + void registerMetadata(Map metadataMap); + + boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws RegistryException; + + boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws RegistryException; +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshDataInfo.java b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshDataInfo.java new file mode 100644 index 0000000000..a478d3deb6 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshDataInfo.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.registry.dto; + +import java.util.Map; + +/** + * EventMeshDataInfo + */ +public class EventMeshDataInfo { + private String eventMeshClusterName; + private String eventMeshName; + private String endpoint; + private long lastUpdateTimestamp; + + private Map metadata; + + public EventMeshDataInfo() { + + } + + public EventMeshDataInfo(String eventMeshClusterName, String eventMeshName, String endpoint, long lastUpdateTimestamp, + Map metadata) { + this.eventMeshClusterName = eventMeshClusterName; + this.eventMeshName = eventMeshName; + this.endpoint = endpoint; + this.lastUpdateTimestamp = lastUpdateTimestamp; + this.metadata = metadata; + } + + public String getEventMeshClusterName() { + return eventMeshClusterName; + } + + public void setEventMeshClusterName(String eventMeshClusterName) { + this.eventMeshClusterName = eventMeshClusterName; + } + + public String getEventMeshName() { + return eventMeshName; + } + + public void setEventMeshName(String eventMeshName) { + this.eventMeshName = eventMeshName; + } + + public String getEndpoint() { + return endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public long getLastUpdateTimestamp() { + return lastUpdateTimestamp; + } + + public void setLastUpdateTimestamp(long lastUpdateTimestamp) { + this.lastUpdateTimestamp = lastUpdateTimestamp; + } + + public Map getMetadata() { + return metadata; + } + + public void setMetadata(Map metadata) { + this.metadata = metadata; + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshRegisterInfo.java b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshRegisterInfo.java new file mode 100644 index 0000000000..2e5a1d1ff1 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshRegisterInfo.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.registry.dto; + +import java.util.Map; + +/** + * EventMeshRegisterInfo + */ +public class EventMeshRegisterInfo { + private String eventMeshClusterName; + private String eventMeshName; + private String endPoint; + private Map> eventMeshInstanceNumMap; + + private Map metadata; + + private String protocolType; + + public String getEventMeshClusterName() { + return eventMeshClusterName; + } + + public void setEventMeshClusterName(String eventMeshClusterName) { + this.eventMeshClusterName = eventMeshClusterName; + } + + public String getEventMeshName() { + return eventMeshName; + } + + public void setEventMeshName(String eventMeshName) { + this.eventMeshName = eventMeshName; + } + + public String getEndPoint() { + return endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public Map> getEventMeshInstanceNumMap() { + return eventMeshInstanceNumMap; + } + + public void setEventMeshInstanceNumMap(Map> eventMeshInstanceNumMap) { + this.eventMeshInstanceNumMap = eventMeshInstanceNumMap; + } + + public Map getMetadata() { + return metadata; + } + + public void setMetadata(Map metadata) { + this.metadata = metadata; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshUnRegisterInfo.java b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshUnRegisterInfo.java new file mode 100644 index 0000000000..30cc8995d7 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshUnRegisterInfo.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.registry.dto; + +/** + * EventMeshUnRegisterInfo + */ +public class EventMeshUnRegisterInfo { + private String eventMeshClusterName; + private String eventMeshName; + + private String endPoint; + + private String protocolType; + + public String getEventMeshClusterName() { + return eventMeshClusterName; + } + + public void setEventMeshClusterName(String eventMeshClusterName) { + this.eventMeshClusterName = eventMeshClusterName; + } + + public String getEventMeshName() { + return eventMeshName; + } + + public void setEventMeshName(String eventMeshName) { + this.eventMeshName = eventMeshName; + } + + public String getEndPoint() { + return endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/build.gradle b/eventmesh-registry-plugin/eventmesh-registry-consul/build.gradle new file mode 100644 index 0000000000..53d7f67b4c --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-consul/build.gradle @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation 'com.ecwid.consul:consul-api:1.4.5' + implementation 'org.apache.httpcomponents:httpclient:4.5.13' + implementation project(":eventmesh-registry-plugin:eventmesh-registry-api") + implementation project(":eventmesh-common") + testImplementation "org.mockito:mockito-core" +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/gradle.properties b/eventmesh-registry-plugin/eventmesh-registry-consul/gradle.properties new file mode 100644 index 0000000000..3ed992f06e --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-consul/gradle.properties @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=registry +pluginName=consul \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/ConsulRegistryService.java b/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/ConsulRegistryService.java new file mode 100644 index 0000000000..36b3c2814c --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/ConsulRegistryService.java @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.consul.service; + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.registry.RegistryService; +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.ConsulRawClient; +import com.ecwid.consul.v1.agent.model.NewService; +import com.ecwid.consul.v1.agent.model.Service; +import com.ecwid.consul.v1.health.HealthServicesRequest; +import com.ecwid.consul.v1.health.model.HealthService; + +public class ConsulRegistryService implements RegistryService { + + public static final String IP_PORT_SEPARATOR = ":"; + + private static final Logger logger = LoggerFactory.getLogger(ConsulRegistryService.class); + + private static final AtomicBoolean INIT_STATUS = new AtomicBoolean(false); + + private static final AtomicBoolean START_STATUS = new AtomicBoolean(false); + + private String consulHost; + + private String consulPort; + + private ConsulClient consulClient; + + private String token; + + @Override + public void init() throws RegistryException { + if (INIT_STATUS.compareAndSet(false, true)) { + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); + if (null != commonConfiguration) { + String namesrvAddr = commonConfiguration.namesrvAddr; + if (StringUtils.isBlank(namesrvAddr)) { + throw new RegistryException("namesrvAddr cannot be null"); + } + String[] addr = namesrvAddr.split(":"); + if (addr.length != 2) { + throw new RegistryException("Illegal namesrvAddr"); + } + this.consulHost = addr[0]; + this.consulPort = addr[1]; + break; + } + } + } + } + + @Override + public void start() throws RegistryException { + consulClient = new ConsulClient(new ConsulRawClient(consulHost, Integer.parseInt(consulPort))); + } + + @Override + public void shutdown() throws RegistryException { + INIT_STATUS.compareAndSet(true, false); + START_STATUS.compareAndSet(true, false); + consulClient = null; + } + + @Override + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws RegistryException { + try { + String[] ipPort = eventMeshRegisterInfo.getEndPoint().split(IP_PORT_SEPARATOR); + NewService service = new NewService(); + service.setPort(Integer.parseInt(ipPort[1])); + service.setAddress(ipPort[0]); + service.setName(eventMeshRegisterInfo.getEventMeshName()); + service.setId(eventMeshRegisterInfo.getEventMeshClusterName() + "-" + eventMeshRegisterInfo.getEventMeshName()); + consulClient.agentServiceRegister(service, token); + } catch (Exception e) { + throw new RegistryException(e.getMessage()); + } + logger.info("EventMesh successfully registered to consul"); + return true; + } + + @Override + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws RegistryException { + try { + consulClient.agentServiceDeregister(eventMeshUnRegisterInfo.getEventMeshClusterName() + "-" + eventMeshUnRegisterInfo.getEventMeshName(), + token); + } catch (Exception e) { + throw new RegistryException(e.getMessage()); + } + logger.info("EventMesh successfully unregistered to consul"); + return true; + } + + @Override + public List findEventMeshInfoByCluster(String clusterName) throws RegistryException { + HealthServicesRequest request = HealthServicesRequest.newBuilder().setPassing(true).setToken(token).build(); + List healthServices = consulClient.getHealthServices(clusterName, request).getValue(); + List eventMeshDataInfos = new ArrayList<>(); + healthServices.forEach(healthService -> { + HealthService.Service service = healthService.getService(); + String[] split = service.getId().split("-"); + eventMeshDataInfos.add(new EventMeshDataInfo(split[0], split[1], service.getAddress() + ":" + service.getPort(), 0, service.getMeta())); + }); + return eventMeshDataInfos; + } + + @Override + public List findAllEventMeshInfo() throws RegistryException { + Map agentServices = consulClient.getAgentServices().getValue(); + List eventMeshDataInfos = new ArrayList<>(); + agentServices.forEach((k, v) -> { + String[] split = v.getId().split("-"); + eventMeshDataInfos.add(new EventMeshDataInfo(split[0], split[1], v.getAddress() + ":" + v.getPort(), 0, v.getMeta())); + }); + return eventMeshDataInfos; + } + + @Override + public Map> findEventMeshClientDistributionData(String clusterName, String group, String purpose) + throws RegistryException { + return Collections.emptyMap(); + } + + @Override + public void registerMetadata(Map metadataMap) { + + } + + public ConsulClient getConsulClient() { + return consulClient; + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/HeatBeatScheduler.java b/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/HeatBeatScheduler.java new file mode 100644 index 0000000000..a62db12fd2 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/HeatBeatScheduler.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.consul.service; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.agent.model.NewService; + +public class HeatBeatScheduler { + + private final ConsulClient consulClient; + + private final ConcurrentHashMap heartBeatMap = new ConcurrentHashMap<>(); + + private final ScheduledExecutorService heartbeatServiceExecutor = new ScheduledThreadPoolExecutor( + Runtime.getRuntime().availableProcessors(), + r -> { + Thread thread = new Thread(r); + thread.setDaemon(true); + thread.setName("ConsulHeartbeatService"); + return thread; + } + ); + + public HeatBeatScheduler(ConsulClient consulClient) { + this.consulClient = consulClient; + } + + /** + * start service heartbeat + * + * @param newService service + * @param aclToken token + */ + protected void startHeartBeat(NewService newService, String aclToken) { + heartbeatServiceExecutor.execute(new HeartBeat(newService, aclToken)); + heartBeatMap.put(newService.getName(), newService); + } + + /** + * stop service heartbeat + * + * @param newService service + */ + private void stopHeartBeat(NewService newService) { + heartBeatMap.remove(newService.getName()); + } + + class HeartBeat implements Runnable { + + private static final String CHECK_ID_PREFIX = "service:"; + + private String checkId; + + private final String aclToken; + + private final NewService instance; + + public HeartBeat(NewService instance, String aclToken) { + this.instance = instance; + this.checkId = instance.getId(); + this.aclToken = aclToken; + if (!checkId.startsWith(CHECK_ID_PREFIX)) { + checkId = CHECK_ID_PREFIX + checkId; + } + } + + @Override + public void run() { + try { + if (aclToken != null) { + consulClient.agentCheckPass(checkId, aclToken); + return; + } + if (heartBeatMap.contains(instance)) { + consulClient.agentCheckPass(checkId); + } + } finally { + heartbeatServiceExecutor.schedule(this, 3000, TimeUnit.SECONDS); + } + } + + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService b/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService new file mode 100644 index 0000000000..d18efe974c --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +consul=org.apache.eventmesh.registry.consul.service.ConsulRegistryService \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/src/test/java/ConsulRegistryServiceTest.java b/eventmesh-registry-plugin/eventmesh-registry-consul/src/test/java/ConsulRegistryServiceTest.java new file mode 100644 index 0000000000..96932e7dd0 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-consul/src/test/java/ConsulRegistryServiceTest.java @@ -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. + */ + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.registry.consul.service.ConsulRegistryService; + +import java.lang.reflect.Field; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ConsulRegistryServiceTest { + + @Mock + private EventMeshRegisterInfo eventMeshRegisterInfo; + @Mock + private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; + + private ConsulRegistryService consulRegistryService; + + @Before + public void registryTest() { + consulRegistryService = new ConsulRegistryService(); + CommonConfiguration configuration = new CommonConfiguration(null); + ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.HTTP, configuration); + configuration.namesrvAddr = "127.0.0.1:8500"; + Mockito.when(eventMeshRegisterInfo.getEventMeshClusterName()).thenReturn("eventmesh"); + Mockito.when(eventMeshRegisterInfo.getEventMeshName()).thenReturn("eventmesh"); + Mockito.when(eventMeshRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:8500"); + + Mockito.when(eventMeshUnRegisterInfo.getEventMeshClusterName()).thenReturn("eventmesh"); + Mockito.when(eventMeshUnRegisterInfo.getEventMeshName()).thenReturn("eventmesh"); + } + + @After + public void after() { + consulRegistryService.shutdown(); + } + + @Test + public void testInit() { + consulRegistryService.init(); + consulRegistryService.start(); + Assert.assertNotNull(consulRegistryService.getConsulClient()); + } + + @Test + public void testStart() { + consulRegistryService.init(); + consulRegistryService.start(); + Assert.assertNotNull(consulRegistryService.getConsulClient()); + } + + @Test + public void testShutdown() throws NoSuchFieldException, IllegalAccessException { + consulRegistryService.init(); + consulRegistryService.start(); + consulRegistryService.shutdown(); + Assert.assertNull(consulRegistryService.getConsulClient()); + Class consulRegistryServiceClass = ConsulRegistryService.class; + Field initStatus = consulRegistryServiceClass.getDeclaredField("INIT_STATUS"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(consulRegistryService); + + Field startStatus = consulRegistryServiceClass.getDeclaredField("START_STATUS"); + startStatus.setAccessible(true); + Object startStatusField = startStatus.get(consulRegistryService); + + + Assert.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); + Assert.assertFalse((Boolean.parseBoolean(startStatusField.toString()))); + } + + @Test(expected = RegistryException.class) + public void testRegister() { + consulRegistryService.init(); + consulRegistryService.start(); + consulRegistryService.register(eventMeshRegisterInfo); + List eventmesh = consulRegistryService.findEventMeshInfoByCluster("eventmesh"); + Assert.assertEquals(1, eventmesh.size()); + } + + @Test(expected = RegistryException.class) + public void testUnRegister() { + consulRegistryService.init(); + consulRegistryService.start(); + consulRegistryService.unRegister(eventMeshUnRegisterInfo); + List eventmesh = consulRegistryService.findEventMeshInfoByCluster("eventmesh"); + Assert.assertEquals(0, eventmesh.size()); + } + + @Test(expected = RegistryException.class) + public void findEventMeshInfoByCluster() { + consulRegistryService.init(); + consulRegistryService.start(); + consulRegistryService.register(eventMeshRegisterInfo); + List eventmesh = consulRegistryService.findEventMeshInfoByCluster("eventmesh"); + Assert.assertEquals(1, eventmesh.size()); + consulRegistryService.unRegister(eventMeshUnRegisterInfo); + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/build.gradle b/eventmesh-registry-plugin/eventmesh-registry-etcd/build.gradle new file mode 100644 index 0000000000..153c7555b3 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/build.gradle @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation ("io.etcd:jetcd-core:0.3.0") + implementation project(":eventmesh-registry-plugin:eventmesh-registry-api") + implementation project(":eventmesh-common") + testImplementation "org.mockito:mockito-core" +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/gradle.properties b/eventmesh-registry-plugin/eventmesh-registry-etcd/gradle.properties new file mode 100644 index 0000000000..325b28af4a --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/gradle.properties @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=registry +pluginName=etcd \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/constant/EtcdConstant.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/constant/EtcdConstant.java new file mode 100644 index 0000000000..16c31306d5 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/constant/EtcdConstant.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.etcd.constant; + +/** + * EtcdConstant. + */ +public class EtcdConstant { + + public static final String SERVER_ADDR = "serverAddr"; + + public static final String USERNAME = "username"; + + public static final String PASSWORD = "password"; + + public static final String KEY_SEPARATOR = "/"; + + public static final long TTL = 15L; + + +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientFactory.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientFactory.java new file mode 100644 index 0000000000..f69bdb5faa --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientFactory.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.etcd.factory; + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.registry.etcd.constant.EtcdConstant; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; +import java.util.Objects; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.etcd.jetcd.ByteSequence; +import io.etcd.jetcd.Client; +import io.etcd.jetcd.ClientBuilder; +import io.etcd.jetcd.options.LeaseOption; + + +public class EtcdClientFactory { + + private static final Logger logger = LoggerFactory.getLogger(EtcdClientFactory.class); + + private static final Map etcdLeaseIdMap = new ConcurrentHashMap<>(); + + + public static Client createClient(Properties properties) { + String serverAddr = properties.getProperty(EtcdConstant.SERVER_ADDR); + String username = properties.getProperty(EtcdConstant.USERNAME); + String password = properties.getProperty(EtcdConstant.PASSWORD); + + EtcdLeaseId etcdLeaseId = etcdLeaseIdMap.get(serverAddr); + if (Objects.nonNull(etcdLeaseId)) { + return etcdLeaseId.getClientWrapper(); + } + ClientBuilder clientBuilder = Client.builder(); + String[] addresses = serverAddr.split(","); + String[] httpAddress = new String[addresses.length]; + for (int i = 0; i < addresses.length; i++) { + if (!addresses[i].startsWith(Constants.HTTP_PROTOCOL_PREFIX)) { + httpAddress[i] = Constants.HTTP_PROTOCOL_PREFIX + addresses[i]; + } + } + etcdLeaseId = new EtcdLeaseId(); + try { + etcdLeaseId.setUrl(serverAddr); + etcdLeaseId.setClientBuilder(clientBuilder.endpoints(httpAddress)); + if (StringUtils.isNoneBlank(username)) { + etcdLeaseId.getClientBuilder().user(ByteSequence.from(username.getBytes())); + } + if (StringUtils.isNoneBlank(password)) { + etcdLeaseId.getClientBuilder().password(ByteSequence.from(password.getBytes())); + } + etcdLeaseId.setClientWrapper(new EtcdClientWrapper(etcdLeaseId.getClientBuilder().build())); + EtcdClientWrapper client = etcdLeaseId.getClientWrapper(); + long leaseId = client.getLeaseClient().grant(EtcdConstant.TTL).get().getID(); + etcdLeaseId.setLeaseId(leaseId); + EtcdStreamObserver etcdStreamObserver = new EtcdStreamObserver(); + etcdStreamObserver.setEtcdLeaseId(etcdLeaseId); + etcdLeaseId.setEtcdStreamObserver(etcdStreamObserver); + client.getLeaseClient().keepAlive(leaseId, etcdStreamObserver); + + etcdLeaseIdMap.put(serverAddr, etcdLeaseId); + } catch (Throwable e) { + logger.error("createClient failed, address: {}", serverAddr, e); + throw new RegistryException("createClient failed", e); + } + return etcdLeaseId.getClientWrapper(); + } + + + public static void renewalLeaseId(EtcdLeaseId etcdLeaseId) { + logger.info("renewal of contract. server url: {}", etcdLeaseId.getUrl()); + Client client = etcdLeaseId.getClientWrapper(); + try { + long ttl = client.getLeaseClient().timeToLive(etcdLeaseId.getLeaseId(), LeaseOption.DEFAULT).get().getTTl(); + if (ttl < 1) { + long leaseId = client.getLeaseClient().grant(EtcdConstant.TTL).get().getID(); + client.getLeaseClient().keepAlive(leaseId, etcdLeaseId.getEtcdStreamObserver()); + etcdLeaseId.setLeaseId(leaseId); + } + } catch (Throwable e) { + logger.error("renewal error, server url: {}", etcdLeaseId.getUrl(), e); + client.getLeaseClient().keepAlive(System.currentTimeMillis(), etcdLeaseId.getEtcdStreamObserver()); + } + } + + public static Long getLeaseId(String url) { + return getEtcdLeaseId(url).getLeaseId(); + } + + public static EtcdLeaseId getEtcdLeaseId(String url) { + return etcdLeaseIdMap.get(url); + } + +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientWrapper.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientWrapper.java new file mode 100644 index 0000000000..5e0b8507b0 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientWrapper.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.etcd.factory; + + +import io.etcd.jetcd.Auth; +import io.etcd.jetcd.Client; +import io.etcd.jetcd.Cluster; +import io.etcd.jetcd.KV; +import io.etcd.jetcd.Lease; +import io.etcd.jetcd.Lock; +import io.etcd.jetcd.Maintenance; +import io.etcd.jetcd.Watch; + + +class EtcdClientWrapper implements Client { + + private volatile Client client; + + public EtcdClientWrapper(Client client) { + this.client = client; + } + + @Override + public Auth getAuthClient() { + return client.getAuthClient(); + } + + @Override + public KV getKVClient() { + return client.getKVClient(); + } + + @Override + public Cluster getClusterClient() { + return client.getClusterClient(); + } + + @Override + public Maintenance getMaintenanceClient() { + return client.getMaintenanceClient(); + } + + @Override + public Lease getLeaseClient() { + return client.getLeaseClient(); + } + + @Override + public Watch getWatchClient() { + return client.getWatchClient(); + } + + @Override + public Lock getLockClient() { + return client.getLockClient(); + } + + @Override + public void close() { + client.close(); + } + +} \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdLeaseId.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdLeaseId.java new file mode 100644 index 0000000000..28ee89f87c --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdLeaseId.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.etcd.factory; + +import java.util.concurrent.atomic.AtomicBoolean; + +import io.etcd.jetcd.ClientBuilder; + +class EtcdLeaseId { + + private long leaseId; + + private AtomicBoolean renewalLock = new AtomicBoolean(); + + private EtcdClientWrapper clientWrapper; + + private ClientBuilder clientBuilder; + + private String url; + + private long ttl; + + private EtcdStreamObserver etcdStreamObserver; + + public AtomicBoolean getRenewalLock() { + return renewalLock; + } + + public void setRenewalLock(AtomicBoolean renewalLock) { + this.renewalLock = renewalLock; + } + + public EtcdClientWrapper getClientWrapper() { + return clientWrapper; + } + + public void setClientWrapper(EtcdClientWrapper clientWrapper) { + this.clientWrapper = clientWrapper; + } + + public ClientBuilder getClientBuilder() { + return clientBuilder; + } + + public void setClientBuilder(ClientBuilder clientBuilder) { + this.clientBuilder = clientBuilder; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public EtcdStreamObserver getEtcdStreamObserver() { + return etcdStreamObserver; + } + + public void setEtcdStreamObserver(EtcdStreamObserver etcdStreamObserver) { + this.etcdStreamObserver = etcdStreamObserver; + } + + public long getLeaseId() { + return leaseId; + } + + public void setLeaseId(long leaseId) { + this.leaseId = leaseId; + } +} + diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdStreamObserver.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdStreamObserver.java new file mode 100644 index 0000000000..6b5efc79ef --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdStreamObserver.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.etcd.factory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.etcd.jetcd.lease.LeaseKeepAliveResponse; +import io.grpc.stub.StreamObserver; + + +public class EtcdStreamObserver implements StreamObserver { + + private static final Logger logger = LoggerFactory.getLogger(EtcdStreamObserver.class); + + private EtcdLeaseId etcdLeaseId; + + @Override + public void onNext(LeaseKeepAliveResponse value) { + } + + @Override + public void onError(Throwable t) { + logger.debug("EtcdStreamObserver lease renewal Exception", t); + } + + @Override + public void onCompleted() { + logger.info("EtcdStreamObserver completed"); + } + + public void setEtcdLeaseId(EtcdLeaseId etcdLeaseId) { + this.etcdLeaseId = etcdLeaseId; + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryService.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryService.java new file mode 100644 index 0000000000..58c78f34a9 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryService.java @@ -0,0 +1,280 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.etcd.service; + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.registry.RegistryService; +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.registry.etcd.constant.EtcdConstant; +import org.apache.eventmesh.registry.etcd.factory.EtcdClientFactory; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.etcd.jetcd.ByteSequence; +import io.etcd.jetcd.Client; +import io.etcd.jetcd.KeyValue; +import io.etcd.jetcd.options.GetOption; +import io.etcd.jetcd.options.PutOption; + +public class EtcdRegistryService implements RegistryService { + + private static final Logger logger = LoggerFactory.getLogger(EtcdRegistryService.class); + + private static final AtomicBoolean INIT_STATUS = new AtomicBoolean(false); + + private static final AtomicBoolean START_STATUS = new AtomicBoolean(false); + + private static final String KEY_PREFIX = EtcdConstant.KEY_SEPARATOR + "eventMesh" + EtcdConstant.KEY_SEPARATOR + "registry" + + EtcdConstant.KEY_SEPARATOR; + + private String serverAddr; + + private String username; + + private String password; + + private Client etcdClient; + + private Map eventMeshRegisterInfoMap; + + private ScheduledExecutorService etcdRegistryMonitorExecutorService; + + @Override + public void init() throws RegistryException { + boolean update = INIT_STATUS.compareAndSet(false, true); + if (!update) { + return; + } + eventMeshRegisterInfoMap = new HashMap<>(ConfigurationContextUtil.KEYS.size()); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); + if (null == commonConfiguration) { + continue; + } + if (StringUtils.isBlank(commonConfiguration.namesrvAddr)) { + throw new RegistryException("namesrvAddr cannot be null"); + } + this.serverAddr = commonConfiguration.namesrvAddr; + this.username = commonConfiguration.eventMeshRegistryPluginUsername; + this.password = commonConfiguration.eventMeshRegistryPluginPassword; + break; + } + etcdRegistryMonitorExecutorService = ThreadPoolFactory.createSingleScheduledExecutor( + "EtcdRegistryMonitorThread" + ); + } + + @Override + public void start() throws RegistryException { + boolean update = START_STATUS.compareAndSet(false, true); + if (!update) { + return; + } + try { + Properties properties = new Properties(); + properties.setProperty(EtcdConstant.SERVER_ADDR, serverAddr); + properties.setProperty(EtcdConstant.USERNAME, username); + properties.setProperty(EtcdConstant.PASSWORD, password); + this.etcdClient = EtcdClientFactory.createClient(properties); + + etcdRegistryMonitorExecutorService.scheduleAtFixedRate(new EventMeshEtcdRegisterMonitor(), + 15000L, 15000L, TimeUnit.MILLISECONDS); + } catch (Exception e) { + logger.error("[EtcdRegistryService][start] error", e); + throw new RegistryException(e.getMessage()); + } + } + + @Override + public void shutdown() throws RegistryException { + INIT_STATUS.compareAndSet(true, false); + START_STATUS.compareAndSet(true, false); + try { + if (etcdClient != null) { + etcdClient.close(); + } + if (etcdRegistryMonitorExecutorService != null && !etcdRegistryMonitorExecutorService.isShutdown()) { + etcdRegistryMonitorExecutorService.shutdown(); + } + } catch (Exception e) { + logger.error("[EtcdRegistryService][shutdown] error", e); + throw new RegistryException(e.getMessage()); + } + logger.info("EtcdRegistryService closed"); + } + + @Override + public List findEventMeshInfoByCluster(String clusterName) throws RegistryException { + List eventMeshDataInfoList = new ArrayList<>(); + + try { + String keyPrefix = clusterName == null ? KEY_PREFIX : KEY_PREFIX + EtcdConstant.KEY_SEPARATOR + clusterName; + ByteSequence keyByteSequence = ByteSequence.from(keyPrefix.getBytes()); + GetOption getOption = GetOption.newBuilder().withPrefix(keyByteSequence).build(); + List keyValues = etcdClient.getKVClient().get(keyByteSequence, getOption).get().getKvs(); + + if (CollectionUtils.isNotEmpty(keyValues)) { + for (KeyValue kv : keyValues) { + EventMeshDataInfo eventMeshDataInfo = JsonUtils.deserialize(new String(kv.getValue().getBytes()), EventMeshDataInfo.class); + eventMeshDataInfoList.add(eventMeshDataInfo); + } + } + } catch (Exception e) { + logger.error("[EtcdRegistryService][findEventMeshInfoByCluster] error, clusterName: {}", clusterName, e); + throw new RegistryException(e.getMessage()); + } + return eventMeshDataInfoList; + } + + @Override + public List findAllEventMeshInfo() throws RegistryException { + try { + return findEventMeshInfoByCluster(null); + } catch (Exception e) { + logger.error("[EtcdRegistryService][findEventMeshInfoByCluster] error", e); + throw new RegistryException(e.getMessage()); + } + } + + @Override + public Map> findEventMeshClientDistributionData(String clusterName, String group, String purpose) + throws RegistryException { + // todo find metadata + return null; + } + + @Override + public void registerMetadata(Map metadataMap) { + for (Map.Entry eventMeshRegisterInfo : eventMeshRegisterInfoMap.entrySet()) { + EventMeshRegisterInfo registerInfo = eventMeshRegisterInfo.getValue(); + registerInfo.setMetadata(metadataMap); + this.register(registerInfo); + } + } + + @Override + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws RegistryException { + String eventMeshClusterName = eventMeshRegisterInfo.getEventMeshClusterName(); + String eventMeshName = eventMeshRegisterInfo.getEventMeshName(); + String endPoint = eventMeshRegisterInfo.getEndPoint(); + try { + ByteSequence etcdKey = getEtcdKey(eventMeshClusterName, eventMeshName, endPoint); + EventMeshDataInfo eventMeshDataInfo = + new EventMeshDataInfo(eventMeshClusterName, eventMeshName, + endPoint, System.currentTimeMillis(), eventMeshRegisterInfo.getMetadata()); + ByteSequence etcdValue = ByteSequence.from(JsonUtils.serialize(eventMeshDataInfo).getBytes()); + etcdClient.getKVClient().put(etcdKey, etcdValue, PutOption.newBuilder().withLeaseId(getLeaseId()).build()); + eventMeshRegisterInfoMap.put(eventMeshName, eventMeshRegisterInfo); + + logger.info("EventMesh successfully registered to etcd, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName); + return true; + } catch (Exception e) { + logger.error("[EtcdRegistryService][register] error, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName, e); + throw new RegistryException(e.getMessage()); + } + } + + @Override + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws RegistryException { + String eventMeshClusterName = eventMeshUnRegisterInfo.getEventMeshClusterName(); + String eventMeshName = eventMeshUnRegisterInfo.getEventMeshName(); + try { + ByteSequence etcdKey = getEtcdKey(eventMeshClusterName, eventMeshName, + eventMeshUnRegisterInfo.getEndPoint()); + etcdClient.getKVClient().delete(etcdKey); + eventMeshRegisterInfoMap.remove(eventMeshName); + logger.info("EventMesh successfully logout to etcd, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName); + return true; + } catch (Exception e) { + logger.error("[EtcdRegistryService][unRegister] error, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName, e); + throw new RegistryException(e.getMessage()); + } + } + + public Client getEtcdClient() { + return etcdClient; + } + + public long getLeaseId() { + return EtcdClientFactory.getLeaseId(serverAddr); + } + + private ByteSequence getEtcdKey(String eventMeshClusterName, String eventMeshName, String endPoint) { + StringBuilder etcdKey = new StringBuilder(KEY_PREFIX).append(eventMeshClusterName); + if (StringUtils.isNoneBlank(eventMeshName)) { + etcdKey.append(EtcdConstant.KEY_SEPARATOR).append(eventMeshName); + } + if (StringUtils.isNoneBlank(endPoint)) { + etcdKey.append(EtcdConstant.KEY_SEPARATOR).append(endPoint); + } + return ByteSequence.from(etcdKey.toString().getBytes()); + } + + /** + * check the registered services if alive + */ + private class EventMeshEtcdRegisterMonitor implements Runnable { + + @Override + public void run() { + if (eventMeshRegisterInfoMap.size() > 0) { + for (Map.Entry eventMeshRegisterInfoEntry : eventMeshRegisterInfoMap.entrySet()) { + EventMeshRegisterInfo eventMeshRegisterInfo = eventMeshRegisterInfoEntry.getValue(); + ByteSequence etcdKey = getEtcdKey(eventMeshRegisterInfo.getEventMeshClusterName(), + eventMeshRegisterInfo.getEventMeshName(), eventMeshRegisterInfo.getEndPoint()); + List keyValues = null; + try { + keyValues = etcdClient.getKVClient().get(etcdKey).get().getKvs(); + } catch (InterruptedException | ExecutionException e) { + logger.error("get etcdKey[{}] failed", etcdKey, e); + } + if (CollectionUtils.isEmpty(keyValues)) { + logger.warn("eventMeshRegisterInfo [{}] is not matched in Etcd , try to register again", + eventMeshRegisterInfo.getEventMeshName()); + EtcdClientFactory.renewalLeaseId(EtcdClientFactory.getEtcdLeaseId(serverAddr)); + register(eventMeshRegisterInfo); + } + } + } + } + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService new file mode 100644 index 0000000000..56730d9290 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +etcd=org.apache.eventmesh.registry.etcd.service.EtcdRegistryService \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/test/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryServiceTest.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/test/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryServiceTest.java new file mode 100644 index 0000000000..5aaaeaf6e4 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/test/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryServiceTest.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.etcd.service; + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; + +import java.lang.reflect.Field; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class EtcdRegistryServiceTest { + + @Mock + private EventMeshRegisterInfo eventMeshRegisterInfo; + @Mock + private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; + + private EtcdRegistryService etcdRegistryService; + + @Before + public void setUp() { + etcdRegistryService = new EtcdRegistryService(); + CommonConfiguration configuration = new CommonConfiguration(null); + configuration.namesrvAddr = "127.0.0.1:2379"; + ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.HTTP, configuration); + + // Mockito.when(eventMeshRegisterInfo.getEventMeshClusterName()).thenReturn("eventmesh"); + // Mockito.when(eventMeshRegisterInfo.getEventMeshName()).thenReturn("eventmesh"); + // Mockito.when(eventMeshRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:2379"); + // + // Mockito.when(eventMeshUnRegisterInfo.getEventMeshClusterName()).thenReturn("eventmesh"); + // Mockito.when(eventMeshUnRegisterInfo.getEventMeshName()).thenReturn("eventmesh"); + // Mockito.when(eventMeshUnRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:2379"); + } + + @After + public void after() { + etcdRegistryService.shutdown(); + } + + + @Test + public void testInit() { + etcdRegistryService.init(); + } + + @Test(expected = RegistryException.class) + public void testStart() { + etcdRegistryService.init(); + etcdRegistryService.start(); + Assert.assertNotNull(etcdRegistryService); + + } + + @Test(expected = RegistryException.class) + public void testShutdown() throws NoSuchFieldException, IllegalAccessException { + etcdRegistryService.init(); + etcdRegistryService.start(); + etcdRegistryService.shutdown(); + + Class etcdRegistryServiceClass = EtcdRegistryService.class; + Field initStatus = etcdRegistryServiceClass.getDeclaredField("INIT_STATUS"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(etcdRegistryService); + + Field startStatus = etcdRegistryServiceClass.getDeclaredField("START_STATUS"); + startStatus.setAccessible(true); + Object startStatusField = startStatus.get(etcdRegistryService); + + } + + @Test(expected = RegistryException.class) + public void testRegister() { + etcdRegistryService.init(); + etcdRegistryService.start(); + etcdRegistryService.register(eventMeshRegisterInfo); + } + + @Test(expected = RegistryException.class) + public void testFindEventMeshInfo() { + etcdRegistryService.init(); + etcdRegistryService.start(); + etcdRegistryService.register(eventMeshRegisterInfo); + List eventMeshDataInfoList = etcdRegistryService.findAllEventMeshInfo(); + } + + @Test(expected = RegistryException.class) + public void testUnRegister() { + etcdRegistryService.init(); + etcdRegistryService.start(); + etcdRegistryService.unRegister(eventMeshUnRegisterInfo); + } + +} \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/build.gradle b/eventmesh-registry-plugin/eventmesh-registry-nacos/build.gradle new file mode 100644 index 0000000000..a0492d7479 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-nacos/build.gradle @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation "com.alibaba.nacos:nacos-client:2.0.4" + implementation project(":eventmesh-registry-plugin:eventmesh-registry-api") + implementation project(":eventmesh-common") + testImplementation "org.mockito:mockito-core" +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/gradle.properties b/eventmesh-registry-plugin/eventmesh-registry-nacos/gradle.properties new file mode 100644 index 0000000000..dc23fa1f66 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-nacos/gradle.properties @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=registry +pluginName=nacos \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/constant/NacosConstant.java b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/constant/NacosConstant.java new file mode 100644 index 0000000000..0164dc1336 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/constant/NacosConstant.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.nacos.constant; + +/** + * NacosConstant. + */ +public class NacosConstant { + + public static final String SERVER_ADDR = "serverAddr"; + + public static final String NAMESPACE = "namespace"; + + public static final String USERNAME = "username"; + + public static final String PASSWORD = "password"; + + public static final String IP_PORT_SEPARATOR = ":"; + + public static final String DEFAULT_GROUP = "DEFAULT_GROUP"; + + public static final String GROUP = "GROUP"; + +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryService.java b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryService.java new file mode 100644 index 0000000000..956f6eb629 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryService.java @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.nacos.service; + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.registry.RegistryService; +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.registry.nacos.constant.NacosConstant; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.alibaba.nacos.client.naming.NacosNamingService; +import com.alibaba.nacos.common.utils.CollectionUtils; + +public class NacosRegistryService implements RegistryService { + + private static final Logger logger = LoggerFactory.getLogger(NacosRegistryService.class); + + private static final AtomicBoolean INIT_STATUS = new AtomicBoolean(false); + + private static final AtomicBoolean START_STATUS = new AtomicBoolean(false); + + private String serverAddr; + + private String username; + + private String password; + + private NamingService namingService; + + private Map eventMeshRegisterInfoMap; + + @Override + public void init() throws RegistryException { + boolean update = INIT_STATUS.compareAndSet(false, true); + if (!update) { + return; + } + eventMeshRegisterInfoMap = new HashMap<>(ConfigurationContextUtil.KEYS.size()); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); + if (null == commonConfiguration) { + continue; + } + if (StringUtils.isBlank(commonConfiguration.namesrvAddr)) { + throw new RegistryException("namesrvAddr cannot be null"); + } + this.serverAddr = commonConfiguration.namesrvAddr; + this.username = commonConfiguration.eventMeshRegistryPluginUsername; + this.password = commonConfiguration.eventMeshRegistryPluginPassword; + break; + } + } + + @Override + public void start() throws RegistryException { + boolean update = START_STATUS.compareAndSet(false, true); + if (!update) { + return; + } + try { + Properties properties = new Properties(); + properties.setProperty(NacosConstant.SERVER_ADDR, serverAddr); + properties.setProperty(NacosConstant.USERNAME, username); + properties.setProperty(NacosConstant.PASSWORD, password); + namingService = new NacosNamingService(properties); + } catch (NacosException e) { + logger.error("[NacosRegistryService][start] error", e); + throw new RegistryException(e.getMessage()); + } + } + + @Override + public void shutdown() throws RegistryException { + INIT_STATUS.compareAndSet(true, false); + START_STATUS.compareAndSet(true, false); + try { + namingService.shutDown(); + } catch (NacosException e) { + logger.error("[NacosRegistryService][shutdown] error", e); + throw new RegistryException(e.getMessage()); + } + logger.info("NacosRegistryService close"); + } + + @Override + public List findEventMeshInfoByCluster(String clusterName) throws RegistryException { + List eventMeshDataInfoList = new ArrayList<>(); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration configuration = ConfigurationContextUtil.get(key); + if (Objects.isNull(configuration)) { + continue; + } + String eventMeshName = configuration.eventMeshName; + try { + List instances = + namingService.selectInstances(eventMeshName + "-" + key, configuration.eventMeshCluster, Collections.singletonList(clusterName), + true); + if (CollectionUtils.isEmpty(instances)) { + continue; + } + for (Instance instance : instances) { + EventMeshDataInfo eventMeshDataInfo = + new EventMeshDataInfo(instance.getClusterName(), instance.getServiceName(), + instance.getIp() + ":" + instance.getPort(), 0L, instance.getMetadata()); + eventMeshDataInfoList.add(eventMeshDataInfo); + } + } catch (NacosException e) { + logger.error("[NacosRegistryService][findEventMeshInfoByCluster] error", e); + throw new RegistryException(e.getMessage()); + } + + } + return eventMeshDataInfoList; + } + + @Override + public List findAllEventMeshInfo() throws RegistryException { + List eventMeshDataInfoList = new ArrayList<>(); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration configuration = ConfigurationContextUtil.get(key); + if (Objects.isNull(configuration)) { + continue; + } + String eventMeshName = configuration.eventMeshName; + try { + List instances = + namingService.selectInstances(eventMeshName + "-" + key, key + "-" + NacosConstant.GROUP, null, + true); + if (CollectionUtils.isEmpty(instances)) { + continue; + } + for (Instance instance : instances) { + EventMeshDataInfo eventMeshDataInfo = + new EventMeshDataInfo(instance.getClusterName(), instance.getServiceName(), + instance.getIp() + ":" + instance.getPort(), 0L, instance.getMetadata()); + eventMeshDataInfoList.add(eventMeshDataInfo); + } + } catch (NacosException e) { + logger.error("[NacosRegistryService][findEventMeshInfoByCluster] error", e); + throw new RegistryException(e.getMessage()); + } + + } + return eventMeshDataInfoList; + } + + @Override + public Map> findEventMeshClientDistributionData(String clusterName, String group, String purpose) + throws RegistryException { + // todo find metadata + return null; + } + + @Override + public void registerMetadata(Map metadataMap) { + for (Map.Entry eventMeshRegisterInfo : eventMeshRegisterInfoMap.entrySet()) { + EventMeshRegisterInfo registerInfo = eventMeshRegisterInfo.getValue(); + registerInfo.setMetadata(metadataMap); + this.register(registerInfo); + } + } + + @Override + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws RegistryException { + try { + String[] ipPort = eventMeshRegisterInfo.getEndPoint().split(NacosConstant.IP_PORT_SEPARATOR); + String eventMeshClusterName = eventMeshRegisterInfo.getEventMeshClusterName(); + Map metadata = eventMeshRegisterInfo.getMetadata(); + + Instance instance = new Instance(); + instance.setIp(ipPort[0]); + instance.setPort(Integer.parseInt(ipPort[1])); + instance.setWeight(1.0); + instance.setClusterName(eventMeshClusterName); + instance.setMetadata(metadata); + + String eventMeshName = eventMeshRegisterInfo.getEventMeshName(); + namingService.registerInstance(eventMeshName, eventMeshRegisterInfo.getProtocolType() + "-" + NacosConstant.GROUP, instance); + eventMeshRegisterInfoMap.put(eventMeshName, eventMeshRegisterInfo); + } catch (NacosException e) { + logger.error("[NacosRegistryService][register] error", e); + throw new RegistryException(e.getMessage()); + } + logger.info("EventMesh successfully registered to nacos"); + return true; + } + + @Override + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws RegistryException { + String[] ipPort = eventMeshUnRegisterInfo.getEndPoint().split(NacosConstant.IP_PORT_SEPARATOR); + try { + Instance instance = new Instance(); + instance.setIp(ipPort[0]); + instance.setPort(Integer.parseInt(ipPort[1])); + String eventMeshName = eventMeshUnRegisterInfo.getEventMeshName(); + String eventMeshClusterName = eventMeshUnRegisterInfo.getEventMeshClusterName(); + instance.setClusterName(eventMeshClusterName); + namingService.deregisterInstance(eventMeshName, eventMeshUnRegisterInfo.getProtocolType() + "-" + NacosConstant.GROUP, instance); + } catch (NacosException e) { + logger.error("[NacosRegistryService][unRegister] error", e); + throw new RegistryException(e.getMessage()); + } + logger.info("EventMesh successfully logout to nacos"); + return true; + } + + public String getServerAddr() { + return serverAddr; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public NamingService getNamingService() { + return namingService; + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService new file mode 100644 index 0000000000..3d28c7c18d --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +nacos=org.apache.eventmesh.registry.nacos.service.NacosRegistryService \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/test/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryServiceTest.java b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/test/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryServiceTest.java new file mode 100644 index 0000000000..9499128930 --- /dev/null +++ b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/test/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryServiceTest.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.registry.nacos.service; + +import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; + +import java.lang.reflect.Field; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class NacosRegistryServiceTest { + + @Mock + private EventMeshRegisterInfo eventMeshRegisterInfo; + @Mock + private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; + + private NacosRegistryService nacosRegistryService; + + @Before + public void setUp() { + nacosRegistryService = new NacosRegistryService(); + CommonConfiguration configuration = new CommonConfiguration(null); + configuration.namesrvAddr = "127.0.0.1"; + configuration.eventMeshRegistryPluginPassword = "nacos"; + configuration.eventMeshRegistryPluginUsername = "nacos"; + ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.HTTP, configuration); + + Mockito.when(eventMeshRegisterInfo.getEventMeshClusterName()).thenReturn("eventmesh"); + Mockito.when(eventMeshRegisterInfo.getEventMeshName()).thenReturn("eventmesh"); + Mockito.when(eventMeshRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:8848"); + + Mockito.when(eventMeshUnRegisterInfo.getEventMeshClusterName()).thenReturn("eventmesh"); + Mockito.when(eventMeshUnRegisterInfo.getEventMeshName()).thenReturn("eventmesh"); + Mockito.when(eventMeshUnRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:8848"); + } + + @After + public void after() { + nacosRegistryService.shutdown(); + } + + + @Test + public void testInit() { + nacosRegistryService.init(); + nacosRegistryService.start(); + Assert.assertNotNull(nacosRegistryService.getServerAddr()); + } + + @Test + public void testStart() { + nacosRegistryService.init(); + nacosRegistryService.start(); + Assert.assertNotNull(nacosRegistryService.getNamingService()); + + } + + @Test + public void testShutdown() throws NoSuchFieldException, IllegalAccessException { + nacosRegistryService.init(); + nacosRegistryService.start(); + nacosRegistryService.shutdown(); + + Class nacosRegistryServiceClass = NacosRegistryService.class; + Field initStatus = nacosRegistryServiceClass.getDeclaredField("INIT_STATUS"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(nacosRegistryService); + + Field startStatus = nacosRegistryServiceClass.getDeclaredField("START_STATUS"); + startStatus.setAccessible(true); + Object startStatusField = startStatus.get(nacosRegistryService); + + + Assert.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); + Assert.assertFalse((Boolean.parseBoolean(startStatusField.toString()))); + } + + @Test(expected = RegistryException.class) + public void testRegister() { + nacosRegistryService.init(); + nacosRegistryService.start(); + nacosRegistryService.register(eventMeshRegisterInfo); + } + + @Test(expected = RegistryException.class) + public void testUnRegister() { + nacosRegistryService.init(); + nacosRegistryService.start(); + nacosRegistryService.unRegister(eventMeshUnRegisterInfo); + } + +} \ No newline at end of file diff --git a/eventmesh-registry/build.gradle b/eventmesh-registry/build.gradle deleted file mode 100644 index 11bbc47bf2..0000000000 --- a/eventmesh-registry/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - id 'java' -} - -group 'cn.webank.defibus' -version '1.0.0' - -repositories { - mavenCentral() -} - -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' -} diff --git a/eventmesh-runtime/bin/start.sh b/eventmesh-runtime/bin/start.sh new file mode 100644 index 0000000000..3ad63a71ea --- /dev/null +++ b/eventmesh-runtime/bin/start.sh @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#=========================================================================================== +# Java Environment Setting +#=========================================================================================== +set -e +#Server configuration may be inconsistent, add these configurations to avoid garbled code problems +export LANG=en_US.UTF-8 +export LC_CTYPE=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +TMP_JAVA_HOME="/nemo/jdk1.8.0_152" + +#detect operating system. +OS=$(uname) + +function is_java8 { + local _java="$1" + [[ -x "$_java" ]] || return 1 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' ]] || return 2 + return 0 +} + +#0(not running), 1(is running) +#function is_proxyRunning { +# local _pid="$1" +# local pid=`ps ax | grep -i 'org.apache.eventmesh.runtime.boot.EventMeshStartup' |grep java | grep -v grep | awk '{print $1}'|grep $_pid` +# if [ -z "$pid" ] ; then +# return 0 +# else +# return 1 +# fi +#} + +function get_pid { + local ppid="" + if [ -f ${EVENTMESH_HOME}/bin/pid.file ]; then + ppid=$(cat ${EVENTMESH_HOME}/bin/pid.file) + else + if [[ $OS =~ Msys ]]; then + # There is a Bug on Msys that may not be able to kill the identified process + ppid=`jps -v | grep -i "org.apache.eventmesh.runtime.boot.EventMeshStartup" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known problem: grep Java may not be able to accurately identify Java processes + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.runtime.boot.EventMeshStartup" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on Linux + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $EVENTMESH_HOME | grep -i "org.apache.eventmesh.runtime.boot.EventMeshStartup" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "$ppid"; +} + + +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then + JAVA="$TMP_JAVA_HOME/bin/java" +elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA="$JAVA_HOME/bin/java" +elif is_java8 "/nemo/jdk8/bin/java"; then + JAVA="/nemo/jdk8/bin/java"; +elif is_java8 "/nemo/jdk1.8/bin/java"; then + JAVA="/nemo/jdk1.8/bin/java"; +elif is_java8 "/nemo/jdk/bin/java"; then + JAVA="/nemo/jdk/bin/java"; +elif is_java8 "$(which java)"; then + JAVA="$(which java)" +else + echo -e "ERROR\t java(1.8) not found, operation abort." + exit 9; +fi + +echo "eventmesh use java location= "$JAVA + +EVENTMESH_HOME=`cd $(dirname $0)/.. && pwd` + +export EVENTMESH_HOME + +export EVENTMESH_LOG_HOME=${EVENTMESH_HOME}/logs + +echo "EVENTMESH_HOME : ${EVENTMESH_HOME}, EVENTMESH_LOG_HOME : ${EVENTMESH_LOG_HOME}" + +function make_logs_dir { + if [ ! -e "${EVENTMESH_LOG_HOME}" ]; then mkdir -p "${EVENTMESH_LOG_HOME}"; fi +} + +error_exit () +{ + echo "ERROR: $1 !!" + exit 1 +} + +export JAVA_HOME + +#=========================================================================================== +# JVM Configuration +#=========================================================================================== +#if [ $1 = "prd" -o $1 = "benchmark" ]; then JAVA_OPT="${JAVA_OPT} -server -Xms2048M -Xmx4096M -Xmn2048m -XX:SurvivorRatio=4" +#elif [ $1 = "sit" ]; then JAVA_OPT="${JAVA_OPT} -server -Xms256M -Xmx512M -Xmn256m -XX:SurvivorRatio=4" +#elif [ $1 = "dev" ]; then JAVA_OPT="${JAVA_OPT} -server -Xms128M -Xmx256M -Xmn128m -XX:SurvivorRatio=4" +#fi + +#JAVA_OPT="${JAVA_OPT} -server -Xms2048M -Xmx4096M -Xmn2048m -XX:SurvivorRatio=4" +JAVA_OPT=`cat ${EVENTMESH_HOME}/conf/server.env | grep APP_START_JVM_OPTION::: | awk -F ':::' {'print $2'}` +JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" +JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${EVENTMESH_HOME}/logs/eventmesh_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${EVENTMESH_HOME}/logs -XX:ErrorFile=${EVENTMESH_HOME}/logs/hs_err_%p.log" +JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" +JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" +JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" +JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" +JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" +JAVA_OPT="${JAVA_OPT} -Dio.netty.leakDetectionLevel=advanced" +JAVA_OPT="${JAVA_OPT} -Dio.netty.allocator.type=pooled" +JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" +JAVA_OPT="${JAVA_OPT} -Dlog4j.configurationFile=${EVENTMESH_HOME}/conf/log4j2.xml" +JAVA_OPT="${JAVA_OPT} -Deventmesh.log.home=${EVENTMESH_LOG_HOME}" +JAVA_OPT="${JAVA_OPT} -DconfPath=${EVENTMESH_HOME}/conf" +JAVA_OPT="${JAVA_OPT} -Dlog4j2.AsyncQueueFullPolicy=Discard" +JAVA_OPT="${JAVA_OPT} -Drocketmq.client.logUseSlf4j=true" +JAVA_OPT="${JAVA_OPT} -DeventMeshPluginDir=${EVENTMESH_HOME}/plugin" + +#if [ -f "pid.file" ]; then +# pid=`cat pid.file` +# if ! is_proxyRunning "$pid"; then +# echo "proxy is running already" +# exit 9; +# else +# echo "err pid$pid, rm pid.file" +# rm pid.file +# fi +#fi + +pid=$(get_pid) +if [ -n "$pid" ];then + echo -e "ERROR\t the server is already running (pid=$pid), there is no need to execute start.sh again." + exit 9; +fi + +make_logs_dir + +echo "using jdk[$JAVA]" >> ${EVENTMESH_LOG_HOME}/eventmesh.out + + +EVENTMESH_MAIN=org.apache.eventmesh.runtime.boot.EventMeshStartup +if [ $DOCKER ] +then + $JAVA $JAVA_OPT -classpath ${EVENTMESH_HOME}/conf:${EVENTMESH_HOME}/apps/*:${EVENTMESH_HOME}/lib/* $EVENTMESH_MAIN >> ${EVENTMESH_LOG_HOME}/eventmesh.out +else + $JAVA $JAVA_OPT -classpath ${EVENTMESH_HOME}/conf:${EVENTMESH_HOME}/apps/*:${EVENTMESH_HOME}/lib/* $EVENTMESH_MAIN >> ${EVENTMESH_LOG_HOME}/eventmesh.out 2>&1 & +echo $!>pid.file +fi +exit 0 diff --git a/eventmesh-runtime/bin/stop.sh b/eventmesh-runtime/bin/stop.sh new file mode 100644 index 0000000000..e85fbf5ec1 --- /dev/null +++ b/eventmesh-runtime/bin/stop.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#detect operating system. +OS=$(uname) + +EVENTMESH_HOME=`cd $(dirname $0)/.. && pwd` + +export EVENTMESH_HOME + +function get_pid { + local ppid="" + if [ -f ${EVENTMESH_HOME}/bin/pid.file ]; then + ppid=$(cat ${EVENTMESH_HOME}/bin/pid.file) + else + if [[ $OS =~ Msys ]]; then + # There is a Bug on Msys that may not be able to kill the identified process + ppid=`jps -v | grep -i "org.apache.eventmesh.runtime.boot.EventMeshStartup" | grep java | grep -v grep | awk -F ' ' {'print $1'}` + elif [[ $OS =~ Darwin ]]; then + # Known problem: grep Java may not be able to accurately identify Java processes + ppid=$(/bin/ps -o user,pid,command | grep "java" | grep -i "org.apache.eventmesh.runtime.boot.EventMeshStartup" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + else + # It is required to identify the process as accurately as possible on Linux + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $EVENTMESH_HOME | grep -i "org.apache.eventmesh.runtime.boot.EventMeshStartup" | grep -Ev "^root" |awk -F ' ' {'print $2'}) + fi + fi + echo "$ppid"; +} + +pid=$(get_pid) +if [ -z "$pid" ];then + echo -e "No eventmesh running.." + exit 0; +fi + +kill ${pid} +echo "Send shutdown request to eventmesh(${pid}) OK" + +[[ $OS =~ Msys ]] && PS_PARAM=" -W " +stop_timeout=60 +for no in $(seq 1 $stop_timeout); do + if ps $PS_PARAM -p "$pid" 2>&1 > /dev/null; then + if [ $no -lt $stop_timeout ]; then + echo "[$no] shutdown server ..." + sleep 1 + continue + fi + + echo "shutdown server timeout, kill process: $pid" + kill -9 $pid; sleep 1; break; + echo "`date +'%Y-%m-%-d %H:%M:%S'` , pid : [$pid] , error message : abnormal shutdown which can not be closed within 60s" > ../logs/shutdown.error + else + echo "shutdown server ok!"; break; + fi +done + +if [ -f "pid.file" ]; then + rm pid.file +fi + + diff --git a/eventmesh-runtime/bin/watchdog.sh b/eventmesh-runtime/bin/watchdog.sh new file mode 100644 index 0000000000..9708e3b918 --- /dev/null +++ b/eventmesh-runtime/bin/watchdog.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e; + +function usage(){ + echo "Usage: watchdog.sh [option]"; + echo -e " -h, --help \t This help text." + echo -e " -a, --add-crontab \t add watchdog task to crontab." + echo -e " -d, --delete-crontab \t delete watchdog task from crontab." + echo -e " -w, --work\t run the watchdog program for ONE time." +} + +function add_crontab(){ + crontab -l | grep -v "$APP_HOME/bin/watchdog.sh" > tmp_crontab.txt || true + mkdir -p $APP_HOME/logs/ && touch $APP_HOME/logs/watchdog.log + echo "* * * * * $APP_HOME/bin/watchdog.sh -w >> $APP_HOME/logs/watchdog.log 2>&1" >> tmp_crontab.txt + crontab tmp_crontab.txt + rm -f tmp_crontab.txt +} + +function delete_crontab(){ + crontab -l | grep -v "$APP_HOME/bin/watchdog.sh" > tmp_crontab.txt || true + crontab tmp_crontab.txt + rm -f tmp_crontab.txt +} + +function restart_service(){ + echo "$(date) INFO stopping service ..." + ./stop.sh || { local code=$?; echo -e "$(date) ERROR\t failed to call stop.sh, code=$code."; exit $code; } + + echo "$(date) INFO starting service ..." + ./start.sh || { local code=$?; echo -e "$(date) ERROR\t failed to call start.sh, code=$code."; exit $code; } + echo "$(date) INFO service restarted." +} + +function work (){ + if [ ! -f "sys.pid" ]; then + echo -e "$(date) ERROR\t sys.pid file not found, try to restart service." + restart_service; + exit $?; + fi + + pid=$(cat sys.pid) + if ps -fp ${pid} 2>&1 > /dev/null; then + exit 0; + else + echo -e "$(date) ERROR\t process($pid) not found, try to restart service." + restart_service; + exit $?; + fi +} + +## script starts here. +APP_BIN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +APP_HOME="$(dirname $APP_BIN)"; [ -d "$APP_HOME" ] || { echo "ERROR Mumble SDK Internal Bug, failed to detect APP_HOME."; exit 1;} +# parse command line. +cd ${APP_BIN}; +OPTS=`getopt -o a::d::h::w:: --long add-crontab::,delete-crontab::,help::,work:: -- "$@"` +if [ $? != 0 ] ; then usage; exit 1 ; fi +eval set -- "$OPTS" +while true ; do + case "$1" in + -a|--add-crontab) add_crontab; exit $?;; + -d|--delete-crontab) delete_crontab; exit $?;; + -w|--work) work; exit $?;; + -h|--help) usage; exit 0;; + *) usage; exit 1 ;; + esac +done diff --git a/eventmesh-runtime/build.gradle b/eventmesh-runtime/build.gradle new file mode 100644 index 0000000000..8ee66a6143 --- /dev/null +++ b/eventmesh-runtime/build.gradle @@ -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. + */ + +def grpcVersion = '1.17.1' + +dependencies { + implementation 'io.cloudevents:cloudevents-core' + + implementation 'io.opentelemetry:opentelemetry-api' + implementation 'io.opentelemetry:opentelemetry-sdk' + implementation 'io.opentelemetry:opentelemetry-exporter-zipkin' + implementation 'io.opentelemetry:opentelemetry-semconv' + + implementation "org.apache.httpcomponents:httpclient" + implementation 'io.netty:netty-all' + + implementation 'com.github.seancfoley:ipaddress:5.3.3' + + implementation project(":eventmesh-common") + implementation project(":eventmesh-spi") + implementation project(":eventmesh-connector-plugin:eventmesh-connector-api") + implementation project(":eventmesh-connector-plugin:eventmesh-connector-standalone") + implementation project(":eventmesh-security-plugin:eventmesh-security-api") + implementation project(":eventmesh-security-plugin:eventmesh-security-acl") + implementation project(":eventmesh-security-plugin:eventmesh-security-auth-http-basic") + implementation project(":eventmesh-registry-plugin:eventmesh-registry-api") + implementation project(":eventmesh-admin:eventmesh-admin-rocketmq") + + + implementation project(":eventmesh-registry-plugin:eventmesh-registry-nacos") + implementation project(":eventmesh-registry-plugin:eventmesh-registry-etcd") + + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + + implementation "io.grpc:grpc-core:${grpcVersion}" + implementation "io.grpc:grpc-protobuf:${grpcVersion}" + implementation "io.grpc:grpc-stub:${grpcVersion}" + implementation "io.grpc:grpc-netty:${grpcVersion}" + implementation "io.grpc:grpc-netty-shaded:${grpcVersion}" + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + // for debug only, can be removed + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-cloudevents") + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-meshmessage") + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-openmessage") + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-http") + + implementation project(":eventmesh-metrics-plugin:eventmesh-metrics-api") + implementation project(":eventmesh-metrics-plugin:eventmesh-metrics-prometheus") + + implementation project(":eventmesh-trace-plugin:eventmesh-trace-api") + implementation project(":eventmesh-trace-plugin:eventmesh-trace-zipkin") + + implementation project(":eventmesh-webhook:eventmesh-webhook-admin") + implementation project(":eventmesh-webhook:eventmesh-webhook-api") + implementation project(":eventmesh-webhook:eventmesh-webhook-receive") + + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-inline" + testImplementation "org.powermock:powermock-module-junit4" + testImplementation "org.powermock:powermock-api-mockito2" +} diff --git a/eventmesh-runtime/conf/eventmesh.properties b/eventmesh-runtime/conf/eventmesh.properties new file mode 100644 index 0000000000..5ad8c14fd3 --- /dev/null +++ b/eventmesh-runtime/conf/eventmesh.properties @@ -0,0 +1,105 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +###############################EVNETMESH-runtime ENV################################# +eventMesh.server.idc=DEFAULT +eventMesh.server.env=PRD +eventMesh.server.cluster=COMMON +eventMesh.server.name=EVENTMESH-runtime +eventMesh.sysid=0000 +eventMesh.server.http.port=10105 +eventMesh.server.grpc.port=10205 +########################## eventMesh tcp configuration ############################ +eventMesh.server.tcp.enabled=true +eventMesh.server.tcp.port=10000 +eventMesh.server.tcp.readerIdleSeconds=120 +eventMesh.server.tcp.writerIdleSeconds=120 +eventMesh.server.tcp.allIdleSeconds=120 +eventMesh.server.tcp.clientMaxNum=10000 +# client isolation time if the message send failure +eventMesh.server.tcp.pushFailIsolateTimeInMills=30000 +# rebalance internal +eventMesh.server.tcp.RebalanceIntervalInMills=30000 +# session expire time about client +eventMesh.server.session.expiredInMills=60000 +# flow control, include the global level and session level +eventMesh.server.tcp.msgReqnumPerSecond=15000 +eventMesh.server.http.msgReqnumPerSecond=15000 +eventMesh.server.session.upstreamBufferSize=20 + +# for single event publish, maximum size allowed per event +eventMesh.server.maxEventSize=1000 +# for batch event publish, maximum number of events allowed in one batch +eventMesh.server.maxEventBatchSize=10 + +# thread number about global scheduler +eventMesh.server.global.scheduler=5 +eventMesh.server.tcp.taskHandleExecutorPoolSize=8 +#retry +eventMesh.server.retry.async.pushRetryTimes=3 +eventMesh.server.retry.sync.pushRetryTimes=3 +eventMesh.server.retry.async.pushRetryDelayInMills=500 +eventMesh.server.retry.sync.pushRetryDelayInMills=500 +eventMesh.server.retry.pushRetryQueueSize=10000 +#admin +eventMesh.server.admin.http.port=10106 +#registry +eventMesh.server.registry.registerIntervalInMills=10000 +eventMesh.server.registry.fetchRegistryAddrIntervalInMills=20000 +#auto-ack +#eventMesh.server.defibus.client.comsumeTimeoutInMin=5 + +#sleep interval between closing client of different group in server graceful shutdown +eventMesh.server.gracefulShutdown.sleepIntervalInMills=1000 +eventMesh.server.rebalanceRedirect.sleepIntervalInMills=200 + +#ip address blacklist +eventMesh.server.blacklist.ipv4=0.0.0.0/8,127.0.0.0/8,169.254.0.0/16,255.255.255.255/32 +eventMesh.server.blacklist.ipv6=::/128,::1/128,ff00::/8 + +#connector plugin +eventMesh.connector.plugin.type=standalone + +#security plugin +eventMesh.server.security.enabled=false +eventMesh.security.plugin.type=security + +#registry plugin +eventMesh.registry.plugin.enabled=false +eventMesh.registry.plugin.type=nacos +eventMesh.registry.plugin.server-addr=127.0.0.1:8848 +eventMesh.registry.plugin.username=nacos +eventMesh.registry.plugin.password=nacos + +# metrics plugin, if you have multiple plugin, you can use ',' to split +eventMesh.metrics.plugin=prometheus + +# trace plugin +eventMesh.server.trace.enabled=false +eventMesh.trace.plugin=zipkin + +# webhook +# Start webhook admin service +eventMesh.webHook.admin.start=true +# Webhook event configuration storage mode. Currently, only file and Nacos are supported +eventMesh.webHook.operationMode=file +# The file storage path of the file storage mode. If #{eventmeshhome} is written, it is in the eventmesh root directory +eventMesh.webHook.fileMode.filePath= #{eventMeshHome}/webhook +# Nacos storage mode, and the configuration naming rule is eventmesh webHook. nacosMode. {nacos native configuration key} please see the specific configuration [nacos github api](https://github.com/alibaba/nacos/blob/develop/api/src/main/java/com/alibaba/nacos/api/SystemPropertyKeyConst.java) +## Address of Nacos +eventMesh.webHook.nacosMode.serverAddr=127.0.0.1:8848 +# Webhook eventcloud sending mode. And eventmesh connector. plugin. The type configuration is the same +eventMesh.webHook.producer.connector=standalone diff --git a/eventmesh-runtime/conf/log4j2.xml b/eventmesh-runtime/conf/log4j2.xml new file mode 100644 index 0000000000..756abeac33 --- /dev/null +++ b/eventmesh-runtime/conf/log4j2.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eventmesh-runtime/conf/sChat2.jks b/eventmesh-runtime/conf/sChat2.jks new file mode 100644 index 0000000000..afaf8c949e Binary files /dev/null and b/eventmesh-runtime/conf/sChat2.jks differ diff --git a/eventmesh-runtime/conf/server.env b/eventmesh-runtime/conf/server.env new file mode 100644 index 0000000000..f8c01df100 --- /dev/null +++ b/eventmesh-runtime/conf/server.env @@ -0,0 +1,18 @@ +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +APP_START_JVM_OPTION:::-server -Xms128M -Xmx256M -Xmn128m -XX:SurvivorRatio=4 -Duser.language=zh diff --git a/eventmesh-runtime/gradle.properties b/eventmesh-runtime/gradle.properties new file mode 100644 index 0000000000..b1312a0905 --- /dev/null +++ b/eventmesh-runtime/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/eventmesh-runtime/scripts/before_shutdown.sh b/eventmesh-runtime/scripts/before_shutdown.sh new file mode 100644 index 0000000000..9cf8b624a9 --- /dev/null +++ b/eventmesh-runtime/scripts/before_shutdown.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +source session.sh | awk '{print $1}' | awk -F '=' '{print $2}' | awk -F '|' '{print $1,$2}' | grep 2019 > tmp.txt + +cat tmp.txt | while read line +do + cmd="./client_manage.sh -s $line" + $cmd + sleep 10s +done + +rm tmp.txt + +./client_manage.sh -a diff --git a/eventmesh-runtime/scripts/client_manage.sh b/eventmesh-runtime/scripts/client_manage.sh new file mode 100644 index 0000000000..0913cc58ec --- /dev/null +++ b/eventmesh-runtime/scripts/client_manage.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +i_eg="sh client_manage.sh -i 10.255.34.160 24591" +s_eg="sh client_manage.sh -s 5319" +r_eg="sh client_manage.sh -r 9876 10.255.1.143 10000" +a_eg="sh client_manage.sh -a" +x_eg="sh client_manage.sh -x 10.255.34.160 24591 10.255.1.143 10000" +y_eg="sh client_manage.sh -y bq-bypass 10.255.1.143 10000" + +function printEg() { + echo "param error." + echo "reject client by ip_port, eg : ${i_eg}" + echo "reject all clients, eg : ${a_eg}" + echo "reject clients by systemid, eg : ${s_eg}" + echo "redirect client by systemid, eg : ${r_eg}" + echo "redirect client by ip port, eg : ${x_eg}" + echo "redirect client by path, eg : ${y_eg}" +} + +#PORT=24591 +#localIp=`ifconfig|grep "inet addr:"|grep -v "127.0.0.1"|cut -d: -f2|awk '{print $1}'` +ADDR="127.0.0.1:10106" +echo "localAddress : ${ADDR}" +#parse command line options +ARGS=`getopt -o ai:s:r: --long -n 'client_manage.sh' -- "$@"` +if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi +eval set -- "$ARGS" + +while true +do + case "$3" in + -a|--all) + msg=`curl "http://${ADDR}/clientManage/rejectAllClient"`;echo ${msg};break;; + -i|--ipport) + CLIENT_IP=$4 + CLIENT_PORT=$5 + msg=`curl "http://${ADDR}/clientManage/rejectClientByIpPort?ip=${CLIENT_IP}&port=${CLIENT_PORT}"`;echo ${msg};break;; + -s|--subsystem) + SUB_SYSTEM=$4 + msg=`curl "http://${ADDR}/clientManage/rejectClientBySubSystem?subSystem=${SUB_SYSTEM}"`;echo ${msg};break;; + -x|--redirectbyip) + CLIENT_IP=$4 + CLIENT_PORT=$5 + DEST_PROXY_IP=$6 + DEST_PROXY_PORT=$7 + msg=`curl "http://${ADDR}/clientManage/redirectClientByIpPort?ip=${CLIENT_IP}&port=${CLIENT_PORT}&destProxyIp=${DEST_PROXY_IP}&destProxyPort=${DEST_PROXY_PORT}"`;echo ${msg};break;; + -y|--redirectbypath) + CLIENT_PATH=$4 + DEST_PROXY_IP=$5 + DEST_PROXY_PORT=$6 + msg=`curl "http://${ADDR}/clientManage/redirectClientByPath?path=${CLIENT_PATH}&destProxyIp=${DEST_PROXY_IP}&destProxyPort=${DEST_PROXY_PORT}"`;echo ${msg};break;; + -r|--redirect) + SUB_SYSTEM=$4 + DEST_PROXY_IP=$5 + DEST_PROXY_PORT=$6 + msg=`curl "http://${ADDR}/clientManage/redirectClientBySubSystem?subSystem=${SUB_SYSTEM}&destProxyIp=${DEST_PROXY_IP}&destProxyPort=${DEST_PROXY_PORT}"`;echo ${msg};break;; + --) + shift; + break;; + *) + printEg; + exit 1;; + esac +done diff --git a/eventmesh-runtime/scripts/connections.sh b/eventmesh-runtime/scripts/connections.sh new file mode 100644 index 0000000000..2f691c861f --- /dev/null +++ b/eventmesh-runtime/scripts/connections.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e +date; +echo -e "active eventmesh connections:\n$(netstat -lnap |grep EST | grep $(jps | grep EventMeshStartup | cut -d" " -f1) | awk -F"[\t ]+" '{print $4}' |sort| uniq -c | sort -rnk1 | grep ":10000")" +echo -e "active mq connections:\n$(netstat -lnap |grep EST | grep $(jps | grep EventMeshStartup | cut -d" " -f1) | awk -F"[\t ]+" '{print $5}' |sort | uniq -c | sort -rnk1 |grep -E "10911|9876")" diff --git a/eventmesh-runtime/scripts/histo.sh b/eventmesh-runtime/scripts/histo.sh new file mode 100644 index 0000000000..7d56351082 --- /dev/null +++ b/eventmesh-runtime/scripts/histo.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e +script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $script_path +echo "[`date`] WARNING this script will PAUSE jvm for seconds." +pid=$(jcmd | grep EventMeshStartup | cut -d" " -f1) +jmap -histo:live $pid | tee $script_path/../logs/histo.$(date +%m%d%H%M).$pid.log diff --git a/eventmesh-runtime/scripts/histo_suspects.sh b/eventmesh-runtime/scripts/histo_suspects.sh new file mode 100644 index 0000000000..82eaa0b8f7 --- /dev/null +++ b/eventmesh-runtime/scripts/histo_suspects.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e +script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $script_path +echo "[`date`] WARNING this script will PAUSE jvm for seconds." +pid=$(jcmd | grep EventMeshStartup | cut -d" " -f1) +./histo.sh | grep -E "RRResponseFurture|PushConsumer|PullMessage|RR|RunnableAdapter|instance|ProducerFactory|ClientInstance|Session" | tee $script_path/../logs/histo.suspects.$(date +%m%d%H%M).$pid.log diff --git a/eventmesh-runtime/scripts/jstack.sh b/eventmesh-runtime/scripts/jstack.sh new file mode 100644 index 0000000000..ca6e2fdbff --- /dev/null +++ b/eventmesh-runtime/scripts/jstack.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e +script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +echo "[`date`] WARNING this script will PAUSE jvm for seconds." +pid=$(jcmd | grep EventMeshStartup | cut -d" " -f1) +jstack $pid | tee $script_path/../logs/jstack.$(date +%m%d%H%M).$pid.log diff --git a/eventmesh-runtime/scripts/monitor_connections.sh b/eventmesh-runtime/scripts/monitor_connections.sh new file mode 100644 index 0000000000..fdaf1f63f6 --- /dev/null +++ b/eventmesh-runtime/scripts/monitor_connections.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e +script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $script_path +while true; do + ./connections.sh + sleep 60s; +done diff --git a/eventmesh-runtime/scripts/monitor_histo_suspects.sh b/eventmesh-runtime/scripts/monitor_histo_suspects.sh new file mode 100644 index 0000000000..35732cf128 --- /dev/null +++ b/eventmesh-runtime/scripts/monitor_histo_suspects.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e +script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $script_path +while true; do + ./histo_suspects.sh + sleep 60s; +done diff --git a/eventmesh-runtime/scripts/monitor_threads.sh b/eventmesh-runtime/scripts/monitor_threads.sh new file mode 100644 index 0000000000..acf766e353 --- /dev/null +++ b/eventmesh-runtime/scripts/monitor_threads.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -e +script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $script_path +while true; do + ./threads.sh + sleep 60s; +done diff --git a/eventmesh-runtime/scripts/session.sh b/eventmesh-runtime/scripts/session.sh new file mode 100644 index 0000000000..3540cf8546 --- /dev/null +++ b/eventmesh-runtime/scripts/session.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +if [ $# -eq 0 ] +then + curl -s 'http://127.0.0.1:10106/clientManage/showClient?' +elif [ $# -eq 1 ] +then + TOPIC=$1 + curl -s "http://127.0.0.1:10106/clientManage/showListenClientByTopic?topic=${TOPIC}" +else + CLIENT_SYSTEM=$1 + curl -s "http://127.0.0.1:10106/clientManage/showClientBySystem?subSystem=${CLIENT_SYSTEM}" +fi diff --git a/eventmesh-runtime/scripts/threads.sh b/eventmesh-runtime/scripts/threads.sh new file mode 100644 index 0000000000..fe1eeb5d7f --- /dev/null +++ b/eventmesh-runtime/scripts/threads.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# Licensed to Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Apache Software Foundation (ASF) licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +jstack $(jcmd | grep EventMeshStartup | cut -d" " -f1) | \ + grep -vE "(Concurrent GC|DestroyJavaVM|Gang worker|Compiler|Attach Listener|GC Thread|VM Thread|Finalizer)" | \ + grep -oE '^".*?"' | \ + sed -r 's/"(.+)(-|_)([0-9]+).*"/\1/g' | \ + sort | uniq -c | sort -nk1 diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/acl/Acl.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/acl/Acl.java new file mode 100644 index 0000000000..c37f3ed94b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/acl/Acl.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.acl; + +import org.apache.eventmesh.api.acl.AclPropertyKeys; +import org.apache.eventmesh.api.acl.AclService; +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Properties; +import java.util.ServiceLoader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Acl { + private static final Logger logger = LoggerFactory.getLogger(Acl.class); + private static AclService aclService; + + public void init(String aclPluginType) throws AclException { + aclService = EventMeshExtensionFactory.getExtension(AclService.class, aclPluginType); + if (aclService == null) { + logger.error("can't load the aclService plugin, please check."); + throw new RuntimeException("doesn't load the aclService plugin, please check."); + } + aclService.init(); + } + + public void start() throws AclException { + aclService.start(); + } + + public void shutdown() throws AclException { + aclService.shutdown(); + } + + public static void doAclCheckInTcpConnect(String remoteAddr, UserAgent userAgent, int requestCode) throws AclException { + aclService.doAclCheckInConnect(buildTcpAclProperties(remoteAddr, userAgent, null, requestCode)); + } + + public static void doAclCheckInTcpHeartbeat(String remoteAddr, UserAgent userAgent, int requestCode) throws AclException { + aclService.doAclCheckInHeartbeat(buildTcpAclProperties(remoteAddr, userAgent, null, requestCode)); + } + + public static void doAclCheckInTcpSend(String remoteAddr, UserAgent userAgent, String topic, int requestCode) throws AclException { + aclService.doAclCheckInSend(buildTcpAclProperties(remoteAddr, userAgent, topic, requestCode)); + } + + public static void doAclCheckInTcpReceive(String remoteAddr, UserAgent userAgent, String topic, int requestCode) throws AclException { + aclService.doAclCheckInReceive(buildTcpAclProperties(remoteAddr, userAgent, topic, requestCode)); + } + + private static Properties buildTcpAclProperties(String remoteAddr, UserAgent userAgent, String topic, int requestCode) { + Properties aclProperties = new Properties(); + aclProperties.put(AclPropertyKeys.CLIENT_IP, remoteAddr); + aclProperties.put(AclPropertyKeys.USER, userAgent.getUsername()); + aclProperties.put(AclPropertyKeys.PASSWORD, userAgent.getPassword()); + aclProperties.put(AclPropertyKeys.SUBSYSTEM, userAgent.getSubsystem()); + aclProperties.put(AclPropertyKeys.REQUEST_CODE, requestCode); + if (StringUtils.isNotBlank(topic)) { + aclProperties.put(AclPropertyKeys.TOPIC, topic); + } + return aclProperties; + } + + public static void doAclCheckInHttpSend(String remoteAddr, String user, String pass, String subsystem, String topic, + int requestCode) throws AclException { + aclService.doAclCheckInSend(buildHttpAclProperties(remoteAddr, user, pass, subsystem, topic, requestCode)); + } + + public static void doAclCheckInHttpSend(String remoteAddr, String user, String pass, String subsystem, String topic, + String requestURI) throws AclException { + aclService.doAclCheckInSend(buildHttpAclProperties(remoteAddr, user, pass, subsystem, topic, requestURI)); + } + + public static void doAclCheckInHttpReceive(String remoteAddr, String user, String pass, String subsystem, String topic, + int requestCode) throws AclException { + aclService.doAclCheckInReceive(buildHttpAclProperties(remoteAddr, user, pass, subsystem, topic, requestCode)); + } + + public static void doAclCheckInHttpReceive(String remoteAddr, String user, String pass, String subsystem, String topic, + String requestURI) throws AclException { + aclService.doAclCheckInReceive(buildHttpAclProperties(remoteAddr, user, pass, subsystem, topic, requestURI)); + } + + public static void doAclCheckInHttpHeartbeat(String remoteAddr, String user, String pass, String subsystem, String topic, + int requestCode) throws AclException { + aclService.doAclCheckInHeartbeat(buildHttpAclProperties(remoteAddr, user, pass, subsystem, topic, requestCode)); + } + + private static Properties buildHttpAclProperties(String remoteAddr, String user, String pass, String subsystem, + String topic, int requestCode) { + Properties aclProperties = new Properties(); + aclProperties.put(AclPropertyKeys.CLIENT_IP, remoteAddr); + aclProperties.put(AclPropertyKeys.USER, user); + aclProperties.put(AclPropertyKeys.PASSWORD, pass); + aclProperties.put(AclPropertyKeys.SUBSYSTEM, subsystem); + aclProperties.put(AclPropertyKeys.REQUEST_CODE, requestCode); + if (StringUtils.isNotBlank(topic)) { + aclProperties.put(AclPropertyKeys.TOPIC, topic); + } + return aclProperties; + } + + private static Properties buildHttpAclProperties(String remoteAddr, String user, String pass, String subsystem, + String topic, String requestURI) { + Properties aclProperties = new Properties(); + aclProperties.put(AclPropertyKeys.CLIENT_IP, remoteAddr); + aclProperties.put(AclPropertyKeys.USER, user); + aclProperties.put(AclPropertyKeys.PASSWORD, pass); + aclProperties.put(AclPropertyKeys.SUBSYSTEM, subsystem); + aclProperties.put(AclPropertyKeys.REQUEST_URI, requestURI); + if (StringUtils.isNotBlank(topic)) { + aclProperties.put(AclPropertyKeys.TOPIC, topic); + } + return aclProperties; + } + + private AclService getSpiAclService() { + ServiceLoader serviceLoader = ServiceLoader.load(AclService.class); + if (serviceLoader.iterator().hasNext()) { + return serviceLoader.iterator().next(); + } + return null; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/controller/ClientManageController.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/controller/ClientManageController.java new file mode 100644 index 0000000000..5084a9de12 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/controller/ClientManageController.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.controller; + +import org.apache.eventmesh.admin.rocketmq.controller.AdminController; +import org.apache.eventmesh.runtime.admin.handler.DeleteWebHookConfigHandler; +import org.apache.eventmesh.runtime.admin.handler.InsertWebHookConfigHandler; +import org.apache.eventmesh.runtime.admin.handler.QueryRecommendEventMeshHandler; +import org.apache.eventmesh.runtime.admin.handler.QueryWebHookConfigByIdHandler; +import org.apache.eventmesh.runtime.admin.handler.QueryWebHookConfigByManufacturerHandler; +import org.apache.eventmesh.runtime.admin.handler.RedirectClientByIpPortHandler; +import org.apache.eventmesh.runtime.admin.handler.RedirectClientByPathHandler; +import org.apache.eventmesh.runtime.admin.handler.RedirectClientBySubSystemHandler; +import org.apache.eventmesh.runtime.admin.handler.RejectAllClientHandler; +import org.apache.eventmesh.runtime.admin.handler.RejectClientByIpPortHandler; +import org.apache.eventmesh.runtime.admin.handler.RejectClientBySubSystemHandler; +import org.apache.eventmesh.runtime.admin.handler.ShowClientBySystemHandler; +import org.apache.eventmesh.runtime.admin.handler.ShowClientHandler; +import org.apache.eventmesh.runtime.admin.handler.ShowListenClientByTopicHandler; +import org.apache.eventmesh.runtime.admin.handler.UpdateWebHookConfigHandler; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.webhook.admin.AdminWebHookConfigOperationManage; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpServer; + +import lombok.Setter; + +@SuppressWarnings("restriction") +public class ClientManageController { + + private static final Logger logger = LoggerFactory.getLogger(ClientManageController.class); + + private EventMeshTCPServer eventMeshTCPServer; + + private AdminController adminController; + + @Setter + private AdminWebHookConfigOperationManage adminWebHookConfigOperationManage; + + public ClientManageController(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + + public void start() throws IOException { + int port = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerAdminPort; + HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); + server.createContext("/clientManage/showClient", new ShowClientHandler(eventMeshTCPServer)); + server.createContext("/clientManage/showClientBySystem", new ShowClientBySystemHandler(eventMeshTCPServer)); + server.createContext("/clientManage/rejectAllClient", new RejectAllClientHandler(eventMeshTCPServer)); + server.createContext("/clientManage/rejectClientByIpPort", new RejectClientByIpPortHandler(eventMeshTCPServer)); + server.createContext("/clientManage/rejectClientBySubSystem", new RejectClientBySubSystemHandler(eventMeshTCPServer)); + server.createContext("/clientManage/redirectClientBySubSystem", new RedirectClientBySubSystemHandler(eventMeshTCPServer)); + server.createContext("/clientManage/redirectClientByPath", new RedirectClientByPathHandler(eventMeshTCPServer)); + server.createContext("/clientManage/redirectClientByIpPort", new RedirectClientByIpPortHandler(eventMeshTCPServer)); + server.createContext("/clientManage/showListenClientByTopic", new ShowListenClientByTopicHandler(eventMeshTCPServer)); + server.createContext("/eventMesh/recommend", new QueryRecommendEventMeshHandler(eventMeshTCPServer)); + + if (Objects.nonNull(adminWebHookConfigOperationManage.getWebHookConfigOperation())) { + WebHookConfigOperation webHookConfigOperation = adminWebHookConfigOperationManage.getWebHookConfigOperation(); + server.createContext("/webhook/insertWebHookConfig", new InsertWebHookConfigHandler(webHookConfigOperation)); + server.createContext("/webhook/updateWebHookConfig", new UpdateWebHookConfigHandler(webHookConfigOperation)); + server.createContext("/webhook/deleteWebHookConfig", new DeleteWebHookConfigHandler(webHookConfigOperation)); + server.createContext("/webhook/queryWebHookConfigById", new QueryWebHookConfigByIdHandler(webHookConfigOperation)); + server.createContext("/webhook/queryWebHookConfigByManufacturer", new QueryWebHookConfigByManufacturerHandler(webHookConfigOperation)); + } + + adminController = new AdminController(); + adminController.run(server); + + server.start(); + logger.info("ClientManageController start success, port:{}", port); + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/DeleteWebHookConfigHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/DeleteWebHookConfigHandler.java new file mode 100644 index 0000000000..bad9da5353 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/DeleteWebHookConfigHandler.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.admin.rocketmq.util.JsonUtils; +import org.apache.eventmesh.admin.rocketmq.util.NetUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; + +import java.io.IOException; +import java.io.OutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class DeleteWebHookConfigHandler implements HttpHandler { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private WebHookConfigOperation operation; + + public DeleteWebHookConfigHandler(WebHookConfigOperation operation) { + this.operation = operation; + } + + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + httpExchange.sendResponseHeaders(200, 0); + + // get requestBody and resolve to WebHookConfig + String requestBody = NetUtils.parsePostBody(httpExchange); + WebHookConfig webHookConfig = JsonUtils.toObject(requestBody, WebHookConfig.class); + + try (OutputStream out = httpExchange.getResponseBody()) { + + Integer code = operation.deleteWebHookConfig(webHookConfig); // operating result + String result = 1 == code ? "deleteWebHookConfig Succeed!" : "deleteWebHookConfig Failed!"; + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("get WebHookConfigOperation implementation Failed.", e); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/InsertWebHookConfigHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/InsertWebHookConfigHandler.java new file mode 100644 index 0000000000..1434b16a8b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/InsertWebHookConfigHandler.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.admin.rocketmq.util.JsonUtils; +import org.apache.eventmesh.admin.rocketmq.util.NetUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; + + +import java.io.IOException; +import java.io.OutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class InsertWebHookConfigHandler implements HttpHandler { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private WebHookConfigOperation operation; + + public InsertWebHookConfigHandler(WebHookConfigOperation operation) { + this.operation = operation; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + httpExchange.sendResponseHeaders(200, 0); + + // get requestBody and resolve to WebHookConfig + String requestBody = NetUtils.parsePostBody(httpExchange); + WebHookConfig webHookConfig = JsonUtils.toObject(requestBody, WebHookConfig.class); + + try (OutputStream out = httpExchange.getResponseBody()) { + Integer code = operation.insertWebHookConfig(webHookConfig); // operating result + String result = 1 == code ? "insertWebHookConfig Succeed!" : "insertWebHookConfig Failed!"; + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("get WebHookConfigOperation implementation Failed.", e); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryRecommendEventMeshHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryRecommendEventMeshHandler.java new file mode 100644 index 0000000000..51ebf9e68c --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryRecommendEventMeshHandler.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend.EventMeshRecommendImpl; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend.EventMeshRecommendStrategy; +import org.apache.eventmesh.runtime.util.NetUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +/** + * query recommend eventmesh + */ +public class QueryRecommendEventMeshHandler implements HttpHandler { + + private Logger logger = LoggerFactory.getLogger(QueryRecommendEventMeshHandler.class); + + private final EventMeshTCPServer eventMeshTCPServer; + + public QueryRecommendEventMeshHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + if (!eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerRegistryEnable) { + throw new Exception("registry enable config is false, not support"); + } + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String group = queryStringInfo.get(EventMeshConstants.MANAGE_GROUP); + String purpose = queryStringInfo.get(EventMeshConstants.MANAGE_PURPOSE); + if (StringUtils.isBlank(group) || StringUtils.isBlank(purpose)) { + httpExchange.sendResponseHeaders(200, 0); + result = "params illegal!"; + out.write(result.getBytes()); + return; + } + + EventMeshRecommendStrategy eventMeshRecommendStrategy = new EventMeshRecommendImpl(eventMeshTCPServer); + String recommendEventMeshResult = eventMeshRecommendStrategy.calculateRecommendEventMesh(group, purpose); + result = (recommendEventMeshResult == null) ? "null" : recommendEventMeshResult; + logger.info("recommend eventmesh:{},group:{},purpose:{}", result, group, purpose); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("QueryRecommendEventMeshHandler fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryWebHookConfigByIdHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryWebHookConfigByIdHandler.java new file mode 100644 index 0000000000..6e1345cd1c --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryWebHookConfigByIdHandler.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.admin.rocketmq.util.JsonUtils; +import org.apache.eventmesh.admin.rocketmq.util.NetUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; + +import java.io.IOException; +import java.io.OutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class QueryWebHookConfigByIdHandler implements HttpHandler { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private WebHookConfigOperation operation; + + public QueryWebHookConfigByIdHandler(WebHookConfigOperation operation) { + this.operation = operation; + } + + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + httpExchange.sendResponseHeaders(200, 0); + httpExchange.getResponseHeaders().add("Content-Type", "application/json"); + + // get requestBody and resolve to WebHookConfig + String requestBody = NetUtils.parsePostBody(httpExchange); + WebHookConfig webHookConfig = JsonUtils.toObject(requestBody, WebHookConfig.class); + + try (OutputStream out = httpExchange.getResponseBody()) { + WebHookConfig result = operation.queryWebHookConfigById(webHookConfig); // operating result + out.write(JsonUtils.toJson(result).getBytes()); + } catch (Exception e) { + logger.error("get WebHookConfigOperation implementation Failed.", e); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryWebHookConfigByManufacturerHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryWebHookConfigByManufacturerHandler.java new file mode 100644 index 0000000000..81f5d808c5 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/QueryWebHookConfigByManufacturerHandler.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.admin.rocketmq.util.JsonUtils; +import org.apache.eventmesh.admin.rocketmq.util.NetUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class QueryWebHookConfigByManufacturerHandler implements HttpHandler { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private WebHookConfigOperation operation; + + public QueryWebHookConfigByManufacturerHandler(WebHookConfigOperation operation) { + this.operation = operation; + } + + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + httpExchange.sendResponseHeaders(200, 0); + httpExchange.getResponseHeaders().add("Content-Type", "application/json"); + + // get requestBody and resolve to WebHookConfig + String requestBody = NetUtils.parsePostBody(httpExchange); + JsonNode node = JsonUtils.getJsonNode(requestBody); + WebHookConfig webHookConfig = JsonUtils.toObject(node.get("webHookConfig").toString(), WebHookConfig.class); + Integer pageNum = Integer.parseInt(node.get("pageNum").toString()); + Integer pageSize = Integer.parseInt(node.get("pageSize").toString()); + + try (OutputStream out = httpExchange.getResponseBody()) { + List result = operation.queryWebHookConfigByManufacturer(webHookConfig, pageNum, pageSize); // operating result + out.write(JsonUtils.toJson(result).getBytes()); + } catch (Exception e) { + logger.error("get WebHookConfigOperation implementation Failed.", e); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByIpPortHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByIpPortHandler.java new file mode 100644 index 0000000000..2039c227f2 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByIpPortHandler.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class RedirectClientByIpPortHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(RedirectClientByIpPortHandler.class); + + private final EventMeshTCPServer eventMeshTCPServer; + + public RedirectClientByIpPortHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String ip = queryStringInfo.get(EventMeshConstants.MANAGE_IP); + String port = queryStringInfo.get(EventMeshConstants.MANAGE_PORT); + String destEventMeshIp = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_IP); + String destEventMeshPort = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_PORT); + + if (StringUtils.isBlank(ip) || !StringUtils.isNumeric(port) + || StringUtils.isBlank(destEventMeshIp) || StringUtils.isBlank(destEventMeshPort) + || !StringUtils.isNumeric(destEventMeshPort)) { + httpExchange.sendResponseHeaders(200, 0); + result = "params illegal!"; + out.write(result.getBytes()); + return; + } + logger.info("redirectClientByIpPort in admin,ip:{},port:{},destIp:{},destPort:{}====================", ip, + port, destEventMeshIp, destEventMeshPort); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); + String redirectResult = ""; + try { + if (!sessionMap.isEmpty()) { + for (Session session : sessionMap.values()) { + if (session.getClient().getHost().equals(ip) && String.valueOf( + session.getClient().getPort()).equals(port)) { + redirectResult += "|"; + redirectResult += EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer, + destEventMeshIp, Integer.parseInt(destEventMeshPort), + session, clientSessionGroupMapping); + } + } + } + } catch (Exception e) { + logger.error("clientManage|redirectClientByIpPort|fail|ip={}|port={}|destEventMeshIp" + + + "={}|destEventMeshPort={},errMsg={}", ip, port, destEventMeshIp, destEventMeshPort, e); + result = String.format("redirectClientByIpPort fail! sessionMap size {%d}, {clientIp=%s clientPort=%s " + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s}, errorMsg : %s", + sessionMap.size(), ip, port, destEventMeshIp, destEventMeshPort, redirectResult, e + .getMessage()); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + return; + } + result = String.format("redirectClientByIpPort success! sessionMap size {%d}, {ip=%s port=%s " + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", + sessionMap.size(), ip, port, destEventMeshIp, destEventMeshPort, redirectResult); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("redirectClientByIpPort fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByPathHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByPathHandler.java new file mode 100644 index 0000000000..b5f83ac890 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByPathHandler.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +/** + * redirect subsystem for path + */ +public class RedirectClientByPathHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(RedirectClientByPathHandler.class); + + private EventMeshTCPServer eventMeshTCPServer; + + public RedirectClientByPathHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String path = queryStringInfo.get(EventMeshConstants.MANAGE_PATH); + String destEventMeshIp = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_IP); + String destEventMeshPort = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_PORT); + + if (StringUtils.isBlank(path) || StringUtils.isBlank(destEventMeshIp) + || StringUtils.isBlank(destEventMeshPort) + || !StringUtils.isNumeric(destEventMeshPort)) { + httpExchange.sendResponseHeaders(200, 0); + result = "params illegal!"; + out.write(result.getBytes()); + return; + } + logger.info("redirectClientByPath in admin,path:{},destIp:{},destPort:{}====================", path, + destEventMeshIp, destEventMeshPort); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); + String redirectResult = ""; + try { + if (!sessionMap.isEmpty()) { + for (Session session : sessionMap.values()) { + if (session.getClient().getPath().contains(path)) { + redirectResult += "|"; + redirectResult += EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer, + destEventMeshIp, Integer.parseInt(destEventMeshPort), + session, clientSessionGroupMapping); + } + } + } + } catch (Exception e) { + logger.error("clientManage|redirectClientByPath|fail|path={}|destEventMeshIp" + + + "={}|destEventMeshPort={},errMsg={}", path, destEventMeshIp, destEventMeshPort, e); + result = String.format("redirectClientByPath fail! sessionMap size {%d}, {path=%s " + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s}, errorMsg : %s", + sessionMap.size(), path, destEventMeshIp, destEventMeshPort, redirectResult, e + .getMessage()); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + return; + } + result = String.format("redirectClientByPath success! sessionMap size {%d}, {path=%s " + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", + sessionMap.size(), path, destEventMeshIp, destEventMeshPort, redirectResult); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("redirectClientByPath fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientBySubSystemHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientBySubSystemHandler.java new file mode 100644 index 0000000000..6fae83c30f --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientBySubSystemHandler.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +/** + * redirect subsystem for subsys and dcn + */ +public class RedirectClientBySubSystemHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(RedirectClientBySubSystemHandler.class); + + private final EventMeshTCPServer eventMeshTCPServer; + + public RedirectClientBySubSystemHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String subSystem = queryStringInfo.get(EventMeshConstants.MANAGE_SUBSYSTEM); + String destEventMeshIp = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_IP); + String destEventMeshPort = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_PORT); + + if (!StringUtils.isNumeric(subSystem) + || StringUtils.isBlank(destEventMeshIp) || StringUtils.isBlank(destEventMeshPort) + || !StringUtils.isNumeric(destEventMeshPort)) { + httpExchange.sendResponseHeaders(200, 0); + result = "params illegal!"; + out.write(result.getBytes()); + return; + } + logger.info("redirectClientBySubSystem in admin,subsys:{},destIp:{},destPort:{}====================", + subSystem, destEventMeshIp, destEventMeshPort); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); + String redirectResult = ""; + try { + if (!sessionMap.isEmpty()) { + for (Session session : sessionMap.values()) { + if (session.getClient().getSubsystem().equals(subSystem)) { + redirectResult += "|"; + redirectResult += EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer, + destEventMeshIp, Integer.parseInt(destEventMeshPort), + session, clientSessionGroupMapping); + } + } + } + } catch (Exception e) { + logger.error("clientManage|redirectClientBySubSystem|fail|subSystem={}|destEventMeshIp" + + + "={}|destEventMeshPort={},errMsg={}", subSystem, destEventMeshIp, destEventMeshPort, e); + result = String.format("redirectClientBySubSystem fail! sessionMap size {%d}, {subSystem=%s " + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s}, errorMsg : %s", + sessionMap.size(), subSystem, destEventMeshIp, destEventMeshPort, redirectResult, e + .getMessage()); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + return; + } + result = String.format("redirectClientBySubSystem success! sessionMap size {%d}, {subSystem=%s " + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", + sessionMap.size(), subSystem, destEventMeshIp, destEventMeshPort, redirectResult); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("redirectClientBySubSystem fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectAllClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectAllClientHandler.java new file mode 100644 index 0000000000..ca445a3b44 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectAllClientHandler.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class RejectAllClientHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(RejectAllClientHandler.class); + + private final EventMeshTCPServer eventMeshTCPServer; + + public RejectAllClientHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + /** + * remove all clients accessed by eventMesh + * + * @param httpExchange + * @throws IOException + */ + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); + final List successRemoteAddrs = new ArrayList<>(); + try { + logger.info("rejectAllClient in admin===================="); + if (!sessionMap.isEmpty()) { + for (Map.Entry entry : sessionMap.entrySet()) { + InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client( + eventMeshTCPServer, entry.getValue(), clientSessionGroupMapping); + if (addr != null) { + successRemoteAddrs.add(addr); + } + } + } + } catch (Exception e) { + logger.error("clientManage|rejectAllClient|fail", e); + result = String.format("rejectAllClient fail! sessionMap size {%d}, had reject {%s}, errorMsg : %s", + sessionMap.size(), NetUtils.addressToString(successRemoteAddrs), e.getMessage()); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + return; + } + result = String.format("rejectAllClient success! sessionMap size {%d}, had reject {%s}", sessionMap.size(), + NetUtils.addressToString(successRemoteAddrs)); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("rejectAllClient fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectClientByIpPortHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectClientByIpPortHandler.java new file mode 100644 index 0000000000..00533f59d5 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectClientByIpPortHandler.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class RejectClientByIpPortHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(RejectClientByIpPortHandler.class); + + private EventMeshTCPServer eventMeshTCPServer; + + public RejectClientByIpPortHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String ip = queryStringInfo.get(EventMeshConstants.MANAGE_IP); + String port = queryStringInfo.get(EventMeshConstants.MANAGE_PORT); + + if (StringUtils.isBlank(ip) || StringUtils.isBlank(port)) { + httpExchange.sendResponseHeaders(200, 0); + result = "params illegal!"; + out.write(result.getBytes()); + return; + } + logger.info("rejectClientByIpPort in admin,ip:{},port:{}====================", ip, port); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); + final List successRemoteAddrs = new ArrayList(); + try { + if (!sessionMap.isEmpty()) { + for (Map.Entry entry : sessionMap.entrySet()) { + if (entry.getKey().getHostString().equals(ip) && String.valueOf(entry.getKey().getPort()).equals(port)) { + InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, + entry.getValue(), clientSessionGroupMapping); + if (addr != null) { + successRemoteAddrs.add(addr); + } + } + } + } + } catch (Exception e) { + logger.error("clientManage|rejectClientByIpPort|fail|ip={}|port={},errMsg={}", ip, port, e); + result = String.format("rejectClientByIpPort fail! {ip=%s port=%s}, had reject {%s}, errorMsg : %s", ip, + port, NetUtils.addressToString(successRemoteAddrs), e.getMessage()); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + return; + } + + result = String.format("rejectClientByIpPort success! {ip=%s port=%s}, had reject {%s}", ip, port, + NetUtils.addressToString(successRemoteAddrs)); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("rejectClientByIpPort fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectClientBySubSystemHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectClientBySubSystemHandler.java new file mode 100644 index 0000000000..90cca19104 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RejectClientBySubSystemHandler.java @@ -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 org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class RejectClientBySubSystemHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(RejectClientBySubSystemHandler.class); + + private EventMeshTCPServer eventMeshTCPServer; + + public RejectClientBySubSystemHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + private String printClients(List clients) { + if (clients.isEmpty()) { + return "no session had been closed"; + } + StringBuilder sb = new StringBuilder(); + for (InetSocketAddress addr : clients) { + sb.append(addr).append("|"); + } + return sb.toString(); + } + + /** + * remove c client by dcn and susysId + * + * @param httpExchange + * @throws IOException + */ + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String subSystem = queryStringInfo.get(EventMeshConstants.MANAGE_SUBSYSTEM); + + if (StringUtils.isBlank(subSystem)) { + httpExchange.sendResponseHeaders(200, 0); + result = "params illegal!"; + out.write(result.getBytes()); + return; + } + + logger.info("rejectClientBySubSystem in admin,subsys:{}====================", subSystem); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); + final List successRemoteAddrs = new ArrayList(); + try { + if (!sessionMap.isEmpty()) { + for (Session session : sessionMap.values()) { + if (session.getClient().getSubsystem().equals(subSystem)) { + InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, session, clientSessionGroupMapping); + if (addr != null) { + successRemoteAddrs.add(addr); + } + } + } + } + } catch (Exception e) { + logger.error("clientManage|rejectClientBySubSystem|fail|subSystemId={},errMsg={}", subSystem, e); + result = String.format("rejectClientBySubSystem fail! sessionMap size {%d}, had reject {%d} , {" + + + "subSystemId=%s}, errorMsg : %s", sessionMap.size(), printClients(successRemoteAddrs), subSystem, e.getMessage()); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + return; + } + result = String.format("rejectClientBySubSystem success! sessionMap size {%d}, had reject {%s} , {" + + + "subSystemId=%s}", sessionMap.size(), printClients(successRemoteAddrs), subSystem); + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("rejectClientBySubSystem fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowClientBySystemHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowClientBySystemHandler.java new file mode 100644 index 0000000000..29d4cd58bd --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowClientBySystemHandler.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class ShowClientBySystemHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(ShowClientBySystemHandler.class); + + private final EventMeshTCPServer eventMeshTCPServer; + + public ShowClientBySystemHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + /** + * print clientInfo by subsys + * + * @param httpExchange + * @throws IOException + */ + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String subSystem = queryStringInfo.get(EventMeshConstants.MANAGE_SUBSYSTEM); + + String newLine = System.getProperty("line.separator"); + logger.info("showClientBySubsys,subsys:{}=================", subSystem); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); + if (!sessionMap.isEmpty()) { + for (Session session : sessionMap.values()) { + if (session.getClient().getSubsystem().equals(subSystem)) { + UserAgent userAgent = session.getClient(); + result += String.format("pid=%s | ip=%s | port=%s | path=%s | purpose=%s", userAgent.getPid(), userAgent + .getHost(), userAgent.getPort(), userAgent.getPath(), userAgent.getPurpose()) + newLine; + } + } + } + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("ShowClientBySystemAndHandler fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + } + + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowClientHandler.java new file mode 100644 index 0000000000..9c28f53166 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowClientHandler.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +/** + * This handler used to print the total client info + */ +public class ShowClientHandler implements HttpHandler { + + private static final Logger logger = LoggerFactory.getLogger(ShowClientHandler.class); + + private final EventMeshTCPServer eventMeshTCPServer; + + public ShowClientHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String newLine = System.getProperty("line.separator"); + logger.info("showAllClient================="); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + + HashMap statMap = new HashMap(); + + Map sessionMap = clientSessionGroupMapping.getSessionMap(); + if (!sessionMap.isEmpty()) { + for (Session session : sessionMap.values()) { + String key = session.getClient().getSubsystem(); + if (!statMap.containsKey(key)) { + statMap.put(key, new AtomicInteger(1)); + } else { + statMap.get(key).incrementAndGet(); + } + } + + for (Map.Entry entry : statMap.entrySet()) { + result += String.format("System=%s | ClientNum=%d", entry.getKey(), entry.getValue().intValue()) + + + newLine; + } + } + + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("ShowClientHandler fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowListenClientByTopicHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowListenClientByTopicHandler.java new file mode 100644 index 0000000000..a7b11bea83 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ShowListenClientByTopicHandler.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientGroupWrapper; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +/** + * query client subscription by topic + */ +public class ShowListenClientByTopicHandler implements HttpHandler { + + private Logger logger = LoggerFactory.getLogger(ShowListenClientByTopicHandler.class); + + private final EventMeshTCPServer eventMeshTCPServer; + + public ShowListenClientByTopicHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + String result = ""; + OutputStream out = httpExchange.getResponseBody(); + try { + String queryString = httpExchange.getRequestURI().getQuery(); + Map queryStringInfo = NetUtils.formData2Dic(queryString); + String topic = queryStringInfo.get(EventMeshConstants.MANAGE_TOPIC); + + String newLine = System.getProperty("line.separator"); + logger.info("showListeningClientByTopic,topic:{}=================", topic); + ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + ConcurrentHashMap clientGroupMap = clientSessionGroupMapping.getClientGroupMap(); + if (!clientGroupMap.isEmpty()) { + for (ClientGroupWrapper cgw : clientGroupMap.values()) { + Set listenSessionSet = cgw.getTopic2sessionInGroupMapping().get(topic); + if (listenSessionSet != null && listenSessionSet.size() > 0) { + result += String.format("group:%s", cgw.getGroup()) + newLine; + for (Session session : listenSessionSet) { + UserAgent userAgent = session.getClient(); + result += String.format("pid=%s | ip=%s | port=%s | path=%s | version=%s", userAgent.getPid(), userAgent + .getHost(), userAgent.getPort(), userAgent.getPath(), userAgent.getVersion()) + newLine; + } + } + } + } + httpExchange.sendResponseHeaders(200, 0); + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("ShowListenClientByTopicHandler fail...", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.warn("out close failed...", e); + } + } + } + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/UpdateWebHookConfigHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/UpdateWebHookConfigHandler.java new file mode 100644 index 0000000000..c9f77e2c95 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/UpdateWebHookConfigHandler.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.admin.rocketmq.util.JsonUtils; +import org.apache.eventmesh.admin.rocketmq.util.NetUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; + +import java.io.IOException; +import java.io.OutputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +@SuppressWarnings("restriction") +public class UpdateWebHookConfigHandler implements HttpHandler { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + + private WebHookConfigOperation operation; + + public UpdateWebHookConfigHandler(WebHookConfigOperation operation) { + this.operation = operation; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + httpExchange.sendResponseHeaders(200, 0); + + // get requestBody and resolve to WebHookConfig + String requestBody = NetUtils.parsePostBody(httpExchange); + WebHookConfig webHookConfig = JsonUtils.toObject(requestBody, WebHookConfig.class); + + try (OutputStream out = httpExchange.getResponseBody()) { + Integer code = operation.updateWebHookConfig(webHookConfig); // operating result + String result = 1 == code ? "updateWebHookConfig Succeed!" : "updateWebHookConfig Failed!"; + out.write(result.getBytes()); + } catch (Exception e) { + logger.error("get WebHookConfigOperation implementation Failed.", e); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractHTTPServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractHTTPServer.java new file mode 100644 index 0000000000..165e673eb7 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractHTTPServer.java @@ -0,0 +1,685 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.body.Body; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.common.Pair; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.HandlerService; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.EventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.metrics.http.HTTPMetricsServer; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.entity.ContentType; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.QueryStringDecoder; +import io.netty.handler.codec.http.multipart.Attribute; +import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory; +import io.netty.handler.codec.http.multipart.DiskAttribute; +import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import io.netty.handler.ssl.SslHandler; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import io.netty.util.ReferenceCountUtil; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.base.Preconditions; + +public abstract class AbstractHTTPServer extends AbstractRemotingServer { + + public Logger httpServerLogger = LoggerFactory.getLogger(this.getClass()); + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + protected HandlerService handlerService; + + public HTTPMetricsServer metrics; + + public DefaultHttpDataFactory defaultHttpDataFactory = new DefaultHttpDataFactory(false); + + private AtomicBoolean started = new AtomicBoolean(false); + + private boolean useTLS; + + public Boolean useTrace = false; //Determine whether trace is enabled + + private EventMeshHTTPConfiguration eventMeshHttpConfiguration; + + public ThreadPoolExecutor asyncContextCompleteHandler = + ThreadPoolFactory.createThreadPoolExecutor(10, 10, "EventMesh-http-asyncContext-"); + + static { + DiskAttribute.deleteOnExitTemporaryFile = false; + } + + protected final Map> + processorTable = new HashMap<>(64); + + protected final Map> + eventProcessorTable = new HashMap<>(64); + + public AbstractHTTPServer(int port, boolean useTLS, EventMeshHTTPConfiguration eventMeshHttpConfiguration) { + this.port = port; + this.useTLS = useTLS; + this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; + } + + public void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { + FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status); + HttpHeaders responseHeaders = response.headers(); + responseHeaders.add( + HttpHeaderNames.CONTENT_TYPE, String.format("text/plain; charset=%s", EventMeshConstants.DEFAULT_CHARSET) + ); + responseHeaders.add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); + responseHeaders.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); + + ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + } + + public void sendResponse(ChannelHandlerContext ctx, DefaultFullHttpResponse response) { + ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> { + if (!f.isSuccess()) { + httpLogger.warn("send response to [{}] fail, will close this channel", + RemotingHelper.parseChannelRemoteAddr(f.channel())); + f.channel().close(); + } + }); + } + + @Override + public void start() throws Exception { + super.start(); + Runnable r = () -> { + ServerBootstrap b = new ServerBootstrap(); + SSLContext sslContext = useTLS ? SSLContextFactory.getSslContext() : null; + b.group(this.bossGroup, this.workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(new HttpsServerInitializer(sslContext)) + .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE); + try { + httpServerLogger.info("HTTPServer[port={}] started......", this.port); + ChannelFuture future = b.bind(this.port).sync(); + future.channel().closeFuture().sync(); + } catch (Exception e) { + httpServerLogger.error("HTTPServer start Err!", e); + try { + shutdown(); + } catch (Exception e1) { + httpServerLogger.error("HTTPServer shutdown Err!", e); + } + } + }; + + Thread t = new Thread(r, "EventMesh-http-server"); + t.start(); + started.compareAndSet(false, true); + } + + @Override + public void init(String threadPrefix) throws Exception { + super.init(threadPrefix); + } + + @Override + public void shutdown() throws Exception { + super.shutdown(); + started.compareAndSet(true, false); + } + + public void registerProcessor(Integer requestCode, HttpRequestProcessor processor, ThreadPoolExecutor executor) { + Preconditions.checkState(ObjectUtils.allNotNull(requestCode), "requestCode can't be null"); + Preconditions.checkState(ObjectUtils.allNotNull(processor), "processor can't be null"); + Preconditions.checkState(ObjectUtils.allNotNull(executor), "executor can't be null"); + Pair pair = new Pair<>(processor, executor); + this.processorTable.put(requestCode.toString(), pair); + } + + public void registerProcessor(String requestURI, EventProcessor processor, ThreadPoolExecutor executor) { + Preconditions.checkState(ObjectUtils.allNotNull(requestURI), "requestURI can't be null"); + Preconditions.checkState(ObjectUtils.allNotNull(processor), "processor can't be null"); + Preconditions.checkState(ObjectUtils.allNotNull(executor), "executor can't be null"); + Pair pair = new Pair<>(processor, executor); + this.eventProcessorTable.put(requestURI, pair); + } + + private Map parseHttpHeader(HttpRequest fullReq) { + Map headerParam = new HashMap<>(); + for (String key : fullReq.headers().names()) { + if (StringUtils.equalsIgnoreCase(HttpHeaderNames.CONTENT_TYPE.toString(), key) + || StringUtils.equalsIgnoreCase(HttpHeaderNames.ACCEPT_ENCODING.toString(), key) + || StringUtils.equalsIgnoreCase(HttpHeaderNames.CONTENT_LENGTH.toString(), key)) { + continue; + } + headerParam.put(key, fullReq.headers().get(key)); + } + return headerParam; + } + + /** + * Validate request, return error status. + * + * @param httpRequest + * @return if request is validated return null else return error status + */ + private HttpResponseStatus validateHttpRequest(HttpRequest httpRequest) { + if (!started.get()) { + return HttpResponseStatus.SERVICE_UNAVAILABLE; + } + if (!httpRequest.decoderResult().isSuccess()) { + return HttpResponseStatus.BAD_REQUEST; + } + if (!HttpMethod.GET.equals(httpRequest.method()) && !HttpMethod.POST.equals(httpRequest.method())) { + return HttpResponseStatus.METHOD_NOT_ALLOWED; + } + final String protocolVersion = httpRequest.headers().get(ProtocolKey.VERSION); + if (!ProtocolVersion.contains(protocolVersion)) { + return HttpResponseStatus.BAD_REQUEST; + } + return null; + } + + /** + * Inject ip and protocol version, if the protocol version is empty, set default to {@link ProtocolVersion#V1}. + * + * @param ctx + * @param httpRequest + */ + private void preProcessHttpRequestHeader(ChannelHandlerContext ctx, HttpRequest httpRequest) { + long startTime = System.currentTimeMillis(); + HttpHeaders requestHeaders = httpRequest.headers(); + requestHeaders.set(ProtocolKey.ClientInstanceKey.IP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel())); + + String protocolVersion = httpRequest.headers().get(ProtocolKey.VERSION); + if (StringUtils.isBlank(protocolVersion)) { + requestHeaders.set(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()); + } + requestHeaders.set(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, startTime); + requestHeaders.set(EventMeshConstants.REQ_SEND_EVENTMESH_IP, eventMeshHttpConfiguration.eventMeshServerIp); + } + + /** + * Parse request body to map + * + * @param httpRequest + * @return + */ + private Map parseHttpRequestBody(HttpRequest httpRequest) throws IOException { + final long bodyDecodeStart = System.currentTimeMillis(); + Map httpRequestBody = new HashMap<>(); + + if (HttpMethod.GET.equals(httpRequest.method())) { + QueryStringDecoder getDecoder = new QueryStringDecoder(httpRequest.uri()); + getDecoder.parameters().forEach((key, value) -> httpRequestBody.put(key, value.get(0))); + } else if (HttpMethod.POST.equals(httpRequest.method())) { + HttpPostRequestDecoder decoder = + new HttpPostRequestDecoder(defaultHttpDataFactory, httpRequest); + for (InterfaceHttpData parm : decoder.getBodyHttpDatas()) { + if (parm.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) { + Attribute data = (Attribute) parm; + httpRequestBody.put(data.getName(), data.getValue()); + } + } + decoder.destroy(); + } + metrics.getSummaryMetrics().recordDecodeTimeCost(System.currentTimeMillis() - bodyDecodeStart); + return httpRequestBody; + } + + class HTTPHandler extends ChannelInboundHandlerAdapter { + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) { + + HttpRequest httpRequest = (HttpRequest) message; + if (Objects.nonNull(handlerService) && handlerService.isProcessorWrapper(httpRequest)) { + handlerService.handler(ctx, httpRequest, asyncContextCompleteHandler); + return; + } + + try { + + Span span = null; + + + preProcessHttpRequestHeader(ctx, httpRequest); + + final Map headerMap = parseHttpHeader(httpRequest); + + + final HttpResponseStatus errorStatus = validateHttpRequest(httpRequest); + if (errorStatus != null) { + sendError(ctx, errorStatus); + + span = TraceUtils.prepareServerSpan(headerMap, EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(span, headerMap, errorStatus.reasonPhrase(), null); + return; + } + metrics.getSummaryMetrics().recordHTTPRequest(); + + boolean useRequestURI = false; + for (String processURI : eventProcessorTable.keySet()) { + if (httpRequest.uri().startsWith(processURI)) { + useRequestURI = true; + break; + } + } + if (useRequestURI) { + if (useTrace) { + span.setAttribute(SemanticAttributes.HTTP_METHOD, httpRequest.method().name()); + span.setAttribute(SemanticAttributes.HTTP_FLAVOR, httpRequest.protocolVersion().protocolName()); + span.setAttribute(SemanticAttributes.HTTP_URL, httpRequest.uri()); + } + HttpEventWrapper httpEventWrapper = parseHttpRequest(httpRequest); + + AsyncContext asyncContext = + new AsyncContext<>(httpEventWrapper, null, asyncContextCompleteHandler); + processHttpRequest(ctx, asyncContext); + + } else { + final HttpCommand requestCommand = new HttpCommand(); + + final Map bodyMap = parseHttpRequestBody(httpRequest); + + String requestCode = + (httpRequest.method() == HttpMethod.POST) + ? httpRequest.headers().get(ProtocolKey.REQUEST_CODE) + : MapUtils.getString(bodyMap, StringUtils.lowerCase(ProtocolKey.REQUEST_CODE), ""); + + requestCommand.setHttpMethod(httpRequest.method().name()); + requestCommand.setHttpVersion(httpRequest.protocolVersion().protocolName()); + requestCommand.setRequestCode(requestCode); + + HttpCommand responseCommand = null; + + if (StringUtils.isBlank(requestCode) + || !processorTable.containsKey(requestCode) + || !RequestCode.contains(Integer.valueOf(requestCode))) { + responseCommand = + requestCommand.createHttpCommandResponse(EventMeshRetCode.EVENTMESH_REQUESTCODE_INVALID); + sendResponse(ctx, responseCommand.httpResponse()); + + span = TraceUtils.prepareServerSpan(headerMap, EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(span, headerMap, EventMeshRetCode.EVENTMESH_REQUESTCODE_INVALID.getErrMsg(), null); + return; + } + + try { + requestCommand.setHeader(Header.buildHeader(requestCode, headerMap)); + requestCommand.setBody(Body.buildBody(requestCode, bodyMap)); + } catch (Exception e) { + responseCommand = requestCommand.createHttpCommandResponse(EventMeshRetCode.EVENTMESH_RUNTIME_ERR); + sendResponse(ctx, responseCommand.httpResponse()); + + span = TraceUtils.prepareServerSpan(headerMap, EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(span, headerMap, EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getErrMsg(), e); + return; + } + + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", requestCommand); + } + + AsyncContext asyncContext = + new AsyncContext<>(requestCommand, responseCommand, asyncContextCompleteHandler); + processEventMeshRequest(ctx, asyncContext); + } + + + } catch (Exception ex) { + httpServerLogger.error("AbrstractHTTPServer.HTTPHandler.channelRead err", ex); + } finally { + ReferenceCountUtil.release(message); + } + } + + public void processHttpRequest(final ChannelHandlerContext ctx, + final AsyncContext asyncContext) { + final HttpEventWrapper requestWrapper = asyncContext.getRequest(); + String requestURI = requestWrapper.getRequestURI(); + String processorKey = "/"; + for (String eventProcessorKey : eventProcessorTable.keySet()) { + if (requestURI.startsWith(eventProcessorKey)) { + processorKey = eventProcessorKey; + break; + } + } + final Pair choosed = eventProcessorTable.get(processorKey); + try { + choosed.getObject2().submit(() -> { + try { + EventProcessor processor = choosed.getObject1(); + if (processor.rejectRequest()) { + + HttpEventWrapper responseWrapper = + requestWrapper.createHttpResponse(EventMeshRetCode.EVENTMESH_REJECT_BY_PROCESSOR_ERROR); + + asyncContext.onComplete(responseWrapper); + if (asyncContext.isComplete()) { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", asyncContext.getResponse()); + } + sendResponse(ctx, asyncContext.getResponse().httpResponse()); + } + return; + } + + processor.processRequest(ctx, asyncContext); + if (!asyncContext.isComplete()) { + return; + } + + metrics.getSummaryMetrics() + .recordHTTPReqResTimeCost(System.currentTimeMillis() - requestWrapper.getReqTime()); + + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", asyncContext.getResponse()); + } + + sendResponse(ctx, asyncContext.getResponse().httpResponse()); + } catch (Exception e) { + httpServerLogger.error("process error", e); + } + }); + } catch (RejectedExecutionException re) { + HttpEventWrapper responseWrapper = requestWrapper.createHttpResponse(EventMeshRetCode.OVERLOAD); + asyncContext.onComplete(responseWrapper); + metrics.getSummaryMetrics().recordHTTPDiscard(); + metrics.getSummaryMetrics().recordHTTPReqResTimeCost(System.currentTimeMillis() - requestWrapper.getReqTime()); + try { + sendResponse(ctx, asyncContext.getResponse().httpResponse()); + } catch (Exception e) { + // ignore + } + } + + } + + public void processEventMeshRequest(final ChannelHandlerContext ctx, + final AsyncContext asyncContext) { + final HttpCommand request = asyncContext.getRequest(); + final Pair choosed = processorTable.get(request.getRequestCode()); + try { + choosed.getObject2().submit(() -> { + try { + HttpRequestProcessor processor = choosed.getObject1(); + if (processor.rejectRequest()) { + HttpCommand responseCommand = + request.createHttpCommandResponse(EventMeshRetCode.EVENTMESH_REJECT_BY_PROCESSOR_ERROR); + asyncContext.onComplete(responseCommand); + if (asyncContext.isComplete()) { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", asyncContext.getResponse()); + } + sendResponse(ctx, responseCommand.httpResponse()); + + Map traceMap = asyncContext.getRequest().getHeader().toMap(); + Span span = TraceUtils.prepareServerSpan(traceMap, EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, + false); + TraceUtils.finishSpanWithException(span, traceMap, + EventMeshRetCode.EVENTMESH_REJECT_BY_PROCESSOR_ERROR.getErrMsg(), null); + } + return; + } + + processor.processRequest(ctx, asyncContext); + if (!asyncContext.isComplete()) { + return; + } + + metrics.getSummaryMetrics() + .recordHTTPReqResTimeCost(System.currentTimeMillis() - request.getReqTime()); + + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", asyncContext.getResponse()); + } + + sendResponse(ctx, asyncContext.getResponse().httpResponse()); + + } catch (Exception e) { + httpServerLogger.error("process error", e); + } + }); + } catch (RejectedExecutionException re) { + HttpCommand responseCommand = request.createHttpCommandResponse(EventMeshRetCode.OVERLOAD); + asyncContext.onComplete(responseCommand); + metrics.getSummaryMetrics().recordHTTPDiscard(); + metrics.getSummaryMetrics().recordHTTPReqResTimeCost(System.currentTimeMillis() - request.getReqTime()); + try { + sendResponse(ctx, asyncContext.getResponse().httpResponse()); + + Map traceMap = asyncContext.getRequest().getHeader().toMap(); + Span span = TraceUtils.prepareServerSpan(traceMap, EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(span, traceMap, EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getErrMsg(), re); + } catch (Exception e) { + httpServerLogger.error("processEventMeshRequest fail", re); + } + } + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + super.channelReadComplete(ctx); + ctx.flush(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + if (null != cause) { + logger.error("", cause); + } + if (null != ctx) { + ctx.close(); + } + } + + Map extractFromRequest(HttpRequest httpRequest) { + return null; + } + } + + private HttpEventWrapper parseHttpRequest(HttpRequest httpRequest) throws IOException { + HttpEventWrapper httpEventWrapper = new HttpEventWrapper(); + httpEventWrapper.setHttpMethod(httpRequest.method().name()); + httpEventWrapper.setHttpVersion(httpRequest.protocolVersion().protocolName()); + httpEventWrapper.setRequestURI(httpRequest.uri()); + + //parse http header + for (String key : httpRequest.headers().names()) { + httpEventWrapper.getHeaderMap().put(key, httpRequest.headers().get(key)); + } + + final long bodyDecodeStart = System.currentTimeMillis(); + //parse http body + FullHttpRequest fullHttpRequest = (FullHttpRequest) httpRequest; + final Map bodyMap = new HashMap<>(); + if (HttpMethod.GET == fullHttpRequest.method()) { + QueryStringDecoder getDecoder = new QueryStringDecoder(fullHttpRequest.uri()); + getDecoder.parameters().forEach((key, value) -> bodyMap.put(key, value.get(0))); + } else if (HttpMethod.POST == fullHttpRequest.method()) { + + if (StringUtils.contains(httpRequest.headers().get("Content-Type"), ContentType.APPLICATION_JSON.getMimeType())) { + int length = fullHttpRequest.content().readableBytes(); + if (length > 0) { + byte[] body = new byte[length]; + fullHttpRequest.content().readBytes(body); + JsonUtils.deserialize(new String(body), new TypeReference>() { + }).forEach(bodyMap::put); + } + } else { + HttpPostRequestDecoder decoder = + new HttpPostRequestDecoder(defaultHttpDataFactory, httpRequest); + for (InterfaceHttpData parm : decoder.getBodyHttpDatas()) { + if (parm.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) { + Attribute data = (Attribute) parm; + bodyMap.put(data.getName(), data.getValue()); + } + } + decoder.destroy(); + } + + } else { + throw new RuntimeException("UnSupported Method " + fullHttpRequest.method()); + } + + byte[] requestBody = JsonUtils.serialize(bodyMap).getBytes(StandardCharsets.UTF_8); + httpEventWrapper.setBody(requestBody); + + metrics.getSummaryMetrics().recordDecodeTimeCost(System.currentTimeMillis() - bodyDecodeStart); + + return httpEventWrapper; + } + + class HttpConnectionHandler extends ChannelDuplexHandler { + public final AtomicInteger connections = new AtomicInteger(0); + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + super.channelRegistered(ctx); + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + super.channelUnregistered(ctx); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + int c = connections.incrementAndGet(); + if (c > 20000) { + httpServerLogger + .warn("client|http|channelActive|remoteAddress={}|msg={}", remoteAddress, + "too many client(20000) connect this eventMesh server"); + ctx.close(); + return; + } + + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + connections.decrementAndGet(); + super.channelInactive(ctx); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { + if (evt instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) evt; + if (event.state().equals(IdleState.ALL_IDLE)) { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + httpServerLogger.info("client|http|userEventTriggered|remoteAddress={}|msg={}", + remoteAddress, evt.getClass().getName()); + ctx.close(); + } + } + + ctx.fireUserEventTriggered(evt); + } + } + + class HttpsServerInitializer extends ChannelInitializer { + + private final SSLContext sslContext; + + public HttpsServerInitializer(SSLContext sslContext) { + this.sslContext = sslContext; + } + + @Override + protected void initChannel(SocketChannel channel) { + ChannelPipeline pipeline = channel.pipeline(); + + + if (sslContext != null && useTLS) { + SSLEngine sslEngine = sslContext.createSSLEngine(); + sslEngine.setUseClientMode(false); + pipeline.addFirst("ssl", new SslHandler(sslEngine)); + } + pipeline.addLast(new HttpRequestDecoder(), + new HttpResponseEncoder(), + + new HttpConnectionHandler(), + new HttpObjectAggregator(Integer.MAX_VALUE), + new HTTPHandler()); + } + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractRemotingServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractRemotingServer.java new file mode 100644 index 0000000000..311ae2e086 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractRemotingServer.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.common.utils.ThreadUtils; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; + +public abstract class AbstractRemotingServer { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + public EventLoopGroup bossGroup; + + public EventLoopGroup ioGroup; + + public EventLoopGroup workerGroup; + + public int port; + + private EventLoopGroup initBossGroup(String threadPrefix) { + bossGroup = new NioEventLoopGroup(1, new ThreadFactory() { + AtomicInteger count = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, threadPrefix + "-boss-" + count.incrementAndGet()); + t.setDaemon(true); + return t; + } + }); + + return bossGroup; + } + + private EventLoopGroup initIOGroup(String threadPrefix) { + ioGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactory() { + AtomicInteger count = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, threadPrefix + "-io-" + count.incrementAndGet()); + return t; + } + }); + return ioGroup; + } + + private EventLoopGroup initWorkerGroup(String threadPrefix) { + workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactory() { + AtomicInteger count = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, threadPrefix + "-worker-" + count.incrementAndGet()); + return t; + } + }); + return workerGroup; + } + + public void init(String threadPrefix) throws Exception { + initBossGroup(threadPrefix); + initIOGroup(threadPrefix); + initWorkerGroup(threadPrefix); + } + + public void shutdown() throws Exception { + if (bossGroup != null) { + bossGroup.shutdownGracefully(); + logger.info("shutdown bossGroup"); + } + + ThreadUtils.randomSleep(30); + + if (ioGroup != null) { + ioGroup.shutdownGracefully(); + logger.info("shutdown ioGroup"); + } + + if (workerGroup != null) { + workerGroup.shutdownGracefully(); + logger.info("shutdown workerGroup"); + } + } + + public void start() throws Exception { + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshGrpcServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshGrpcServer.java new file mode 100644 index 0000000000..467257aca4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshGrpcServer.java @@ -0,0 +1,278 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.retry.GrpcRetryer; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ConsumerService; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.HeartbeatService; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ProducerService; +import org.apache.eventmesh.runtime.registry.Registry; + +import org.apache.commons.lang3.RandomUtils; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.Server; +import io.grpc.ServerBuilder; + +import com.google.common.util.concurrent.RateLimiter; + +public class EventMeshGrpcServer { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final EventMeshGrpcConfiguration eventMeshGrpcConfiguration; + + private Server server; + + private ProducerManager producerManager; + + private ConsumerManager consumerManager; + + private GrpcRetryer grpcRetryer; + + private ThreadPoolExecutor sendMsgExecutor; + + private ThreadPoolExecutor replyMsgExecutor; + + private ThreadPoolExecutor clientMgmtExecutor; + + private ThreadPoolExecutor pushMsgExecutor; + + private List httpClientPool; + + private RateLimiter msgRateLimiter; + + private Registry registry; + + public EventMeshGrpcServer(EventMeshGrpcConfiguration eventMeshGrpcConfiguration, Registry registry) { + this.eventMeshGrpcConfiguration = eventMeshGrpcConfiguration; + this.registry = registry; + } + + public void init() throws Exception { + logger.info("==================EventMeshGRPCServer Initializing=================="); + + initThreadPool(); + + initHttpClientPool(); + + msgRateLimiter = RateLimiter.create(eventMeshGrpcConfiguration.eventMeshMsgReqNumPerSecond); + + producerManager = new ProducerManager(this); + producerManager.init(); + + consumerManager = new ConsumerManager(this); + consumerManager.init(); + + grpcRetryer = new GrpcRetryer(this); + grpcRetryer.init(); + + int serverPort = eventMeshGrpcConfiguration.grpcServerPort; + + server = ServerBuilder.forPort(serverPort) + .addService(new ProducerService(this, sendMsgExecutor)) + .addService(new ConsumerService(this, clientMgmtExecutor, replyMsgExecutor)) + .addService(new HeartbeatService(this, clientMgmtExecutor)) + .build(); + + logger.info("GRPCServer[port={}] started", serverPort); + logger.info("-----------------EventMeshGRPCServer initialized"); + } + + public void start() throws Exception { + logger.info("---------------EventMeshGRPCServer starting-------------------"); + + producerManager.start(); + consumerManager.start(); + grpcRetryer.start(); + server.start(); + + if (eventMeshGrpcConfiguration.eventMeshServerRegistryEnable) { + this.register(); + } + + logger.info("---------------EventMeshGRPCServer running-------------------"); + } + + public void shutdown() throws Exception { + logger.info("---------------EventMeshGRPCServer stopping-------------------"); + + producerManager.shutdown(); + consumerManager.shutdown(); + grpcRetryer.shutdown(); + + shutdownThreadPools(); + shutdownHttpClientPool(); + + server.shutdown(); + + if (eventMeshGrpcConfiguration.eventMeshServerRegistryEnable) { + this.unRegister(); + } + + logger.info("---------------EventMeshGRPCServer stopped-------------------"); + } + + public boolean register() { + boolean registerResult = false; + try { + String endPoints = IPUtils.getLocalAddress() + + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshGrpcConfiguration.grpcServerPort; + EventMeshRegisterInfo eventMeshRegisterInfo = new EventMeshRegisterInfo(); + eventMeshRegisterInfo.setEventMeshClusterName(eventMeshGrpcConfiguration.eventMeshCluster); + eventMeshRegisterInfo.setEventMeshName(eventMeshGrpcConfiguration.eventMeshName + "-" + ConfigurationContextUtil.GRPC); + eventMeshRegisterInfo.setEndPoint(endPoints); + eventMeshRegisterInfo.setProtocolType(ConfigurationContextUtil.GRPC); + registerResult = registry.register(eventMeshRegisterInfo); + } catch (Exception e) { + logger.warn("eventMesh register to registry failed", e); + } + + return registerResult; + } + + private void unRegister() throws Exception { + String endPoints = IPUtils.getLocalAddress() + + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshGrpcConfiguration.grpcServerPort; + EventMeshUnRegisterInfo eventMeshUnRegisterInfo = new EventMeshUnRegisterInfo(); + eventMeshUnRegisterInfo.setEventMeshClusterName(eventMeshGrpcConfiguration.eventMeshCluster); + eventMeshUnRegisterInfo.setEventMeshName(eventMeshGrpcConfiguration.eventMeshName); + eventMeshUnRegisterInfo.setEndPoint(endPoints); + eventMeshUnRegisterInfo.setProtocolType(ConfigurationContextUtil.GRPC); + boolean registerResult = registry.unRegister(eventMeshUnRegisterInfo); + if (!registerResult) { + throw new EventMeshException("eventMesh fail to unRegister"); + } + } + + public EventMeshGrpcConfiguration getEventMeshGrpcConfiguration() { + return this.eventMeshGrpcConfiguration; + } + + public ProducerManager getProducerManager() { + return producerManager; + } + + public ConsumerManager getConsumerManager() { + return consumerManager; + } + + public GrpcRetryer getGrpcRetryer() { + return grpcRetryer; + } + + public ThreadPoolExecutor getSendMsgExecutor() { + return sendMsgExecutor; + } + + public ThreadPoolExecutor getClientMgmtExecutor() { + return clientMgmtExecutor; + } + + public ThreadPoolExecutor getPushMsgExecutor() { + return pushMsgExecutor; + } + + public RateLimiter getMsgRateLimiter() { + return msgRateLimiter; + } + + public CloseableHttpClient getHttpClient() { + int size = httpClientPool.size(); + return httpClientPool.get(RandomUtils.nextInt(size, 2 * size) % size); + } + + private void initThreadPool() { + BlockingQueue sendMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshGrpcConfiguration.eventMeshServerSendMsgBlockQueueSize); + + sendMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor(eventMeshGrpcConfiguration.eventMeshServerSendMsgThreadNum, + eventMeshGrpcConfiguration.eventMeshServerSendMsgThreadNum, sendMsgThreadPoolQueue, + "eventMesh-grpc-sendMsg-%d", true); + + BlockingQueue subscribeMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshGrpcConfiguration.eventMeshServerSubscribeMsgBlockQueueSize); + + clientMgmtExecutor = ThreadPoolFactory.createThreadPoolExecutor(eventMeshGrpcConfiguration.eventMeshServerSubscribeMsgThreadNum, + eventMeshGrpcConfiguration.eventMeshServerSubscribeMsgThreadNum, subscribeMsgThreadPoolQueue, + "eventMesh-grpc-clientMgmt-%d", true); + + BlockingQueue pushMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshGrpcConfiguration.eventMeshServerPushMsgBlockQueueSize); + + pushMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor(eventMeshGrpcConfiguration.eventMeshServerPushMsgThreadNum, + eventMeshGrpcConfiguration.eventMeshServerPushMsgThreadNum, pushMsgThreadPoolQueue, + "eventMesh-grpc-pushMsg-%d", true); + + BlockingQueue replyMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshGrpcConfiguration.eventMeshServerSendMsgBlockQueueSize); + + replyMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor(eventMeshGrpcConfiguration.eventMeshServerReplyMsgThreadNum, + eventMeshGrpcConfiguration.eventMeshServerReplyMsgThreadNum, sendMsgThreadPoolQueue, + "eventMesh-grpc-replyMsg-%d", true); + } + + private void initHttpClientPool() { + httpClientPool = new LinkedList<>(); + for (int i = 0; i < 8; i++) { + CloseableHttpClient client = HttpClients.createDefault(); + httpClientPool.add(client); + } + } + + private void shutdownThreadPools() { + sendMsgExecutor.shutdown(); + clientMgmtExecutor.shutdown(); + pushMsgExecutor.shutdown(); + replyMsgExecutor.shutdown(); + } + + private void shutdownHttpClientPool() { + Iterator itr = httpClientPool.iterator(); + while (itr.hasNext()) { + CloseableHttpClient client = itr.next(); + try { + client.close(); + } catch (Exception e) { + // ignored + } + itr.remove(); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshHTTPServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshHTTPServer.java new file mode 100644 index 0000000000..f7280efac1 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshHTTPServer.java @@ -0,0 +1,430 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.metrics.api.MetricsPluginFactory; +import org.apache.eventmesh.metrics.api.MetricsRegistry; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.http.processor.AdminMetricsProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.BatchSendMessageProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.BatchSendMessageV2Processor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.HandlerService; +import org.apache.eventmesh.runtime.core.protocol.http.processor.HeartBeatProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.LocalSubscribeEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.LocalUnSubscribeEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.RemoteSubscribeEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.RemoteUnSubscribeEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.ReplyMessageProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.SendAsyncEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.SendAsyncMessageProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.SendAsyncRemoteEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.SendSyncMessageProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.SubscribeProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.UnSubscribeProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.WebHookProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.core.protocol.http.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.http.push.HTTPClientPool; +import org.apache.eventmesh.runtime.core.protocol.http.retry.HttpRetryer; +import org.apache.eventmesh.runtime.metrics.http.HTTPMetricsServer; +import org.apache.eventmesh.runtime.registry.Registry; +import org.apache.eventmesh.webhook.receive.WebHookController; + +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; + +import org.assertj.core.util.Lists; + +import com.google.common.eventbus.EventBus; +import com.google.common.util.concurrent.RateLimiter; + +public class EventMeshHTTPServer extends AbstractHTTPServer { + + private EventMeshServer eventMeshServer; + + public ServiceState serviceState; + + private EventMeshHTTPConfiguration eventMeshHttpConfiguration; + + private Registry registry; + + public final ConcurrentHashMap localConsumerGroupMapping = + new ConcurrentHashMap<>(); + + public final ConcurrentHashMap> localClientInfoMapping = + new ConcurrentHashMap<>(); + + public EventMeshHTTPServer(EventMeshServer eventMeshServer, + EventMeshHTTPConfiguration eventMeshHttpConfiguration) { + super(eventMeshHttpConfiguration.httpServerPort, eventMeshHttpConfiguration.eventMeshServerUseTls, eventMeshHttpConfiguration); + this.eventMeshServer = eventMeshServer; + this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; + this.registry = eventMeshServer.getRegistry(); + } + + public EventMeshServer getEventMeshServer() { + return eventMeshServer; + } + + public EventBus eventBus = new EventBus(); + + private ConsumerManager consumerManager; + + private ProducerManager producerManager; + + private HttpRetryer httpRetryer; + + public ThreadPoolExecutor batchMsgExecutor; + + public ThreadPoolExecutor sendMsgExecutor; + + public ThreadPoolExecutor remoteMsgExecutor; + + public ThreadPoolExecutor replyMsgExecutor; + + public ThreadPoolExecutor pushMsgExecutor; + + public ThreadPoolExecutor clientManageExecutor; + + public ThreadPoolExecutor adminExecutor; + + public ThreadPoolExecutor webhookExecutor; + + private RateLimiter msgRateLimiter; + + private RateLimiter batchRateLimiter; + + public HTTPClientPool httpClientPool = new HTTPClientPool(10); + + public void shutdownThreadPool() throws Exception { + batchMsgExecutor.shutdown(); + adminExecutor.shutdown(); + clientManageExecutor.shutdown(); + sendMsgExecutor.shutdown(); + remoteMsgExecutor.shutdown(); + pushMsgExecutor.shutdown(); + replyMsgExecutor.shutdown(); + } + + public void initThreadPool() throws Exception { + + BlockingQueue batchMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshHttpConfiguration.eventMeshServerBatchBlockQSize); + batchMsgExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerBatchMsgThreadNum, + eventMeshHttpConfiguration.eventMeshServerBatchMsgThreadNum, batchMsgThreadPoolQueue, + "eventMesh-batchMsg-", true); + + BlockingQueue sendMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshHttpConfiguration.eventMeshServerSendMsgBlockQSize); + sendMsgExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerSendMsgThreadNum, + eventMeshHttpConfiguration.eventMeshServerSendMsgThreadNum, sendMsgThreadPoolQueue, + "eventMesh-sendMsg-", true); + + BlockingQueue remoteMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshHttpConfiguration.eventMeshServerRemoteMsgBlockQSize); + remoteMsgExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerRemoteMsgThreadNum, + eventMeshHttpConfiguration.eventMeshServerRemoteMsgThreadNum, remoteMsgThreadPoolQueue, + "eventMesh-remoteMsg-", true); + + BlockingQueue pushMsgThreadPoolQueue = + new LinkedBlockingQueue(eventMeshHttpConfiguration.eventMeshServerPushMsgBlockQSize); + pushMsgExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerPushMsgThreadNum, + eventMeshHttpConfiguration.eventMeshServerPushMsgThreadNum, pushMsgThreadPoolQueue, + "eventMesh-pushMsg-", true); + + BlockingQueue clientManageThreadPoolQueue = + new LinkedBlockingQueue(eventMeshHttpConfiguration.eventMeshServerClientManageBlockQSize); + clientManageExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerClientManageThreadNum, + eventMeshHttpConfiguration.eventMeshServerClientManageThreadNum, clientManageThreadPoolQueue, + "eventMesh-clientManage-", true); + + BlockingQueue adminThreadPoolQueue = new LinkedBlockingQueue(50); + adminExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerAdminThreadNum, + eventMeshHttpConfiguration.eventMeshServerAdminThreadNum, adminThreadPoolQueue, "eventMesh-admin-", + true); + + BlockingQueue replyMessageThreadPoolQueue = new LinkedBlockingQueue(100); + replyMsgExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerReplyMsgThreadNum, + eventMeshHttpConfiguration.eventMeshServerReplyMsgThreadNum, replyMessageThreadPoolQueue, + "eventMesh-replyMsg-", true); + } + + public ThreadPoolExecutor getBatchMsgExecutor() { + return batchMsgExecutor; + } + + public ThreadPoolExecutor getSendMsgExecutor() { + return sendMsgExecutor; + } + + public ThreadPoolExecutor getReplyMsgExecutor() { + return replyMsgExecutor; + } + + public ThreadPoolExecutor getPushMsgExecutor() { + return pushMsgExecutor; + } + + public ThreadPoolExecutor getClientManageExecutor() { + return clientManageExecutor; + } + + public ThreadPoolExecutor getAdminExecutor() { + return adminExecutor; + } + + public RateLimiter getMsgRateLimiter() { + return msgRateLimiter; + } + + public RateLimiter getBatchRateLimiter() { + return batchRateLimiter; + } + + public Registry getRegistry() { + return registry; + } + + public void init() throws Exception { + logger.info("==================EventMeshHTTPServer Initialing=================="); + super.init("eventMesh-http"); + + initThreadPool(); + + msgRateLimiter = RateLimiter.create(eventMeshHttpConfiguration.eventMeshHttpMsgReqNumPerSecond); + batchRateLimiter = RateLimiter.create(eventMeshHttpConfiguration.eventMeshBatchMsgRequestNumPerSecond); + + // The MetricsRegistry is singleton, so we can use factory method to get. + final List metricsRegistries = Lists.newArrayList(); + Optional.ofNullable(eventMeshHttpConfiguration.eventMeshMetricsPluginType) + .ifPresent( + metricsPlugins -> metricsPlugins.forEach( + pluginType -> metricsRegistries.add(MetricsPluginFactory.getMetricsRegistry(pluginType)))); + + httpRetryer = new HttpRetryer(this); + httpRetryer.init(); + + metrics = new HTTPMetricsServer(this, metricsRegistries); + metrics.init(); + + consumerManager = new ConsumerManager(this); + consumerManager.init(); + + producerManager = new ProducerManager(this); + producerManager.init(); + + this.handlerService = new HandlerService(); + this.handlerService.setMetrics(metrics); + + + //get the trace-plugin + if (StringUtils.isNotEmpty(eventMeshHttpConfiguration.eventMeshTracePluginType) && eventMeshHttpConfiguration.eventMeshServerTraceEnable) { + + super.useTrace = eventMeshHttpConfiguration.eventMeshServerTraceEnable; + } + + this.handlerService.setHttpTrace(new HTTPTrace(eventMeshHttpConfiguration.eventMeshServerTraceEnable)); + + registerHTTPRequestProcessor(); + this.initWebhook(); + logger.info("--------------------------EventMeshHTTPServer inited"); + } + + @Override + public void start() throws Exception { + super.start(); + metrics.start(); + consumerManager.start(); + producerManager.start(); + httpRetryer.start(); + if (eventMeshHttpConfiguration.eventMeshServerRegistryEnable) { + this.register(); + } + logger.info("--------------------------EventMeshHTTPServer started"); + } + + @Override + public void shutdown() throws Exception { + + super.shutdown(); + + metrics.shutdown(); + + consumerManager.shutdown(); + + shutdownThreadPool(); + + httpClientPool.shutdown(); + + producerManager.shutdown(); + + httpRetryer.shutdown(); + + if (eventMeshHttpConfiguration.eventMeshServerRegistryEnable) { + this.unRegister(); + } + logger.info("--------------------------EventMeshHTTPServer shutdown"); + } + + public boolean register() { + boolean registerResult = false; + try { + String endPoints = IPUtils.getLocalAddress() + + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshHttpConfiguration.httpServerPort; + EventMeshRegisterInfo eventMeshRegisterInfo = new EventMeshRegisterInfo(); + eventMeshRegisterInfo.setEventMeshClusterName(eventMeshHttpConfiguration.eventMeshCluster); + eventMeshRegisterInfo.setEventMeshName(eventMeshHttpConfiguration.eventMeshName + "-" + ConfigurationContextUtil.HTTP); + eventMeshRegisterInfo.setEndPoint(endPoints); + eventMeshRegisterInfo.setProtocolType(ConfigurationContextUtil.HTTP); + registerResult = registry.register(eventMeshRegisterInfo); + } catch (Exception e) { + logger.warn("eventMesh register to registry failed", e); + } + + return registerResult; + } + + private void unRegister() throws Exception { + String endPoints = IPUtils.getLocalAddress() + + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshHttpConfiguration.httpServerPort; + EventMeshUnRegisterInfo eventMeshUnRegisterInfo = new EventMeshUnRegisterInfo(); + eventMeshUnRegisterInfo.setEventMeshClusterName(eventMeshHttpConfiguration.eventMeshCluster); + eventMeshUnRegisterInfo.setEventMeshName(eventMeshHttpConfiguration.eventMeshName); + eventMeshUnRegisterInfo.setEndPoint(endPoints); + eventMeshUnRegisterInfo.setProtocolType(ConfigurationContextUtil.HTTP); + boolean registerResult = registry.unRegister(eventMeshUnRegisterInfo); + if (!registerResult) { + throw new EventMeshException("eventMesh fail to unRegister"); + } + } + + public void registerHTTPRequestProcessor() { + BatchSendMessageProcessor batchSendMessageProcessor = new BatchSendMessageProcessor(this); + registerProcessor(RequestCode.MSG_BATCH_SEND.getRequestCode(), batchSendMessageProcessor, batchMsgExecutor); + + BatchSendMessageV2Processor batchSendMessageV2Processor = new BatchSendMessageV2Processor(this); + registerProcessor(RequestCode.MSG_BATCH_SEND_V2.getRequestCode(), batchSendMessageV2Processor, + batchMsgExecutor); + + SendSyncMessageProcessor sendSyncMessageProcessor = new SendSyncMessageProcessor(this); + registerProcessor(RequestCode.MSG_SEND_SYNC.getRequestCode(), sendSyncMessageProcessor, sendMsgExecutor); + + SendAsyncMessageProcessor sendAsyncMessageProcessor = new SendAsyncMessageProcessor(this); + registerProcessor(RequestCode.MSG_SEND_ASYNC.getRequestCode(), sendAsyncMessageProcessor, sendMsgExecutor); + + SendAsyncEventProcessor sendAsyncEventProcessor = new SendAsyncEventProcessor(this); + handlerService.register(sendAsyncEventProcessor, sendMsgExecutor); + + SendAsyncRemoteEventProcessor sendAsyncRemoteEventProcessor = new SendAsyncRemoteEventProcessor(this); + handlerService.register(sendAsyncRemoteEventProcessor, remoteMsgExecutor); + + AdminMetricsProcessor adminMetricsProcessor = new AdminMetricsProcessor(this); + registerProcessor(RequestCode.ADMIN_METRICS.getRequestCode(), adminMetricsProcessor, adminExecutor); + + HeartBeatProcessor heartProcessor = new HeartBeatProcessor(this); + registerProcessor(RequestCode.HEARTBEAT.getRequestCode(), heartProcessor, clientManageExecutor); + + SubscribeProcessor subscribeProcessor = new SubscribeProcessor(this); + registerProcessor(RequestCode.SUBSCRIBE.getRequestCode(), subscribeProcessor, clientManageExecutor); + + LocalSubscribeEventProcessor localSubscribeEventProcessor = new LocalSubscribeEventProcessor(this); + handlerService.register(localSubscribeEventProcessor, clientManageExecutor); + + RemoteSubscribeEventProcessor remoteSubscribeEventProcessor = new RemoteSubscribeEventProcessor(this); + handlerService.register(remoteSubscribeEventProcessor, clientManageExecutor); + + UnSubscribeProcessor unSubscribeProcessor = new UnSubscribeProcessor(this); + registerProcessor(RequestCode.UNSUBSCRIBE.getRequestCode(), unSubscribeProcessor, clientManageExecutor); + + LocalUnSubscribeEventProcessor localUnSubscribeEventProcessor = new LocalUnSubscribeEventProcessor(this); + handlerService.register(localUnSubscribeEventProcessor, clientManageExecutor); + + RemoteUnSubscribeEventProcessor remoteUnSubscribeEventProcessor = new RemoteUnSubscribeEventProcessor(this); + handlerService.register(remoteUnSubscribeEventProcessor, clientManageExecutor); + + ReplyMessageProcessor replyMessageProcessor = new ReplyMessageProcessor(this); + registerProcessor(RequestCode.REPLY_MESSAGE.getRequestCode(), replyMessageProcessor, replyMsgExecutor); + + + } + + private void initWebhook() throws Exception { + + + BlockingQueue webhookThreadPoolQueue = new LinkedBlockingQueue(100); + webhookExecutor = + ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpConfiguration.eventMeshServerWebhookThreadNum, + eventMeshHttpConfiguration.eventMeshServerWebhookThreadNum, webhookThreadPoolQueue, + "eventMesh-webhook-", true); + WebHookProcessor webHookProcessor = new WebHookProcessor(); + + WebHookController webHookController = new WebHookController(); + webHookController.setConfigurationWrapper(eventMeshHttpConfiguration.getConfigurationWrapper()); + webHookController.init(); + webHookProcessor.setWebHookController(webHookController); + this.handlerService.register(webHookProcessor, webhookExecutor); + } + + public ConsumerManager getConsumerManager() { + return consumerManager; + } + + public ProducerManager getProducerManager() { + return producerManager; + } + + public ServiceState getServiceState() { + return serviceState; + } + + public EventMeshHTTPConfiguration getEventMeshHttpConfiguration() { + return eventMeshHttpConfiguration; + } + + public EventBus getEventBus() { + return eventBus; + } + + public HttpRetryer getHttpRetryer() { + return httpRetryer; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshServer.java new file mode 100644 index 0000000000..e6569432bd --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshServer.java @@ -0,0 +1,234 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.runtime.connector.ConnectorResource; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.registry.Registry; +import org.apache.eventmesh.runtime.trace.Trace; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventMeshServer { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + public EventMeshHTTPServer eventMeshHTTPServer; + + private EventMeshTCPServer eventMeshTCPServer; + + private EventMeshGrpcServer eventMeshGrpcServer; + + private EventMeshGrpcConfiguration eventMeshGrpcConfiguration; + + private EventMeshHTTPConfiguration eventMeshHttpConfiguration; + + private EventMeshTCPConfiguration eventMeshTcpConfiguration; + + private Acl acl; + + private Registry registry; + + private static Trace trace; + + private ConnectorResource connectorResource; + + private ServiceState serviceState; + + public EventMeshServer(EventMeshHTTPConfiguration eventMeshHttpConfiguration, + EventMeshTCPConfiguration eventMeshTcpConfiguration, + EventMeshGrpcConfiguration eventMeshGrpcConfiguration) { + this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; + this.eventMeshTcpConfiguration = eventMeshTcpConfiguration; + this.eventMeshGrpcConfiguration = eventMeshGrpcConfiguration; + this.acl = new Acl(); + this.registry = new Registry(); + this.trace = new Trace(eventMeshHttpConfiguration.eventMeshServerTraceEnable); + this.connectorResource = new ConnectorResource(); + + ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.TCP, eventMeshTcpConfiguration); + ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.GRPC, eventMeshGrpcConfiguration); + ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.HTTP, eventMeshHttpConfiguration); + } + + public void init() throws Exception { + if (eventMeshHttpConfiguration != null && eventMeshHttpConfiguration.eventMeshServerSecurityEnable) { + acl.init(eventMeshHttpConfiguration.eventMeshSecurityPluginType); + } + + // registry init + if (eventMeshTcpConfiguration != null + && eventMeshTcpConfiguration.eventMeshTcpServerEnabled + && eventMeshTcpConfiguration.eventMeshServerRegistryEnable) { + registry.init(eventMeshTcpConfiguration.eventMeshRegistryPluginType); + } + + if (eventMeshGrpcConfiguration != null && eventMeshGrpcConfiguration.eventMeshServerRegistryEnable) { + registry.init(eventMeshGrpcConfiguration.eventMeshRegistryPluginType); + } + + if (eventMeshHttpConfiguration != null && eventMeshHttpConfiguration.eventMeshServerRegistryEnable) { + registry.init(eventMeshHttpConfiguration.eventMeshRegistryPluginType); + } + + if (eventMeshHttpConfiguration != null && eventMeshHttpConfiguration.eventMeshServerTraceEnable) { + trace.init(eventMeshHttpConfiguration.eventMeshTracePluginType); + } + + connectorResource.init(eventMeshHttpConfiguration.eventMeshConnectorPluginType); + + // server init + if (eventMeshGrpcConfiguration != null) { + eventMeshGrpcServer = new EventMeshGrpcServer(eventMeshGrpcConfiguration, registry); + eventMeshGrpcServer.init(); + } + + if (eventMeshHttpConfiguration != null) { + eventMeshHTTPServer = new EventMeshHTTPServer(this, eventMeshHttpConfiguration); + eventMeshHTTPServer.init(); + } + + if (eventMeshTcpConfiguration != null) { + eventMeshTCPServer = new EventMeshTCPServer(this, eventMeshTcpConfiguration, registry); + if (eventMeshTcpConfiguration.eventMeshTcpServerEnabled) { + eventMeshTCPServer.init(); + } + } + + String eventStore = System + .getProperty(EventMeshConstants.EVENT_STORE_PROPERTIES, System.getenv(EventMeshConstants.EVENT_STORE_ENV)); + logger.info("eventStore : {}", eventStore); + + serviceState = ServiceState.INITED; + logger.info("server state:{}", serviceState); + } + + public void start() throws Exception { + if (eventMeshHttpConfiguration != null && eventMeshHttpConfiguration.eventMeshServerSecurityEnable) { + acl.start(); + } + // registry start + if (eventMeshTcpConfiguration != null + && eventMeshTcpConfiguration.eventMeshTcpServerEnabled + && eventMeshTcpConfiguration.eventMeshServerRegistryEnable) { + registry.start(); + } + if (eventMeshHttpConfiguration != null && eventMeshHttpConfiguration.eventMeshServerRegistryEnable) { + registry.start(); + } + if (eventMeshGrpcConfiguration != null && eventMeshGrpcConfiguration.eventMeshServerRegistryEnable) { + registry.start(); + } + + // server start + if (eventMeshGrpcConfiguration != null) { + eventMeshGrpcServer.start(); + } + if (eventMeshHttpConfiguration != null) { + eventMeshHTTPServer.start(); + } + if (eventMeshTcpConfiguration != null && eventMeshTcpConfiguration.eventMeshTcpServerEnabled) { + eventMeshTCPServer.start(); + } + serviceState = ServiceState.RUNNING; + logger.info("server state:{}", serviceState); + } + + public void shutdown() throws Exception { + serviceState = ServiceState.STOPING; + logger.info("server state:{}", serviceState); + + if (eventMeshHttpConfiguration != null) { + eventMeshHTTPServer.shutdown(); + } + + if (eventMeshTcpConfiguration != null + && eventMeshTcpConfiguration.eventMeshTcpServerEnabled) { + eventMeshTCPServer.shutdown(); + } + + if (eventMeshGrpcConfiguration != null) { + eventMeshGrpcServer.shutdown(); + } + + if (eventMeshHttpConfiguration != null + && eventMeshHttpConfiguration.eventMeshServerRegistryEnable) { + registry.shutdown(); + } + + if (eventMeshTcpConfiguration != null + && eventMeshTcpConfiguration.eventMeshTcpServerEnabled + && eventMeshTcpConfiguration.eventMeshServerRegistryEnable) { + registry.shutdown(); + } + + if (eventMeshGrpcConfiguration != null + && eventMeshGrpcConfiguration.eventMeshServerRegistryEnable) { + registry.shutdown(); + } + + connectorResource.release(); + + if (eventMeshHttpConfiguration != null && eventMeshHttpConfiguration.eventMeshServerSecurityEnable) { + acl.shutdown(); + } + + if (eventMeshHttpConfiguration != null && eventMeshHttpConfiguration.eventMeshServerTraceEnable) { + trace.shutdown(); + } + + ConfigurationContextUtil.clear(); + serviceState = ServiceState.STOPED; + logger.info("server state:{}", serviceState); + } + + public EventMeshGrpcServer getEventMeshGrpcServer() { + return eventMeshGrpcServer; + } + + public EventMeshHTTPServer getEventMeshHTTPServer() { + return eventMeshHTTPServer; + } + + public EventMeshTCPServer getEventMeshTCPServer() { + return eventMeshTCPServer; + } + + public static Trace getTrace() { + return trace; + } + + public ServiceState getServiceState() { + return serviceState; + } + + public Registry getRegistry() { + return registry; + } + + public void setRegistry(Registry registry) { + this.registry = registry; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshStartup.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshStartup.java new file mode 100644 index 0000000000..5150be94c3 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshStartup.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.common.config.ConfigurationWrapper; +import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventMeshStartup { + + public static Logger logger = LoggerFactory.getLogger(EventMeshStartup.class); + + public static void main(String[] args) throws Exception { + try { + ConfigurationWrapper configurationWrapper = + new ConfigurationWrapper(EventMeshConstants.EVENTMESH_CONF_HOME, + EventMeshConstants.EVENTMESH_CONF_FILE, false); + EventMeshHTTPConfiguration eventMeshHttpConfiguration = new EventMeshHTTPConfiguration(configurationWrapper); + eventMeshHttpConfiguration.init(); + EventMeshTCPConfiguration eventMeshTcpConfiguration = new EventMeshTCPConfiguration(configurationWrapper); + eventMeshTcpConfiguration.init(); + EventMeshGrpcConfiguration eventMeshGrpcConfiguration = new EventMeshGrpcConfiguration(configurationWrapper); + eventMeshGrpcConfiguration.init(); + EventMeshServer server = new EventMeshServer(eventMeshHttpConfiguration, eventMeshTcpConfiguration, eventMeshGrpcConfiguration); + server.init(); + server.start(); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + logger.info("eventMesh shutting down hook begin..."); + long start = System.currentTimeMillis(); + server.shutdown(); + long end = System.currentTimeMillis(); + logger.info("eventMesh shutdown cost {}ms", end - start); + } catch (Exception e) { + logger.error("exception when shutdown...", e); + } + })); + } catch (Throwable e) { + logger.error("EventMesh start fail.", e); + e.printStackTrace(); + System.exit(-1); + } + + } +} + diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshTCPServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshTCPServer.java new file mode 100644 index 0000000000..68e58ec6b4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshTCPServer.java @@ -0,0 +1,410 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.tcp.codec.Codec; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.metrics.api.MetricsPluginFactory; +import org.apache.eventmesh.metrics.api.MetricsRegistry; +import org.apache.eventmesh.runtime.admin.controller.ClientManageController; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcpConnectionHandler; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcpExceptionHandler; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcpMessageDispatcher; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance.EventMeshRebalanceService; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance.EventmeshRebalanceImpl; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry.EventMeshTcpRetryer; +import org.apache.eventmesh.runtime.metrics.tcp.EventMeshTcpMonitor; +import org.apache.eventmesh.runtime.registry.Registry; +import org.apache.eventmesh.runtime.util.EventMeshThreadFactoryImpl; +import org.apache.eventmesh.webhook.admin.AdminWebHookConfigOperationManage; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; + +import org.assertj.core.util.Lists; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.AdaptiveRecvByteBufAllocator; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.timeout.IdleStateHandler; +import io.netty.handler.traffic.ChannelTrafficShapingHandler; +import io.netty.handler.traffic.GlobalTrafficShapingHandler; + +import com.google.common.util.concurrent.RateLimiter; + +public class EventMeshTCPServer extends AbstractRemotingServer { + + private ClientSessionGroupMapping clientSessionGroupMapping; + + private EventMeshTcpRetryer eventMeshTcpRetryer; + + private EventMeshTcpMonitor eventMeshTcpMonitor; + + private ClientManageController clientManageController; + + private EventMeshServer eventMeshServer; + + private EventMeshTCPConfiguration eventMeshTCPConfiguration; + + private GlobalTrafficShapingHandler globalTrafficShapingHandler; + + private ScheduledExecutorService scheduler; + + private ExecutorService taskHandleExecutorService; + + private ExecutorService broadcastMsgDownstreamExecutorService; + + private Registry registry; + + private EventMeshRebalanceService eventMeshRebalanceService; + + public void setClientSessionGroupMapping(ClientSessionGroupMapping clientSessionGroupMapping) { + this.clientSessionGroupMapping = clientSessionGroupMapping; + } + + public ClientManageController getClientManageController() { + return clientManageController; + } + + public void setClientManageController(ClientManageController clientManageController) { + this.clientManageController = clientManageController; + } + + public ScheduledExecutorService getScheduler() { + return scheduler; + } + + public void setScheduler(ScheduledExecutorService scheduler) { + this.scheduler = scheduler; + } + + public ExecutorService getTaskHandleExecutorService() { + return taskHandleExecutorService; + } + + public ExecutorService getBroadcastMsgDownstreamExecutorService() { + return broadcastMsgDownstreamExecutorService; + } + + public void setTaskHandleExecutorService(ExecutorService taskHandleExecutorService) { + this.taskHandleExecutorService = taskHandleExecutorService; + } + + public RateLimiter getRateLimiter() { + return rateLimiter; + } + + public void setRateLimiter(RateLimiter rateLimiter) { + this.rateLimiter = rateLimiter; + } + + private ScheduledFuture tcpRegisterTask; + + private RateLimiter rateLimiter; + + public EventMeshTCPServer(EventMeshServer eventMeshServer, + EventMeshTCPConfiguration eventMeshTCPConfiguration, Registry registry) { + super(); + this.eventMeshServer = eventMeshServer; + this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; + this.registry = registry; + } + + private void startServer() { + Runnable r = () -> { + ServerBootstrap bootstrap = new ServerBootstrap(); + ChannelInitializer channelInitializer = new ChannelInitializer() { + @Override + public void initChannel(Channel ch) throws Exception { + ch.pipeline() + .addLast(new Codec.Encoder()) + .addLast(new Codec.Decoder()) + .addLast("global-traffic-shaping", globalTrafficShapingHandler) + .addLast("channel-traffic-shaping", newCTSHandler()) + .addLast(new EventMeshTcpConnectionHandler(EventMeshTCPServer.this)) + .addLast( + workerGroup, + new IdleStateHandler( + eventMeshTCPConfiguration.eventMeshTcpIdleReadSeconds, + eventMeshTCPConfiguration.eventMeshTcpIdleWriteSeconds, + eventMeshTCPConfiguration.eventMeshTcpIdleAllSeconds), + new EventMeshTcpMessageDispatcher(EventMeshTCPServer.this), + new EventMeshTcpExceptionHandler(EventMeshTCPServer.this) + ); + } + }; + + bootstrap.group(bossGroup, ioGroup) + .channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG, 128) + .option(ChannelOption.SO_REUSEADDR, true) + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) + .childOption(ChannelOption.SO_KEEPALIVE, false) + .childOption(ChannelOption.SO_LINGER, 0) + .childOption(ChannelOption.SO_TIMEOUT, 600000) + .childOption(ChannelOption.TCP_NODELAY, true) + .childOption(ChannelOption.SO_SNDBUF, 65535 * 4) + .childOption(ChannelOption.SO_RCVBUF, 65535 * 4) + .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(2048, 4096, 65536)) + .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) + .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) + .childHandler(channelInitializer); + + try { + int port = eventMeshTCPConfiguration.eventMeshTcpServerPort; + ChannelFuture f = bootstrap.bind(port).sync(); + logger.info("EventMeshTCPServer[port={}] started.....", port); + f.channel().closeFuture().sync(); + } catch (Exception e) { + logger.error("EventMeshTCPServer RemotingServer Start Err!", e); + try { + shutdown(); + } catch (Exception e1) { + logger.error("EventMeshTCPServer RemotingServer shutdown Err!", e); + } + } + }; + + Thread t = new Thread(r, "eventMesh-tcp-server"); + t.start(); + } + + public void init() throws Exception { + logger.info("==================EventMeshTCPServer Initialing=================="); + initThreadPool(); + + rateLimiter = RateLimiter.create(eventMeshTCPConfiguration.eventMeshTcpMsgReqnumPerSecond); + + globalTrafficShapingHandler = newGTSHandler(); + + + AdminWebHookConfigOperationManage adminWebHookConfigOperationManage = new AdminWebHookConfigOperationManage(); + adminWebHookConfigOperationManage.setConfigurationWrapper(eventMeshTCPConfiguration.getConfigurationWrapper()); + adminWebHookConfigOperationManage.init(); + + clientManageController = new ClientManageController(this); + clientManageController.setAdminWebHookConfigOperationManage(adminWebHookConfigOperationManage); + + clientSessionGroupMapping = new ClientSessionGroupMapping(this); + clientSessionGroupMapping.init(); + + eventMeshTcpRetryer = new EventMeshTcpRetryer(this); + eventMeshTcpRetryer.init(); + + // The MetricsRegistry is singleton, so we can use factory method to get. + final List metricsRegistries = Lists.newArrayList(); + Optional.ofNullable(eventMeshTCPConfiguration.eventMeshMetricsPluginType) + .ifPresent( + metricsPlugins -> metricsPlugins.forEach( + pluginType -> metricsRegistries.add(MetricsPluginFactory.getMetricsRegistry(pluginType)))); + eventMeshTcpMonitor = new EventMeshTcpMonitor(this, metricsRegistries); + eventMeshTcpMonitor.init(); + + if (eventMeshTCPConfiguration.eventMeshServerRegistryEnable) { + eventMeshRebalanceService = new EventMeshRebalanceService(this, + new EventmeshRebalanceImpl(this)); + eventMeshRebalanceService.init(); + } + logger.info("--------------------------EventMeshTCPServer Inited"); + } + + @Override + public void start() throws Exception { + startServer(); + + clientSessionGroupMapping.start(); + + eventMeshTcpRetryer.start(); + + eventMeshTcpMonitor.start(); + + clientManageController.start(); + + if (eventMeshTCPConfiguration.eventMeshServerRegistryEnable) { + this.register(); + eventMeshRebalanceService.start(); + } + + logger.info("--------------------------EventMeshTCPServer Started"); + } + + @Override + public void shutdown() throws Exception { + if (bossGroup != null) { + bossGroup.shutdownGracefully(); + logger.info("shutdown bossGroup, no client is allowed to connect access server"); + } + + if (eventMeshTCPConfiguration.eventMeshServerRegistryEnable) { + eventMeshRebalanceService.shutdown(); + + this.unRegister(); + } + + clientSessionGroupMapping.shutdown(); + try { + Thread.sleep(40 * 1000); + } catch (InterruptedException e) { + logger.error("interruptedException occurred while sleeping", e); + } + + globalTrafficShapingHandler.release(); + + if (ioGroup != null) { + ioGroup.shutdownGracefully(); + logger.info("shutdown ioGroup"); + } + if (workerGroup != null) { + workerGroup.shutdownGracefully(); + logger.info("shutdown workerGroup"); + } + + eventMeshTcpRetryer.shutdown(); + + eventMeshTcpMonitor.shutdown(); + + shutdownThreadPool(); + logger.info("--------------------------EventMeshTCPServer Shutdown"); + } + + public boolean register() { + boolean registerResult = false; + try { + String endPoints = IPUtils.getLocalAddress() + + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshTCPConfiguration.eventMeshTcpServerPort; + EventMeshRegisterInfo eventMeshRegisterInfo = new EventMeshRegisterInfo(); + eventMeshRegisterInfo.setEventMeshClusterName(eventMeshTCPConfiguration.eventMeshCluster); + eventMeshRegisterInfo.setEventMeshName(eventMeshTCPConfiguration.eventMeshName + "-" + ConfigurationContextUtil.TCP); + eventMeshRegisterInfo.setEndPoint(endPoints); + eventMeshRegisterInfo.setEventMeshInstanceNumMap(clientSessionGroupMapping.prepareProxyClientDistributionData()); + eventMeshRegisterInfo.setProtocolType(ConfigurationContextUtil.TCP); + registerResult = registry.register(eventMeshRegisterInfo); + } catch (Exception e) { + logger.warn("eventMesh register to registry failed", e); + } + + return registerResult; + } + + private void unRegister() throws Exception { + String endPoints = IPUtils.getLocalAddress() + + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshTCPConfiguration.eventMeshTcpServerPort; + EventMeshUnRegisterInfo eventMeshUnRegisterInfo = new EventMeshUnRegisterInfo(); + eventMeshUnRegisterInfo.setEventMeshClusterName(eventMeshTCPConfiguration.eventMeshCluster); + eventMeshUnRegisterInfo.setEventMeshName(eventMeshTCPConfiguration.eventMeshName); + eventMeshUnRegisterInfo.setEndPoint(endPoints); + eventMeshUnRegisterInfo.setProtocolType(ConfigurationContextUtil.TCP); + boolean registerResult = registry.unRegister(eventMeshUnRegisterInfo); + if (!registerResult) { + throw new EventMeshException("eventMesh fail to unRegister"); + } + } + + private void initThreadPool() throws Exception { + super.init("eventMesh-tcp"); + + scheduler = ThreadPoolFactory.createScheduledExecutor(eventMeshTCPConfiguration.eventMeshTcpGlobalScheduler, + new EventMeshThreadFactoryImpl("eventMesh-tcp-scheduler", true)); + + taskHandleExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshTCPConfiguration.eventMeshTcpTaskHandleExecutorPoolSize, + eventMeshTCPConfiguration.eventMeshTcpTaskHandleExecutorPoolSize, + new LinkedBlockingQueue<>(10000), + new EventMeshThreadFactoryImpl("eventMesh-tcp-task-handle", true)); + + broadcastMsgDownstreamExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshTCPConfiguration.eventMeshTcpMsgDownStreamExecutorPoolSize, + eventMeshTCPConfiguration.eventMeshTcpMsgDownStreamExecutorPoolSize, + new LinkedBlockingQueue<>(10000), + new EventMeshThreadFactoryImpl("eventMesh-tcp-msg-downstream", true)); + } + + private void shutdownThreadPool() { + scheduler.shutdown(); + taskHandleExecutorService.shutdown(); + } + + private GlobalTrafficShapingHandler newGTSHandler() { + GlobalTrafficShapingHandler handler = new GlobalTrafficShapingHandler(scheduler, 0, + eventMeshTCPConfiguration.getGtc().getReadLimit()) { + @Override + protected long calculateSize(Object msg) { + return 1; + } + }; + handler.setMaxTimeWait(1000); + return handler; + } + + private ChannelTrafficShapingHandler newCTSHandler() { + ChannelTrafficShapingHandler handler = new ChannelTrafficShapingHandler(0, + eventMeshTCPConfiguration.getCtc().getReadLimit()) { + @Override + protected long calculateSize(Object msg) { + return 1; + } + }; + handler.setMaxTimeWait(3000); + return handler; + } + + public ClientSessionGroupMapping getClientSessionGroupMapping() { + return clientSessionGroupMapping; + } + + public EventMeshTcpRetryer getEventMeshTcpRetryer() { + return eventMeshTcpRetryer; + } + + public EventMeshTcpMonitor getEventMeshTcpMonitor() { + return eventMeshTcpMonitor; + } + + public EventMeshServer getEventMeshServer() { + return eventMeshServer; + } + + public EventMeshTCPConfiguration getEventMeshTCPConfiguration() { + return eventMeshTCPConfiguration; + } + + public Registry getRegistry() { + return registry; + } + + public EventMeshRebalanceService getEventMeshRebalanceService() { + return eventMeshRebalanceService; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/HTTPTrace.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/HTTPTrace.java new file mode 100644 index 0000000000..9e80180b8f --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/HTTPTrace.java @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nullable; + +import io.cloudevents.CloudEvent; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpRequest; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +public class HTTPTrace { + + public boolean useTrace; + + public HTTPTrace(boolean useTrace) { + this.useTrace = useTrace; + } + + public TraceOperation getTraceOperation(HttpRequest httpRequest, Channel channel, boolean traceEnabled) { + + final Map headerMap = parseHttpHeader(httpRequest); + Span span = TraceUtils.prepareServerSpan(headerMap, EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, + false); + return new TraceOperation(span, null, traceEnabled); + } + + private Map parseHttpHeader(HttpRequest fullReq) { + Map headerParam = new HashMap<>(); + for (String key : fullReq.headers().names()) { + if (StringUtils.equalsIgnoreCase(HttpHeaderNames.CONTENT_TYPE.toString(), key) + || StringUtils.equalsIgnoreCase(HttpHeaderNames.ACCEPT_ENCODING.toString(), key) + || StringUtils.equalsIgnoreCase(HttpHeaderNames.CONTENT_LENGTH.toString(), key)) { + continue; + } + headerParam.put(key, fullReq.headers().get(key)); + } + return headerParam; + } + + @AllArgsConstructor + @Getter + public class TraceOperation { + + private Span span; + + private TraceOperation childTraceOperation; + + private boolean traceEnabled; + + public void endTrace(CloudEvent ce) { + if (!HTTPTrace.this.useTrace) { + return; + } + if (childTraceOperation != null) { + childTraceOperation.endTrace(ce); + } + try (Scope ignored = span.makeCurrent()) { + TraceUtils.finishSpan(span, ce); + } + } + + public void exceptionTrace(@Nullable Throwable ex, Map map) { + if (!HTTPTrace.this.useTrace) { + return; + } + if (childTraceOperation != null) { + childTraceOperation.exceptionTrace(ex, map); + } + try (Scope ignored = span.makeCurrent()) { + TraceUtils.finishSpanWithException(span, map, ex.getMessage(), ex); + } + } + + public void endLatestTrace(CloudEvent ce) { + if (childTraceOperation != null) { + TraceOperation traceOperation = this.childTraceOperation.getChildTraceOperation(); + this.childTraceOperation.setChildTraceOperation(null); + + childTraceOperation.endTrace(ce); + this.childTraceOperation = traceOperation; + } + } + + public void exceptionLatestTrace(@Nullable Throwable ex, Map traceMap) { + if (childTraceOperation != null) { + TraceOperation traceOperation = this.childTraceOperation.getChildTraceOperation(); + this.childTraceOperation.setChildTraceOperation(null); + + childTraceOperation.exceptionTrace(ex, traceMap); + this.childTraceOperation = traceOperation; + } + } + + public TraceOperation createClientTraceOperation(Map map, String spanName, boolean isSpanFinishInOtherThread) { + TraceOperation traceOperation = new TraceOperation(TraceUtils.prepareClientSpan(map, spanName, isSpanFinishInOtherThread), + null, this.traceEnabled); + this.setChildTraceOperation(traceOperation); + return traceOperation; + } + + public void setChildTraceOperation(TraceOperation traceOperation) { + if (childTraceOperation != null) { + childTraceOperation.setChildTraceOperation(traceOperation); + } + this.childTraceOperation = traceOperation; + } + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/SSLContextFactory.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/SSLContextFactory.java new file mode 100644 index 0000000000..0d7fff5d04 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/SSLContextFactory.java @@ -0,0 +1,74 @@ +/* + * Licensed to Apache Software Foundation (ASF) under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.boot; + +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.security.KeyStore; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SSLContextFactory { + private static Logger httpLogger = LoggerFactory.getLogger("http"); + + private static String protocol = "TLSv1.1"; + + private static String fileName; + + private static String pass; + + + public static SSLContext getSslContext() { + SSLContext sslContext; + try { + protocol = System.getProperty("ssl.server.protocol", "TLSv1.1"); + + fileName = System.getProperty("ssl.server.cer", "sChat2.jks"); + + char[] filePass = null; + pass = System.getProperty("ssl.server.pass", "sNetty"); + if (StringUtils.isNotBlank(pass)) { + filePass = pass.toCharArray(); + } + sslContext = SSLContext.getInstance(protocol); + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(Files.newInputStream(Paths.get(EventMeshConstants.EVENTMESH_CONF_HOME + + File.separator + + fileName), StandardOpenOption.READ), filePass); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, filePass); + sslContext.init(kmf.getKeyManagers(), null, null); + } catch (Exception e) { + httpLogger.warn("sslContext init failed", e); + sslContext = null; + } + return sslContext; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/EventMeshTrace.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/EventMeshTrace.java new file mode 100644 index 0000000000..348f74120e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/EventMeshTrace.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.common; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface EventMeshTrace { + /** + * If true, enable the trace + */ + boolean isEnable() default false; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/Pair.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/Pair.java new file mode 100644 index 0000000000..5e2a428ef6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/Pair.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.common; + +public class Pair { + private T1 object1; + private T2 object2; + + public Pair(T1 object1, T2 object2) { + this.object1 = object1; + this.object2 = object2; + } + + public T1 getObject1() { + return object1; + } + + public void setObject1(T1 object1) { + this.object1 = object1; + } + + public T2 getObject2() { + return object2; + } + + public void setObject2(T2 object2) { + this.object2 = object2; + } +} + diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/ServiceState.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/ServiceState.java new file mode 100644 index 0000000000..6848b2c2bc --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/common/ServiceState.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.common; + +public enum ServiceState { + + INITED, + + RUNNING, + + STOPING, + + STOPED; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshGrpcConfiguration.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshGrpcConfiguration.java new file mode 100644 index 0000000000..65142f6326 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshGrpcConfiguration.java @@ -0,0 +1,257 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.configuration; + +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.config.ConfigurationWrapper; +import org.apache.eventmesh.common.utils.IPUtils; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.base.Preconditions; + +public class EventMeshGrpcConfiguration extends CommonConfiguration { + + public int grpcServerPort = 10205; + + public int eventMeshSessionExpiredInMills = 60000; + + public boolean eventMeshServerBatchMsgBatchEnabled = Boolean.TRUE; + + public int eventMeshServerBatchMsgThreadNum = 10; + + public int eventMeshServerSendMsgThreadNum = 8; + + public int eventMeshServerPushMsgThreadNum = 8; + + public int eventMeshServerReplyMsgThreadNum = 8; + + public int eventMeshServerSubscribeMsgThreadNum = 4; + + public int eventMeshServerRegistryThreadNum = 10; + + public int eventMeshServerAdminThreadNum = 2; + + public int eventMeshServerRetryThreadNum = 2; + + public int eventMeshServerPullRegistryInterval = 30000; + + public int eventMeshServerAsyncAccumulationThreshold = 1000; + + public int eventMeshServerRetryBlockQueueSize = 10000; + + public int eventMeshServerBatchBlockQueueSize = 1000; + + public int eventMeshServerSendMsgBlockQueueSize = 1000; + + public int eventMeshServerPushMsgBlockQueueSize = 1000; + + public int eventMeshServerSubscribeMsgBlockQueueSize = 1000; + + public int eventMeshServerBusyCheckInterval = 1000; + + public boolean eventMeshServerConsumerEnabled = false; + + public boolean eventMeshServerUseTls = false; + + public int eventMeshBatchMsgRequestNumPerSecond = 20000; + + public int eventMeshMsgReqNumPerSecond = 15000; + + public String eventMeshIp = IPUtils.getLocalAddress(); + + public EventMeshGrpcConfiguration(ConfigurationWrapper configurationWrapper) { + super(configurationWrapper); + } + + @Override + public void init() { + super.init(); + + if (configurationWrapper != null) { + String httpServerPortStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_SERVER_GRPC_PORT); + Preconditions.checkState(StringUtils.isNotEmpty(httpServerPortStr) && StringUtils.isNumeric(httpServerPortStr), + String.format("%s error", ConfKeys.KEYS_EVENTMESH_SERVER_GRPC_PORT)); + grpcServerPort = Integer.parseInt(StringUtils.deleteWhitespace(httpServerPortStr)); + + String eventMeshServerBatchMsgThreadNumStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_BATCHMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerBatchMsgThreadNumStr) && StringUtils.isNumeric(eventMeshServerBatchMsgThreadNumStr)) { + eventMeshServerBatchMsgThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerBatchMsgThreadNumStr)); + } + + String eventMeshTcpSessionExpiredInMillsStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_SERVER_SESSION_EXPIRED_TIME); + if (StringUtils.isNotEmpty(eventMeshTcpSessionExpiredInMillsStr) && StringUtils.isNumeric(eventMeshTcpSessionExpiredInMillsStr)) { + eventMeshSessionExpiredInMills = Integer.parseInt(eventMeshTcpSessionExpiredInMillsStr); + } + + String eventMeshServerBatchMsgReqNumPerSecondStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_BATCHMSG_REQ_NUM_PER_SECOND); + if (StringUtils.isNotEmpty(eventMeshServerBatchMsgReqNumPerSecondStr) + && StringUtils.isNumeric(eventMeshServerBatchMsgReqNumPerSecondStr)) { + eventMeshBatchMsgRequestNumPerSecond = Integer.parseInt(eventMeshServerBatchMsgReqNumPerSecondStr); + } + + String eventMeshServerBatchMsgBatchEnableStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_BATCHMSG_BATCH_ENABLED); + if (StringUtils.isNotBlank(eventMeshServerBatchMsgBatchEnableStr)) { + eventMeshServerBatchMsgBatchEnabled = Boolean.parseBoolean(eventMeshServerBatchMsgBatchEnableStr); + } + + String eventMeshServerAsyncAccumulationThresholdStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ASYNC_ACCUMULATION_THRESHOLD); + if (StringUtils.isNotEmpty(eventMeshServerAsyncAccumulationThresholdStr) + && StringUtils.isNumeric(eventMeshServerAsyncAccumulationThresholdStr)) { + eventMeshServerAsyncAccumulationThreshold = Integer.parseInt( + StringUtils.deleteWhitespace(eventMeshServerAsyncAccumulationThresholdStr)); + } + + String eventMeshServerSendMsgThreadNumStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_SENDMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerSendMsgThreadNumStr) && StringUtils.isNumeric(eventMeshServerSendMsgThreadNumStr)) { + eventMeshServerSendMsgThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerSendMsgThreadNumStr)); + } + + String eventMeshServerReplyMsgThreadNumStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_REPLYMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerReplyMsgThreadNumStr) && StringUtils.isNumeric(eventMeshServerReplyMsgThreadNumStr)) { + eventMeshServerReplyMsgThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerReplyMsgThreadNumStr)); + } + + String eventMeshServerPushMsgThreadNumStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_PUSHMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerPushMsgThreadNumStr) && StringUtils.isNumeric(eventMeshServerPushMsgThreadNumStr)) { + eventMeshServerPushMsgThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerPushMsgThreadNumStr)); + } + + String eventMeshServerRegistryThreadNumStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_REGISTRY_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerRegistryThreadNumStr) && StringUtils.isNumeric(eventMeshServerRegistryThreadNumStr)) { + eventMeshServerRegistryThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerRegistryThreadNumStr)); + } + + String eventMeshServerClientManageThreadNumStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_CLIENTMANAGE_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerClientManageThreadNumStr) && StringUtils.isNumeric(eventMeshServerClientManageThreadNumStr)) { + eventMeshServerSubscribeMsgThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerClientManageThreadNumStr)); + } + + String eventMeshServerPullRegistryIntervalStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_PULL_REGISTRY_INTERVAL); + if (StringUtils.isNotEmpty(eventMeshServerPullRegistryIntervalStr) && StringUtils.isNumeric(eventMeshServerPullRegistryIntervalStr)) { + eventMeshServerPullRegistryInterval = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerPullRegistryIntervalStr)); + } + + String eventMeshServerAdminThreadNumStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ADMIN_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerAdminThreadNumStr) && StringUtils.isNumeric(eventMeshServerAdminThreadNumStr)) { + eventMeshServerAdminThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerAdminThreadNumStr)); + } + + String eventMeshServerRetryBlockQueueSizeStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_RETRY_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerRetryBlockQueueSizeStr) && StringUtils.isNumeric(eventMeshServerRetryBlockQueueSizeStr)) { + eventMeshServerRetryBlockQueueSize = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerRetryBlockQueueSizeStr)); + } + + String eventMeshServerBatchBlockQueueSizeStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_BATCHMSG_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerBatchBlockQueueSizeStr) && StringUtils.isNumeric(eventMeshServerBatchBlockQueueSizeStr)) { + eventMeshServerBatchBlockQueueSize = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerBatchBlockQueueSizeStr)); + } + + String eventMeshServerSendMsgBlockQueueSizeStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SENDMSG_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerSendMsgBlockQueueSizeStr) && StringUtils.isNumeric(eventMeshServerSendMsgBlockQueueSizeStr)) { + eventMeshServerSendMsgBlockQueueSize = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerSendMsgBlockQueueSizeStr)); + } + + String eventMeshServerPushMsgBlockQueueSizeStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_PUSHMSG_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerPushMsgBlockQueueSizeStr) && StringUtils.isNumeric(eventMeshServerPushMsgBlockQueueSizeStr)) { + eventMeshServerPushMsgBlockQueueSize = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerPushMsgBlockQueueSizeStr)); + } + + String eventMeshServerClientManageBlockQueueSizeStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_CLIENTM_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerClientManageBlockQueueSizeStr) + && StringUtils.isNumeric(eventMeshServerClientManageBlockQueueSizeStr)) { + eventMeshServerSubscribeMsgBlockQueueSize = Integer.parseInt( + StringUtils.deleteWhitespace(eventMeshServerClientManageBlockQueueSizeStr)); + } + + String eventMeshServerBusyCheckIntervalStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_BUSY_CHECK_INTERVAL); + if (StringUtils.isNotEmpty(eventMeshServerBusyCheckIntervalStr) && StringUtils.isNumeric(eventMeshServerBusyCheckIntervalStr)) { + eventMeshServerBusyCheckInterval = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerBusyCheckIntervalStr)); + } + + String eventMeshServerConsumerEnabledStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_CONSUMER_ENABLED); + if (StringUtils.isNotEmpty(eventMeshServerConsumerEnabledStr)) { + eventMeshServerConsumerEnabled = Boolean.parseBoolean(StringUtils.deleteWhitespace(eventMeshServerConsumerEnabledStr)); + } + + String eventMeshServerRetryThreadNumStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_RETRY_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerRetryThreadNumStr) && StringUtils.isNumeric(eventMeshServerRetryThreadNumStr)) { + eventMeshServerRetryThreadNum = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerRetryThreadNumStr)); + } + + String eventMeshServerUseTlsStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_TLS_ENABLED); + if (StringUtils.isNotEmpty(eventMeshServerUseTlsStr)) { + eventMeshServerUseTls = Boolean.parseBoolean(StringUtils.deleteWhitespace(eventMeshServerUseTlsStr)); + } + + String eventMeshMsgReqNumPerSecondStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SERVER_MSG_REQ_NUM_PER_SECOND); + if (StringUtils.isNotEmpty(eventMeshMsgReqNumPerSecondStr) && StringUtils.isNumeric(eventMeshMsgReqNumPerSecondStr)) { + eventMeshMsgReqNumPerSecond = Integer.parseInt(eventMeshMsgReqNumPerSecondStr); + } + } + } + + static class ConfKeys { + + public static final String KEYS_EVENTMESH_SERVER_GRPC_PORT = "eventMesh.server.grpc.port"; + + public static final String KEYS_EVENTMESH_SERVER_SESSION_EXPIRED_TIME = "eventMesh.server.session.expiredInMills"; + + public static final String KEYS_EVENTMESH_BATCHMSG_THREAD_NUM = "eventMesh.server.batchmsg.threads.num"; + + public static final String KEYS_EVENTMESH_BATCHMSG_REQ_NUM_PER_SECOND = "eventMesh.server.batchmsg.reqNumPerSecond"; + + public static final String KEYS_EVENTMESH_BATCHMSG_BATCH_ENABLED = "eventMesh.server.batchmsg.batch.enabled"; + + public static final String KEYS_EVENTMESH_ASYNC_ACCUMULATION_THRESHOLD = "eventMesh.server.async.accumulation.threshold"; + + public static final String KEY_EVENTMESH_BUSY_CHECK_INTERVAL = "eventMesh.server.busy.check.interval"; + + public static final String KEYS_EVENTMESH_SENDMSG_THREAD_NUM = "eventMesh.server.sendmsg.threads.num"; + + public static final String KEYS_EVENTMESH_REPLYMSG_THREAD_NUM = "eventMesh.server.replymsg.threads.num"; + + public static final String KEYS_EVENTMESH_PUSHMSG_THREAD_NUM = "eventMesh.server.pushmsg.threads.num"; + + public static final String KEYS_EVENTMESH_REGISTRY_THREAD_NUM = "eventMesh.server.registry.threads.num"; + + public static final String KEYS_EVENTMESH_CLIENTMANAGE_THREAD_NUM = "eventMesh.server.clientmanage.threads.num"; + + public static final String KEYS_EVENTMESH_ADMIN_THREAD_NUM = "eventMesh.server.admin.threads.num"; + + public static final String KEY_EVENTMESH_RETRY_THREAD_NUM = "eventMesh.server.retry.threads.num"; + + public static final String KEYS_EVENTMESH_PULL_REGISTRY_INTERVAL = "eventMesh.server.pull.registry.interval"; + + public static final String KEY_EVENTMESH_RETRY_BLOCKQ_SIZE = "eventMesh.server.retry.blockQ.size"; + + public static final String KEY_EVENTMESH_BATCHMSG_BLOCKQ_SIZE = "eventMesh.server.batchmsg.blockQ.size"; + + public static final String KEY_EVENTMESH_SENDMSG_BLOCKQ_SIZE = "eventMesh.server.sendmsg.blockQ.size"; + + public static final String KEY_EVENTMESH_PUSHMSG_BLOCKQ_SIZE = "eventMesh.server.pushmsg.blockQ.size"; + + public static final String KEY_EVENTMESH_CLIENTM_BLOCKQ_SIZE = "eventMesh.server.clientM.blockQ.size"; + + public static final String KEY_EVENTMESH_CONSUMER_ENABLED = "eventMesh.server.consumer.enabled"; + + public static final String KEY_EVENTMESH_TLS_ENABLED = "eventMesh.server.useTls.enabled"; + + public static final String KEY_EVENTMESH_SERVER_MSG_REQ_NUM_PER_SECOND = "eventMesh.server.http.msgReqnumPerSecond"; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshHTTPConfiguration.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshHTTPConfiguration.java new file mode 100644 index 0000000000..287fce915a --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshHTTPConfiguration.java @@ -0,0 +1,380 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.configuration; + +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.config.ConfigurationWrapper; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Collections; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; + +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; + +public class EventMeshHTTPConfiguration extends CommonConfiguration { + + public static Logger logger = LoggerFactory.getLogger(EventMeshHTTPConfiguration.class); + + public int httpServerPort = 10105; + + public boolean eventMeshServerBatchMsgBatchEnabled = Boolean.TRUE; + + public int eventMeshServerBatchMsgThreadNum = 10; + + public int eventMeshServerSendMsgThreadNum = 8; + + public int eventMeshServerRemoteMsgThreadNum = 8; + + public int eventMeshServerPushMsgThreadNum = 8; + + public int eventMeshServerReplyMsgThreadNum = 8; + + public int eventMeshServerClientManageThreadNum = 4; + + public int eventMeshServerRegistryThreadNum = 10; + + public int eventMeshServerAdminThreadNum = 2; + + public int eventMeshServerRetryThreadNum = 2; + + public int eventMeshServerWebhookThreadNum = 4; + + public int eventMeshServerPullRegistryInterval = 30000; + + public int eventMeshServerAsyncAccumulationThreshold = 1000; + + public int eventMeshServerRetryBlockQSize = 10000; + + public int eventMeshServerBatchBlockQSize = 1000; + + public int eventMeshServerSendMsgBlockQSize = 1000; + + public int eventMeshServerRemoteMsgBlockQSize = 1000; + + public int eventMeshServerPushMsgBlockQSize = 1000; + + public int eventMeshServerClientManageBlockQSize = 1000; + + public int eventMeshServerBusyCheckInterval = 1000; + + public boolean eventMeshServerConsumerEnabled = false; + + public boolean eventMeshServerUseTls = false; + + public int eventMeshHttpMsgReqNumPerSecond = 15000; + + public int eventMeshBatchMsgRequestNumPerSecond = 20000; + + public int eventMeshEventSize = 1000; + + public int eventMeshEventBatchSize = 10; + + public List eventMeshIpv4BlackList = Collections.emptyList(); + + public List eventMeshIpv6BlackList = Collections.emptyList(); + + public EventMeshHTTPConfiguration(ConfigurationWrapper configurationWrapper) { + super(configurationWrapper); + } + + @Override + public void init() { + super.init(); + + if (configurationWrapper != null) { + String httpServerPortStr = configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_SERVER_HTTP_PORT); + Preconditions.checkState(StringUtils.isNotEmpty(httpServerPortStr) + && StringUtils.isNumeric(httpServerPortStr), String.format("%s error", ConfKeys.KEYS_EVENTMESH_SERVER_HTTP_PORT)); + httpServerPort = Integer.parseInt(StringUtils.deleteWhitespace(httpServerPortStr)); + + String eventMeshServerBatchMsgThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_BATCHMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerBatchMsgThreadNumStr) + && StringUtils.isNumeric(eventMeshServerBatchMsgThreadNumStr)) { + eventMeshServerBatchMsgThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerBatchMsgThreadNumStr)); + } + + String eventMeshServerBatchMsgReqNumPerSecondStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_BATCHMSG_REQ_NUM_PER_SECOND); + if (StringUtils.isNotEmpty(eventMeshServerBatchMsgReqNumPerSecondStr) + && StringUtils.isNumeric(eventMeshServerBatchMsgReqNumPerSecondStr)) { + eventMeshBatchMsgRequestNumPerSecond = Integer.parseInt(eventMeshServerBatchMsgReqNumPerSecondStr); + } + + String eventMeshServerBatchMsgBatchEnableStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_BATCHMSG_BATCH_ENABLED); + if (StringUtils.isNotBlank(eventMeshServerBatchMsgBatchEnableStr)) { + eventMeshServerBatchMsgBatchEnabled = Boolean.parseBoolean(eventMeshServerBatchMsgBatchEnableStr); + } + + String eventMeshServerAsyncAccumulationThresholdStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ASYNC_ACCUMULATION_THRESHOLD); + if (StringUtils.isNotEmpty(eventMeshServerAsyncAccumulationThresholdStr) + && StringUtils.isNumeric(eventMeshServerAsyncAccumulationThresholdStr)) { + eventMeshServerAsyncAccumulationThreshold = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerAsyncAccumulationThresholdStr)); + } + + String eventMeshServerSendMsgThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_SENDMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerSendMsgThreadNumStr) + && StringUtils.isNumeric(eventMeshServerSendMsgThreadNumStr)) { + eventMeshServerSendMsgThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerSendMsgThreadNumStr)); + } + + String eventMeshServerRemoteMsgThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_REMOTEMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerRemoteMsgThreadNumStr) + && StringUtils.isNumeric(eventMeshServerRemoteMsgThreadNumStr)) { + eventMeshServerRemoteMsgThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerRemoteMsgThreadNumStr)); + } + + String eventMeshServerReplyMsgThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_REPLYMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerReplyMsgThreadNumStr) + && StringUtils.isNumeric(eventMeshServerReplyMsgThreadNumStr)) { + eventMeshServerReplyMsgThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerReplyMsgThreadNumStr)); + } + + String eventMeshServerPushMsgThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_PUSHMSG_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerPushMsgThreadNumStr) + && StringUtils.isNumeric(eventMeshServerPushMsgThreadNumStr)) { + eventMeshServerPushMsgThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerPushMsgThreadNumStr)); + } + + String eventMeshServerRegistryThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_REGISTRY_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerRegistryThreadNumStr) + && StringUtils.isNumeric(eventMeshServerRegistryThreadNumStr)) { + eventMeshServerRegistryThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerRegistryThreadNumStr)); + } + + String eventMeshServerClientManageThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_CLIENTMANAGE_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerClientManageThreadNumStr) + && StringUtils.isNumeric(eventMeshServerClientManageThreadNumStr)) { + eventMeshServerClientManageThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerClientManageThreadNumStr)); + } + + String eventMeshServerPullRegistryIntervalStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_PULL_REGISTRY_INTERVAL); + if (StringUtils.isNotEmpty(eventMeshServerPullRegistryIntervalStr) + && StringUtils.isNumeric(eventMeshServerPullRegistryIntervalStr)) { + eventMeshServerPullRegistryInterval = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerPullRegistryIntervalStr)); + } + + String eventMeshServerAdminThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEYS_EVENTMESH_ADMIN_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerAdminThreadNumStr) + && StringUtils.isNumeric(eventMeshServerAdminThreadNumStr)) { + eventMeshServerAdminThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerAdminThreadNumStr)); + } + + String eventMeshServerRetryBlockQSizeStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_RETRY_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerRetryBlockQSizeStr) + && StringUtils.isNumeric(eventMeshServerRetryBlockQSizeStr)) { + eventMeshServerRetryBlockQSize = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerRetryBlockQSizeStr)); + } + + String eventMeshServerBatchBlockQSizeStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_BATCHMSG_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerBatchBlockQSizeStr) + && StringUtils.isNumeric(eventMeshServerBatchBlockQSizeStr)) { + eventMeshServerBatchBlockQSize = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerBatchBlockQSizeStr)); + } + + String eventMeshServerSendMsgBlockQSizeStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SENDMSG_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerSendMsgBlockQSizeStr) + && StringUtils.isNumeric(eventMeshServerSendMsgBlockQSizeStr)) { + eventMeshServerSendMsgBlockQSize = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerSendMsgBlockQSizeStr)); + } + + String eventMeshServerPushMsgBlockQSizeStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_PUSHMSG_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerPushMsgBlockQSizeStr) + && StringUtils.isNumeric(eventMeshServerPushMsgBlockQSizeStr)) { + eventMeshServerPushMsgBlockQSize = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerPushMsgBlockQSizeStr)); + } + + String eventMeshServerClientManageBlockQSizeStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_CLIENTM_BLOCKQ_SIZE); + if (StringUtils.isNotEmpty(eventMeshServerClientManageBlockQSizeStr) + && StringUtils.isNumeric(eventMeshServerClientManageBlockQSizeStr)) { + eventMeshServerClientManageBlockQSize = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerClientManageBlockQSizeStr)); + } + + String eventMeshServerBusyCheckIntervalStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_BUSY_CHECK_INTERVAL); + if (StringUtils.isNotEmpty(eventMeshServerBusyCheckIntervalStr) + && StringUtils.isNumeric(eventMeshServerBusyCheckIntervalStr)) { + eventMeshServerBusyCheckInterval = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerBusyCheckIntervalStr)); + + } + + String eventMeshServerConsumerEnabledStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_CONSUMER_ENABLED); + if (StringUtils.isNotEmpty(eventMeshServerConsumerEnabledStr)) { + eventMeshServerConsumerEnabled = + Boolean.parseBoolean(StringUtils.deleteWhitespace(eventMeshServerConsumerEnabledStr)); + } + + + String eventMeshServerRetryThreadNumStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_RETRY_THREAD_NUM); + if (StringUtils.isNotEmpty(eventMeshServerRetryThreadNumStr) + && StringUtils.isNumeric(eventMeshServerRetryThreadNumStr)) { + eventMeshServerRetryThreadNum = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshServerRetryThreadNumStr)); + + } + + String eventMeshServerUseTlsStr = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_HTTPS_ENABLED); + if (StringUtils.isNotEmpty(eventMeshServerUseTlsStr)) { + eventMeshServerUseTls = Boolean.parseBoolean(StringUtils.deleteWhitespace(eventMeshServerUseTlsStr)); + } + + + String eventMeshHttpMsgReqNumPerSecondStr = + configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SERVER_MSG_REQ_NUM_PER_SECOND); + if (StringUtils.isNotEmpty(eventMeshHttpMsgReqNumPerSecondStr) + && StringUtils.isNumeric(eventMeshHttpMsgReqNumPerSecondStr)) { + eventMeshHttpMsgReqNumPerSecond = Integer.parseInt(eventMeshHttpMsgReqNumPerSecondStr); + + } + + String eventSize = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SERVER_EVENTSIZE); + if (StringUtils.isNotEmpty(eventSize) && StringUtils.isNumeric(eventSize)) { + eventMeshEventSize = Integer.parseInt(eventSize); + } + + String eventBatchSize = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SERVER_EVENT_BATCHSIZE); + if (StringUtils.isNotEmpty(eventBatchSize) && StringUtils.isNumeric(eventBatchSize)) { + eventMeshEventBatchSize = Integer.parseInt(eventBatchSize); + } + + String ipv4BlackList = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SERVER_IPV4_BLACK_LIST); + if (StringUtils.isNotEmpty(ipv4BlackList)) { + eventMeshIpv4BlackList = getBlacklist(ipv4BlackList); + } + + String ipv6BlackList = configurationWrapper.getProp(ConfKeys.KEY_EVENTMESH_SERVER_IPV6_BLACK_LIST); + if (StringUtils.isNotEmpty(ipv6BlackList)) { + eventMeshIpv6BlackList = getBlacklist(ipv6BlackList); + } + } + } + + private static List getBlacklist(String cidrs) { + List cidrList = Splitter.on(",").omitEmptyStrings() + .trimResults().splitToList(cidrs); + + List ipAddresses = Lists.newArrayList(); + for (String cidr : cidrList) { + try { + ipAddresses.add(new IPAddressString(cidr).toAddress()); + } catch (Exception e) { + logger.warn("Invalid cidr={}", cidr, e); + } + } + return ipAddresses; + } + + static class ConfKeys { + + public static final String KEYS_EVENTMESH_SERVER_HTTP_PORT = "eventMesh.server.http.port"; + + public static final String KEYS_EVENTMESH_BATCHMSG_THREAD_NUM = "eventMesh.server.batchmsg.threads.num"; + + public static final String KEYS_EVENTMESH_BATCHMSG_REQ_NUM_PER_SECOND = "eventMesh.server.batchmsg.reqNumPerSecond"; + + public static final String KEYS_EVENTMESH_BATCHMSG_BATCH_ENABLED = "eventMesh.server.batchmsg.batch.enabled"; + + public static final String KEYS_EVENTMESH_ASYNC_ACCUMULATION_THRESHOLD = "eventMesh.server.async.accumulation.threshold"; + + public static final String KEY_EVENTMESH_BUSY_CHECK_INTERVAL = "eventMesh.server.busy.check.interval"; + + public static final String KEYS_EVENTMESH_SENDMSG_THREAD_NUM = "eventMesh.server.sendmsg.threads.num"; + + public static final String KEYS_EVENTMESH_REMOTEMSG_THREAD_NUM = "eventMesh.server.remotemsg.threads.num"; + + public static final String KEYS_EVENTMESH_REPLYMSG_THREAD_NUM = "eventMesh.server.replymsg.threads.num"; + + public static final String KEYS_EVENTMESH_PUSHMSG_THREAD_NUM = "eventMesh.server.pushmsg.threads.num"; + + public static final String KEYS_EVENTMESH_REGISTRY_THREAD_NUM = "eventMesh.server.registry.threads.num"; + + public static final String KEYS_EVENTMESH_CLIENTMANAGE_THREAD_NUM = "eventMesh.server.clientmanage.threads.num"; + + public static final String KEYS_EVENTMESH_ADMIN_THREAD_NUM = "eventMesh.server.admin.threads.num"; + + public static final String KEY_EVENTMESH_RETRY_THREAD_NUM = "eventMesh.server.retry.threads.num"; + + public static final String KEYS_EVENTMESH_PULL_REGISTRY_INTERVAL = "eventMesh.server.pull.registry.interval"; + + public static final String KEY_EVENTMESH_RETRY_BLOCKQ_SIZE = "eventMesh.server.retry.blockQ.size"; + + public static final String KEY_EVENTMESH_BATCHMSG_BLOCKQ_SIZE = "eventMesh.server.batchmsg.blockQ.size"; + + public static final String KEY_EVENTMESH_SENDMSG_BLOCKQ_SIZE = "eventMesh.server.sendmsg.blockQ.size"; + + public static final String KEY_EVENTMESH_PUSHMSG_BLOCKQ_SIZE = "eventMesh.server.pushmsg.blockQ.size"; + + public static final String KEY_EVENTMESH_CLIENTM_BLOCKQ_SIZE = "eventMesh.server.clientM.blockQ.size"; + + public static final String KEY_EVENTMESH_CONSUMER_ENABLED = "eventMesh.server.consumer.enabled"; + + public static final String KEY_EVENTMESH_HTTPS_ENABLED = "eventMesh.server.useTls.enabled"; + + public static final String KEY_EVENTMESH_SERVER_MSG_REQ_NUM_PER_SECOND = "eventMesh.server.http.msgReqnumPerSecond"; + + public static final String KEY_EVENTMESH_SERVER_EVENTSIZE = "eventMesh.server.maxEventSize"; + + public static final String KEY_EVENTMESH_SERVER_EVENT_BATCHSIZE = "eventMesh.server.maxEventBatchSize"; + + public static final String KEY_EVENTMESH_SERVER_IPV4_BLACK_LIST = "eventMesh.server.blacklist.ipv4"; + + public static final String KEY_EVENTMESH_SERVER_IPV6_BLACK_LIST = "eventMesh.server.blacklist.ipv6"; + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshTCPConfiguration.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshTCPConfiguration.java new file mode 100644 index 0000000000..3bf071fa2d --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/configuration/EventMeshTCPConfiguration.java @@ -0,0 +1,271 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.configuration; + +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.config.ConfigurationWrapper; + +public class EventMeshTCPConfiguration extends CommonConfiguration { + public int eventMeshTcpServerPort = 10000; + + public int eventMeshTcpIdleAllSeconds = 60; + + public int eventMeshTcpIdleWriteSeconds = 60; + + public int eventMeshTcpIdleReadSeconds = 60; + + public Integer eventMeshTcpMsgReqnumPerSecond = 15000; + + /** + * TCP Server allows max client num + */ + public int eventMeshTcpClientMaxNum = 10000; + + //======================================= New add config ================================= + /** + * whether enable TCP Serer + */ + public boolean eventMeshTcpServerEnabled = Boolean.FALSE; + + public int eventMeshTcpGlobalScheduler = 5; + + public int eventMeshTcpTaskHandleExecutorPoolSize = Runtime.getRuntime().availableProcessors(); + + public int eventMeshTcpMsgDownStreamExecutorPoolSize = Math.max(Runtime.getRuntime().availableProcessors(), 8); + + public int eventMeshTcpSessionExpiredInMills = 60000; + + public int eventMeshTcpSessionUpstreamBufferSize = 100; + + public int eventMeshTcpMsgAsyncRetryTimes = 3; + + public int eventMeshTcpMsgSyncRetryTimes = 1; + + public int eventMeshTcpMsgRetrySyncDelayInMills = 500; + + public int eventMeshTcpMsgRetryAsyncDelayInMills = 500; + + public int eventMeshTcpMsgRetryQueueSize = 10000; + + public Integer eventMeshTcpRebalanceIntervalInMills = 30 * 1000; + + public int eventMeshServerAdminPort = 10106; + + public boolean eventMeshTcpSendBackEnabled = Boolean.TRUE; + + public int eventMeshTcpSendBackMaxTimes = 3; + + public int eventMeshTcpPushFailIsolateTimeInMills = 30 * 1000; + + public int gracefulShutdownSleepIntervalInMills = 1000; + + public int sleepIntervalInRebalanceRedirectMills = 200; + + public int eventMeshEventSize = 1000; + + public int eventMeshEventBatchSize = 10; + + private TrafficShapingConfig gtc = new TrafficShapingConfig(0, 10_000, 1_000, 2000); + private TrafficShapingConfig ctc = new TrafficShapingConfig(0, 2_000, 1_000, 10_000); + + public EventMeshTCPConfiguration(ConfigurationWrapper configurationWrapper) { + super(configurationWrapper); + } + + @Override + public void init() { + super.init(); + eventMeshTcpServerPort = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_TCP_PORT, eventMeshTcpServerPort); + + eventMeshTcpIdleReadSeconds = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_READER_IDLE_SECONDS, + eventMeshTcpIdleReadSeconds); + + eventMeshTcpIdleWriteSeconds = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_WRITER_IDLE_SECONDS, + eventMeshTcpIdleWriteSeconds); + + eventMeshTcpIdleAllSeconds = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_ALL_IDLE_SECONDS, + eventMeshTcpIdleAllSeconds); + + eventMeshTcpMsgReqnumPerSecond = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_MSG_REQ_NUM_PER_SECONDS, + eventMeshTcpMsgReqnumPerSecond); + + eventMeshTcpClientMaxNum = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_CLIENT_MAX_NUM, + eventMeshTcpClientMaxNum); + + eventMeshTcpServerEnabled = configurationWrapper.getBoolProp(ConfKeys.KEYS_EVENTMESH_TCP_SERVER_ENABLED, + eventMeshTcpServerEnabled); + + eventMeshTcpGlobalScheduler = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_GLOBAL_SCHEDULER, + eventMeshTcpGlobalScheduler); + + eventMeshTcpTaskHandleExecutorPoolSize = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_TCP_TASK_HANDLE_POOL_SIZE, eventMeshTcpTaskHandleExecutorPoolSize); + + eventMeshTcpMsgDownStreamExecutorPoolSize = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_TCP_MSG_DOWNSTREAM_POOL_SIZE, eventMeshTcpMsgDownStreamExecutorPoolSize); + + eventMeshTcpSessionExpiredInMills = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_SESSION_EXPIRED_TIME, eventMeshTcpSessionExpiredInMills); + + eventMeshTcpSessionUpstreamBufferSize = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_SESSION_UPSTREAM_BUFFER_SIZE, eventMeshTcpSessionUpstreamBufferSize); + + //========================================eventMesh retry config=============================================// + eventMeshTcpMsgAsyncRetryTimes = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_RETRY_ASYNC_PUSH_RETRY_TIMES, eventMeshTcpMsgAsyncRetryTimes); + + eventMeshTcpMsgSyncRetryTimes = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_RETRY_SYNC_PUSH_RETRY_TIMES, eventMeshTcpMsgSyncRetryTimes); + + eventMeshTcpMsgRetryAsyncDelayInMills = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_RETRY_ASYNC_PUSH_RETRY_DELAY, eventMeshTcpMsgRetryAsyncDelayInMills); + + eventMeshTcpMsgRetrySyncDelayInMills = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_RETRY_SYNC_PUSH_RETRY_DELAY, eventMeshTcpMsgRetrySyncDelayInMills); + + eventMeshTcpMsgRetryQueueSize = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_RETRY_PUSH_RETRY_QUEUE_SIZE, eventMeshTcpMsgRetryQueueSize); + + eventMeshTcpRebalanceIntervalInMills = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_TCP_REBALANCE_INTERVAL, eventMeshTcpRebalanceIntervalInMills); + + eventMeshServerAdminPort = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_ADMIN_HTTP_PORT, eventMeshServerAdminPort); + + eventMeshTcpSendBackEnabled = configurationWrapper.getBoolProp( + ConfKeys.KEYS_EVENTMESH_TCP_SEND_BACK_ENABLED, eventMeshTcpSendBackEnabled); + + eventMeshTcpPushFailIsolateTimeInMills = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_PUSH_FAIL_ISOLATE_TIME, eventMeshTcpPushFailIsolateTimeInMills); + + gracefulShutdownSleepIntervalInMills = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_GRACEFUL_SHUTDOWN_SLEEP_TIME, gracefulShutdownSleepIntervalInMills); + + sleepIntervalInRebalanceRedirectMills = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_REBALANCE_REDIRECT_SLEEP_TIME, sleepIntervalInRebalanceRedirectMills); + + eventMeshEventSize = configurationWrapper.getIntProp(ConfKeys.KEYS_EVENTMESH_SERVER_EVENTSIZE, eventMeshEventSize); + + eventMeshEventBatchSize = configurationWrapper.getIntProp( + ConfKeys.KEYS_EVENTMESH_SERVER_EVENT_BATCHSIZE, eventMeshEventBatchSize); + } + + public TrafficShapingConfig getGtc() { + return gtc; + } + + public TrafficShapingConfig getCtc() { + return ctc; + } + + static class ConfKeys { + + public static final String KEYS_EVENTMESH_SERVER_TCP_PORT = "eventMesh.server.tcp.port"; + public static final String KEYS_EVENTMESH_SERVER_READER_IDLE_SECONDS = "eventMesh.server.tcp.readerIdleSeconds"; + public static final String KEYS_EVENTMESH_SERVER_WRITER_IDLE_SECONDS = "eventMesh.server.tcp.writerIdleSeconds"; + public static final String KEYS_EVENTMESH_SERVER_ALL_IDLE_SECONDS = "eventMesh.server.tcp.allIdleSeconds"; + public static final String KEYS_EVENTMESH_SERVER_CLIENT_MAX_NUM = "eventMesh.server.tcp.clientMaxNum"; + public static final String KEYS_EVENTMESH_SERVER_MSG_REQ_NUM_PER_SECONDS = "eventMesh.server.tcp.msgReqnumPerSecond"; + public static final String KEYS_EVENTMESH_SERVER_TCP_REBALANCE_INTERVAL = "eventMesh.server.tcp.RebalanceIntervalInMills"; + public static final String KEYS_EVENTMESH_SERVER_GLOBAL_SCHEDULER = "eventMesh.server.global.scheduler"; + public static final String KEYS_EVENTMESH_SERVER_TCP_TASK_HANDLE_POOL_SIZE = "eventMesh.server.tcp.taskHandleExecutorPoolSize"; + public static final String KEYS_EVENTMESH_SERVER_TCP_MSG_DOWNSTREAM_POOL_SIZE = "eventMesh.server.tcp.msgDownStreamExecutorPoolSize"; + public static final String KEYS_EVENTMESH_SERVER_SESSION_EXPIRED_TIME = "eventMesh.server.session.expiredInMills"; + public static final String KEYS_EVENTMESH_SERVER_SESSION_UPSTREAM_BUFFER_SIZE = "eventMesh.server.session.upstreamBufferSize"; + public static final String KEYS_EVENTMESH_SERVER_SESSION_DOWNSTREAM_UNACK_SIZE = "eventMesh.server.session.downstreamUnackSize"; + public static final String KEYS_EVENTMESH_SERVER_RETRY_ASYNC_PUSH_RETRY_TIMES = "eventMesh.server.retry.async.pushRetryTimes"; + public static final String KEYS_EVENTMESH_SERVER_RETRY_SYNC_PUSH_RETRY_TIMES = "eventMesh.server.retry.sync.pushRetryTimes"; + public static final String KEYS_EVENTMESH_SERVER_RETRY_ASYNC_PUSH_RETRY_DELAY = "eventMesh.server.retry.async.pushRetryDelayInMills"; + public static final String KEYS_EVENTMESH_SERVER_RETRY_SYNC_PUSH_RETRY_DELAY = "eventMesh.server.retry.sync.pushRetryDelayInMills"; + public static final String KEYS_EVENTMESH_SERVER_RETRY_PUSH_RETRY_QUEUE_SIZE = "eventMesh.server.retry.pushRetryQueueSize"; + public static final String KEYS_EVENTMESH_SERVER_ADMIN_HTTP_PORT = "eventMesh.server.admin.http.port"; + public static final String KEYS_EVENTMESH_TCP_SERVER_ENABLED = "eventMesh.server.tcp.enabled"; + public static final String KEYS_EVENTMESH_TCP_SEND_BACK_ENABLED = "eventMesh.server.tcp.sendBack.enabled"; + public static final String KEYS_EVENTMESH_SERVER_PUSH_FAIL_ISOLATE_TIME = "eventMesh.server.tcp.pushFailIsolateTimeInMills"; + public static final String KEYS_EVENTMESH_SERVER_GRACEFUL_SHUTDOWN_SLEEP_TIME = "eventMesh.server.gracefulShutdown.sleepIntervalInMills"; + public static final String KEYS_EVENTMESH_SERVER_REBALANCE_REDIRECT_SLEEP_TIME = "eventMesh.server.rebalanceRedirect.sleepIntervalInM"; + public static final String KEYS_EVENTMESH_SERVER_EVENTSIZE = "eventMesh.server.maxEventSize"; + public static final String KEYS_EVENTMESH_SERVER_EVENT_BATCHSIZE = "eventMesh.server.maxEventBatchSize"; + } + + public static class TrafficShapingConfig { + long writeLimit = 0; + long readLimit = 1000; + long checkInterval = 1000; + long maxTime = 5000; + + public TrafficShapingConfig(long writeLimit, long readLimit, long checkInterval, long maxTime) { + this.writeLimit = writeLimit; + this.readLimit = readLimit; + this.checkInterval = checkInterval; + this.maxTime = maxTime; + } + + public TrafficShapingConfig() { + + } + + public long getWriteLimit() { + return writeLimit; + } + + public void setWriteLimit(long writeLimit) { + this.writeLimit = writeLimit; + } + + public long getReadLimit() { + return readLimit; + } + + public void setReadLimit(long readLimit) { + this.readLimit = readLimit; + } + + public long getCheckInterval() { + return checkInterval; + } + + public void setCheckInterval(long checkInterval) { + this.checkInterval = checkInterval; + } + + public long getMaxTime() { + return maxTime; + } + + public void setMaxTime(long maxTime) { + this.maxTime = maxTime; + } + + @Override + public String toString() { + return "TrafficShapingConfig{" + + + "writeLimit=" + writeLimit + + + ", readLimit=" + readLimit + + + ", checkInterval=" + checkInterval + + + ", maxTime=" + maxTime + + + '}'; + } + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/connector/ConnectorResource.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/connector/ConnectorResource.java new file mode 100644 index 0000000000..f47352eaed --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/connector/ConnectorResource.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.connector; + +import org.apache.eventmesh.api.connector.ConnectorResourceService; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConnectorResource { + + private static final Logger logger = LoggerFactory.getLogger(ConnectorResource.class); + private static ConnectorResourceService connectorResourceService; + + public void init(String connectorResourcePluginType) throws Exception { + connectorResourceService = EventMeshExtensionFactory.getExtension(ConnectorResourceService.class, connectorResourcePluginType); + if (connectorResourceService == null) { + logger.error("can't load the connectorResourceService plugin, please check."); + throw new RuntimeException("doesn't load the connectorResourceService plugin, please check."); + } + connectorResourceService.init(); + } + + public void release() throws Exception { + connectorResourceService.release(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/constants/EventMeshConstants.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/constants/EventMeshConstants.java new file mode 100644 index 0000000000..ee84c2993b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/constants/EventMeshConstants.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.constants; + +import org.apache.eventmesh.common.Constants; + +public class EventMeshConstants { + + public static final String EVENT_STORE_PROPERTIES = "eventstore"; + + public static final String EVENT_STORE_ENV = "EVENT_STORE"; + + public static final String PROTOCOL_HTTP = "http"; + + public static final String PROTOCOL_TCP = "tcp"; + + public static final String PROTOCOL_GRPC = "grpc"; + + public static final String DEFAULT_CHARSET = "UTF-8"; + + public static final String IP_PORT_SEPARATOR = ":"; + + public static final String EVENTMESH_CONF_HOME = System.getProperty("confPath", System.getenv("confPath")); + + public static final String EVENTMESH_CONF_FILE = "eventmesh.properties"; + + public static final String REQ_C2EVENTMESH_TIMESTAMP = "reqc2eventmeshtimestamp"; + public static final String REQ_EVENTMESH2MQ_TIMESTAMP = "reqeventmesh2mqtimestamp"; + public static final String REQ_MQ2EVENTMESH_TIMESTAMP = "reqmq2eventmeshtimestamp"; + public static final String REQ_EVENTMESH2C_TIMESTAMP = "reqeventmesh2ctimestamp"; + public static final String RSP_C2EVENTMESH_TIMESTAMP = "rspc2eventmeshtimestamp"; + public static final String RSP_EVENTMESH2MQ_TIMESTAMP = "rspeventmesh2mqtimestamp"; + public static final String RSP_MQ2EVENTMESH_TIMESTAMP = "rspmq2eventmeshtimestamp"; + public static final String RSP_EVENTMESH2C_TIMESTAMP = "rspeventmesh2ctimestamp"; + + public static final String REQ_SEND_EVENTMESH_IP = "reqsendeventmeship"; + public static final String REQ_RECEIVE_EVENTMESH_IP = "reqreceiveeventmeship"; + public static final String RSP_SEND_EVENTMESH_IP = "rspsendeventmeship"; + public static final String RSP_RECEIVE_EVENTMESH_IP = "rspreceiveeventmeship"; + + public static final String RSP_SYS = "rsp0sys"; + public static final String RSP_IP = "rsp0ip"; + public static final String RSP_IDC = "rsp0idc"; + public static final String RSP_GROUP = "rsp0group"; + public static final String RSP_URL = "rsp0url"; + + public static final String REQ_SYS = "req0sys"; + public static final String REQ_IP = "req0ip"; + public static final String REQ_IDC = "req0idc"; + public static final String REQ_GROUP = "req0group"; + + //default TTL 4 hours + public static final Integer DEFAULT_MSG_TTL_MILLS = 14400000; + + public static final int DEFAULT_TIMEOUT_IN_MILLISECONDS = 3000; + + public static final int DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS = 100; + + public static final int DEFAULT_PUSH_RETRY_TIMES = 3; + + public static final int DEFAULT_PUSH_RETRY_TIME_DISTANCE_IN_MILLSECONDS = 3000; + + public static final String PURPOSE_PUB = "pub"; + + public static final String PURPOSE_SUB = "sub"; + + public static final String PURPOSE_ALL = "all"; + + public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; + + + public static final String BORN_TIMESTAMP = "BORN_TIME"; + public static final String STORE_TIMESTAMP = "STORE_TIME"; + public static final String LEAVE_TIMESTAMP = "LEAVE_TIME"; + public static final String ARRIVE_TIMESTAMP = "ARRIVE_TIME"; + + public static final String KEYS_UPPERCASE = "KEYS"; + public static final String KEYS_LOWERCASE = "keys"; + public static final String RR_REQUEST_UNIQ_ID = "RR_REQUEST_UNIQ_ID"; + public static final String TTL = "ttl"; + + public static final String TAG = "TAG"; + + public static final String MANAGE_SUBSYSTEM = "subsystem"; + public static final String MANAGE_IP = "ip"; + public static final String MANAGE_PORT = "port"; + public static final String MANAGE_DEST_IP = "desteventmeshIp"; + public static final String MANAGE_DEST_PORT = "desteventmeshport"; + public static final String MANAGE_PATH = "path"; + public static final String MANAGE_GROUP = "group"; + public static final String MANAGE_PURPOSE = "purpose"; + public static final String MANAGE_TOPIC = "topic"; + + public static final String EVENTMESH_SEND_BACK_TIMES = "eventmeshdendbacktimes"; + + public static final String EVENTMESH_SEND_BACK_IP = "eventmeshsendbackip"; + + public static final String EVENTMESH_REGISTRY_ADDR_KEY = "eventMeshRegistryAddr"; + + public static final int DEFAULT_TIME_OUT_MILLS = 5 * 1000; + + public static final String RR_REPLY_TOPIC = "rr-reply-topic"; + + public static final String PROPERTY_MESSAGE_CLUSTER = "cluster"; + + public static final String PROPERTY_MESSAGE_TTL = "ttl"; + + public static final String PROPERTY_MESSAGE_KEYS = "keys"; + + public static final String PROPERTY_MESSAGE_REPLY_TO = "REPLY_TO"; //requester clientId + + public static final String PROPERTY_RR_REQUEST_ID = "RR_REQUEST_UNIQ_ID"; + + public static final String LEAVE_TIME = "leave" + Constants.MESSAGE_PROP_SEPARATOR + "time"; //leaveBrokerTime + public static final String ARRIVE_TIME = "arrive" + Constants.MESSAGE_PROP_SEPARATOR + "time"; + public static final String STORE_TIME = "store" + Constants.MESSAGE_PROP_SEPARATOR + "time"; + + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/constants/EventMeshVersion.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/constants/EventMeshVersion.java new file mode 100644 index 0000000000..91cc68475f --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/constants/EventMeshVersion.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.constants; + +public class EventMeshVersion { + + public static final String CURRENT_VERSION = Version.V3_0_0.name(); + + public static String getCurrentVersionDesc() { + return CURRENT_VERSION.replaceAll("V", "") + .replaceAll("_", ".") + .replaceAll("_SNAPSHOT", "-SNAPSHOT"); + } + + public enum Version { + V3_0_0, + V3_0_1, + V3_1_0, + V3_2_0, + V3_3_0 + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupConf.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupConf.java new file mode 100644 index 0000000000..2c44b5958e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupConf.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.consumergroup; + +import java.io.Serializable; +import java.util.Map; +import java.util.Objects; + +import com.google.common.collect.Maps; + +public class ConsumerGroupConf implements Serializable { + //eg . 5013-1A0 + private String consumerGroup; + + private Map consumerGroupTopicConf = Maps.newConcurrentMap(); + + public ConsumerGroupConf(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public Map getConsumerGroupTopicConf() { + return consumerGroupTopicConf; + } + + public void setConsumerGroupTopicConf(Map consumerGroupTopicConf) { + this.consumerGroupTopicConf = consumerGroupTopicConf; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConsumerGroupConf that = (ConsumerGroupConf) o; + + return consumerGroup.equals(that.consumerGroup) + && + Objects.equals(consumerGroupTopicConf, that.consumerGroupTopicConf); + } + + @Override + public int hashCode() { + return Objects.hash(consumerGroup, consumerGroupTopicConf); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("consumerGroupConfig={") + .append("groupName=").append(consumerGroup).append(",") + .append(",consumerGroupTopicConf=").append(consumerGroupTopicConf).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupMetadata.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupMetadata.java new file mode 100644 index 0000000000..2644ccd411 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupMetadata.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.consumergroup; + +import java.util.Map; + +import com.google.common.collect.Maps; + +public class ConsumerGroupMetadata { + + /** + * consumer group + */ + private String consumerGroup; + + /** + * consumer group topic metadata + */ + private Map consumerGroupTopicMetadataMap = Maps.newConcurrentMap(); + + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public Map getConsumerGroupTopicMetadataMap() { + return consumerGroupTopicMetadataMap; + } + + public void setConsumerGroupTopicMetadataMap( + Map consumerGroupTopicMetadataMap) { + this.consumerGroupTopicMetadataMap = consumerGroupTopicMetadataMap; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupTopicConf.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupTopicConf.java new file mode 100644 index 0000000000..1bc73e1b20 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupTopicConf.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.consumergroup; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class ConsumerGroupTopicConf implements Serializable { + + public static Logger logger = LoggerFactory.getLogger(ConsumerGroupTopicConf.class); + + private String consumerGroup; + + private String topic; + + /** + * @see org.apache.eventmesh.common.protocol.SubscriptionItem + */ + private SubscriptionItem subscriptionItem; + + /** + * PUSH URL + * Map key:IDC value:URL list in IDC + */ + private Map> idcUrls = Maps.newConcurrentMap(); + + /** + * ALL IDC URLs + */ + private Set urls = Sets.newConcurrentHashSet(); + + /** + * url auth type + */ + private Map httpAuthTypeMap = Maps.newConcurrentMap(); + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConsumerGroupTopicConf that = (ConsumerGroupTopicConf) o; + return consumerGroup.equals(that.consumerGroup) + && + Objects.equals(topic, that.topic) + && + Objects.equals(subscriptionItem, that.subscriptionItem) + && + Objects.equals(idcUrls, that.idcUrls); + } + + @Override + public int hashCode() { + return Objects.hash(consumerGroup, topic, subscriptionItem, idcUrls); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("consumeTopicConfig={consumerGroup=").append(consumerGroup) + .append(",topic=").append(topic) + .append(",subscriptionMode=").append(subscriptionItem) + .append(",idcUrls=").append(idcUrls).append("}"); + return sb.toString(); + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public SubscriptionItem getSubscriptionItem() { + return subscriptionItem; + } + + public void setSubscriptionItem(SubscriptionItem subscriptionItem) { + this.subscriptionItem = subscriptionItem; + } + + public Map> getIdcUrls() { + return idcUrls; + } + + public void setIdcUrls(Map> idcUrls) { + this.idcUrls = idcUrls; + } + + public Set getUrls() { + return urls; + } + + public void setUrls(Set urls) { + this.urls = urls; + } + + public Map getHttpAuthTypeMap() { + return httpAuthTypeMap; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupTopicMetadata.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupTopicMetadata.java new file mode 100644 index 0000000000..3536500144 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ConsumerGroupTopicMetadata.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.consumergroup; + +import java.util.Set; + + +import com.google.common.collect.Sets; + +public class ConsumerGroupTopicMetadata { + /** + * consumer group + */ + private String consumerGroup; + + /** + * subscribed topic + */ + private String topic; + + /** + * ALL IDC URLs + */ + private Set urls = Sets.newConcurrentHashSet(); + + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public Set getUrls() { + return urls; + } + + public void setUrls(Set urls) { + this.urls = urls; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ProducerGroupConf.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ProducerGroupConf.java new file mode 100644 index 0000000000..e121755bca --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/ProducerGroupConf.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.consumergroup; + +import java.util.Objects; + +public class ProducerGroupConf { + private String groupName; + + public ProducerGroupConf(String groupName) { + this.groupName = groupName; + } + + public String getGroupName() { + return groupName; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("producerGroupConfig={") + .append("groupName=").append(groupName).append("}"); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ProducerGroupConf that = (ProducerGroupConf) o; + + if (groupName == that.groupName) { + return true; + } + if (groupName == null) { + return false; + } + return groupName.equals(that.groupName); + } + + @Override + public int hashCode() { + return Objects.hash(groupName); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/event/ConsumerGroupStateEvent.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/event/ConsumerGroupStateEvent.java new file mode 100644 index 0000000000..fbf06125d3 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/event/ConsumerGroupStateEvent.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.consumergroup.event; + +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; + +public class ConsumerGroupStateEvent { + + public String consumerGroup; + public ConsumerGroupStateAction action; + public ConsumerGroupConf consumerGroupConfig; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("consumerGroupStateEvent={") + .append("consumerGroup=").append(consumerGroup) + .append(",action=").append(action).append("}"); + return sb.toString(); + } + + + public enum ConsumerGroupStateAction { + NEW, + CHANGE, + DELETE + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/event/ConsumerGroupTopicConfChangeEvent.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/event/ConsumerGroupTopicConfChangeEvent.java new file mode 100644 index 0000000000..7b19ffb041 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumergroup/event/ConsumerGroupTopicConfChangeEvent.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.consumergroup.event; + +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; + +public class ConsumerGroupTopicConfChangeEvent { + + public ConsumerGroupTopicConfChangeAction action; + + public String topic; + + public String consumerGroup; + + public ConsumerGroupTopicConf newTopicConf; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("consumerGroupTopicConfChangeEvent={") + .append("consumerGroup=").append(consumerGroup).append(",") + .append("topic=").append(topic).append(",") + .append("action=").append(action).append("}"); + return sb.toString(); + } + + public enum ConsumerGroupTopicConfChangeAction { + NEW, + CHANGE, + DELETE + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQConsumerWrapper.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQConsumerWrapper.java new file mode 100644 index 0000000000..6bd8875f89 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQConsumerWrapper.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.plugin; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.consumer.Consumer; +import org.apache.eventmesh.api.factory.ConnectorPluginFactory; + +import java.util.List; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class MQConsumerWrapper extends MQWrapper { + + public final Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected Consumer meshMQPushConsumer; + + public MQConsumerWrapper(String connectorPluginType) { + this.meshMQPushConsumer = ConnectorPluginFactory.getMeshMQPushConsumer(connectorPluginType); + if (meshMQPushConsumer == null) { + logger.error("can't load the meshMQPushConsumer plugin, please check."); + throw new RuntimeException("doesn't load the meshMQPushConsumer plugin, please check."); + } + } + + public void subscribe(String topic) throws Exception { + meshMQPushConsumer.subscribe(topic); + } + + public void unsubscribe(String topic) throws Exception { + meshMQPushConsumer.unsubscribe(topic); + } + + public synchronized void init(Properties keyValue) throws Exception { + + meshMQPushConsumer.init(keyValue); + inited.compareAndSet(false, true); + } + + public synchronized void start() throws Exception { + meshMQPushConsumer.start(); + started.compareAndSet(false, true); + } + + public synchronized void shutdown() throws Exception { + meshMQPushConsumer.shutdown(); + inited.compareAndSet(false, true); + started.compareAndSet(false, true); + } + + public void registerEventListener(EventListener listener) { + meshMQPushConsumer.registerEventListener(listener); + } + + public void updateOffset(List events, AbstractContext eventMeshConsumeConcurrentlyContext) { + meshMQPushConsumer.updateOffset(events, eventMeshConsumeConcurrentlyContext); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQProducerWrapper.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQProducerWrapper.java new file mode 100644 index 0000000000..73411a6fc2 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQProducerWrapper.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.plugin; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.factory.ConnectorPluginFactory; +import org.apache.eventmesh.api.producer.Producer; + +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class MQProducerWrapper extends MQWrapper { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected Producer meshMQProducer; + + public MQProducerWrapper(String connectorPluginType) { + this.meshMQProducer = ConnectorPluginFactory.getMeshMQProducer(connectorPluginType); + if (meshMQProducer == null) { + logger.error("can't load the meshMQProducer plugin, please check."); + throw new RuntimeException("doesn't load the meshMQProducer plugin, please check."); + } + } + + public synchronized void init(Properties keyValue) throws Exception { + if (inited.get()) { + return; + } + + meshMQProducer.init(keyValue); + inited.compareAndSet(false, true); + } + + public synchronized void start() throws Exception { + if (started.get()) { + return; + } + + meshMQProducer.start(); + + started.compareAndSet(false, true); + } + + public synchronized void shutdown() throws Exception { + if (!inited.get()) { + return; + } + + if (!started.get()) { + return; + } + + meshMQProducer.shutdown(); + + inited.compareAndSet(true, false); + started.compareAndSet(true, false); + } + + public void send(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { + meshMQProducer.publish(cloudEvent, sendCallback); + } + + public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) + throws Exception { + meshMQProducer.request(cloudEvent, rrCallback, timeout); + } + + public boolean reply(final CloudEvent cloudEvent, final SendCallback sendCallback) throws Exception { + return meshMQProducer.reply(cloudEvent, sendCallback); + } + + public Producer getMeshMQProducer() { + return meshMQProducer; + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQWrapper.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQWrapper.java new file mode 100644 index 0000000000..c77d18e787 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQWrapper.java @@ -0,0 +1,49 @@ +/* + * Licensed to Apache Software Foundation (ASF) under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.core.plugin; + +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.util.concurrent.atomic.AtomicBoolean; + +public abstract class MQWrapper { + + public static final String EVENT_STORE_ROCKETMQ = "rocketmq"; + + public static final String EVENT_STORE_DEFIBUS = "defibus"; + + public static String CURRENT_EVENT_STORE = EVENT_STORE_DEFIBUS; + + public static final String EVENT_STORE_CONF = System.getProperty(EventMeshConstants.EVENT_STORE_PROPERTIES, + System.getenv(EventMeshConstants.EVENT_STORE_ENV)); + + static { + if (StringUtils.isNotBlank(EVENT_STORE_CONF)) { + CURRENT_EVENT_STORE = EVENT_STORE_CONF; + } + } + + public AtomicBoolean started = new AtomicBoolean(Boolean.FALSE); + + public AtomicBoolean inited = new AtomicBoolean(Boolean.FALSE); + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/ConsumerManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/ConsumerManager.java new file mode 100644 index 0000000000..1f88115324 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/ConsumerManager.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.consumer; + +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupClient; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.GrpcType; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConsumerManager { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + + // key: ConsumerGroup + private final Map> clientTable = new ConcurrentHashMap<>(); + + // key: ConsumerGroup + private final Map consumerTable = new ConcurrentHashMap<>(); + + public ConsumerManager(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void init() throws Exception { + logger.info("Grpc ConsumerManager initialized......"); + } + + public void start() throws Exception { + startClientCheck(); + logger.info("Grpc ConsumerManager started......"); + } + + public void shutdown() throws Exception { + for (EventMeshConsumer consumer : consumerTable.values()) { + consumer.shutdown(); + } + scheduledExecutorService.shutdown(); + logger.info("Grpc ConsumerManager shutdown......"); + } + + public EventMeshConsumer getEventMeshConsumer(String consumerGroup) { + EventMeshConsumer consumer = consumerTable.get(consumerGroup); + if (consumer == null) { + consumer = new EventMeshConsumer(eventMeshGrpcServer, consumerGroup); + consumerTable.put(consumerGroup, consumer); + } + return consumer; + } + + public synchronized void registerClient(ConsumerGroupClient newClient) { + String consumerGroup = newClient.getConsumerGroup(); + String topic = newClient.getTopic(); + GrpcType grpcType = newClient.getGrpcType(); + String url = newClient.getUrl(); + String ip = newClient.getIp(); + String pid = newClient.getPid(); + SubscriptionMode subscriptionMode = newClient.getSubscriptionMode(); + List localClients = clientTable.get(consumerGroup); + + if (localClients == null) { + localClients = new ArrayList<>(); + localClients.add(newClient); + clientTable.put(consumerGroup, localClients); + } else { + boolean isContains = false; + for (ConsumerGroupClient localClient : localClients) { + if (GrpcType.WEBHOOK.equals(grpcType) && StringUtils.equals(localClient.getTopic(), topic) + && StringUtils.equals(localClient.getUrl(), url) + && localClient.getSubscriptionMode().equals(subscriptionMode)) { + isContains = true; + localClient.setUrl(newClient.getUrl()); + localClient.setLastUpTime(newClient.getLastUpTime()); + break; + } else if (GrpcType.STREAM.equals(grpcType) && StringUtils.equals(localClient.getTopic(), topic) + && StringUtils.equals(localClient.getIp(), ip) && StringUtils.equals(localClient.getPid(), pid) + && localClient.getSubscriptionMode().equals(subscriptionMode)) { + isContains = true; + localClient.setEventEmitter(newClient.getEventEmitter()); + localClient.setLastUpTime(newClient.getLastUpTime()); + break; + } + } + if (!isContains) { + localClients.add(newClient); + } + } + } + + public void updateClientTime(ConsumerGroupClient client) { + String consumerGroup = client.getConsumerGroup(); + List localClients = clientTable.get(consumerGroup); + if (CollectionUtils.isEmpty(localClients)) { + return; + } + for (ConsumerGroupClient localClient : localClients) { + if (StringUtils.equals(localClient.getIp(), client.getIp()) + && StringUtils.equals(localClient.getPid(), client.getPid()) + && StringUtils.equals(localClient.getSys(), client.getSys()) + && StringUtils.equals(localClient.getTopic(), client.getTopic())) { + localClient.setLastUpTime(new Date()); + break; + } + } + } + + public synchronized void deregisterClient(ConsumerGroupClient client) { + String consumerGroup = client.getConsumerGroup(); + List localClients = clientTable.get(consumerGroup); + if (CollectionUtils.isEmpty(localClients)) { + return; + } + + Iterator iterator = localClients.iterator(); + while (iterator.hasNext()) { + ConsumerGroupClient localClient = iterator.next(); + if (StringUtils.equals(localClient.getTopic(), client.getTopic()) + && localClient.getSubscriptionMode().equals(client.getSubscriptionMode())) { + + // close the GRPC client stream before removing it + closeEventStream(localClient); + iterator.remove(); + } + } + + if (localClients.size() == 0) { + clientTable.remove(consumerGroup); + } + } + + private void closeEventStream(ConsumerGroupClient client) { + if (client.getEventEmitter() != null) { + client.getEventEmitter().onCompleted(); + } + } + + public synchronized void restartEventMeshConsumer(String consumerGroup) throws Exception { + EventMeshConsumer eventMeshConsumer = consumerTable.get(consumerGroup); + + if (eventMeshConsumer == null) { + return; + } + + if (ServiceState.RUNNING.equals(eventMeshConsumer.getStatus())) { + eventMeshConsumer.shutdown(); + } + + eventMeshConsumer.init(); + eventMeshConsumer.start(); + + if (!ServiceState.RUNNING.equals(eventMeshConsumer.getStatus())) { + consumerTable.remove(consumerGroup); + } + } + + private void startClientCheck() { + int clientTimeout = eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshSessionExpiredInMills; + if (clientTimeout > 0) { + scheduledExecutorService.scheduleAtFixedRate(() -> { + logger.info("grpc client info check"); + List clientList = new LinkedList<>(); + for (List clients : clientTable.values()) { + clientList.addAll(clients); + } + if (logger.isDebugEnabled()) { + logger.debug("total number of ConsumerGroupClients: {}", clientList.size()); + } + + if (clientList.isEmpty()) { + return; + } + Set consumerGroupRestart = new HashSet<>(); + for (ConsumerGroupClient client : clientList) { + if (System.currentTimeMillis() - client.getLastUpTime().getTime() > clientTimeout) { + logger.warn("client {} lastUpdate time {} over three heartbeat cycles. Removing it", + JsonUtils.serialize(client), client.getLastUpTime()); + String consumerGroup = client.getConsumerGroup(); + EventMeshConsumer consumer = getEventMeshConsumer(consumerGroup); + + deregisterClient(client); + if (consumer.deregisterClient(client)) { + consumerGroupRestart.add(consumerGroup); + } + } + } + + // restart EventMeshConsumer for the group + for (String consumerGroup : consumerGroupRestart) { + try { + restartEventMeshConsumer(consumerGroup); + } catch (Exception e) { + logger.error("Error in restarting EventMeshConsumer [{}]", consumerGroup, e); + } + } + }, 10000, 10000, TimeUnit.MILLISECONDS); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/EventMeshConsumer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/EventMeshConsumer.java new file mode 100644 index 0000000000..6324619e9a --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/EventMeshConsumer.java @@ -0,0 +1,298 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.EventMeshAction; +import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.plugin.MQConsumerWrapper; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupClient; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupTopicConfig; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.GrpcType; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext; +import org.apache.eventmesh.runtime.core.protocol.grpc.push.HandleMsgContext; +import org.apache.eventmesh.runtime.core.protocol.grpc.push.MessageHandler; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class EventMeshConsumer { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final String consumerGroup; + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final EventMeshGrpcConfiguration eventMeshGrpcConfiguration; + + private final MQConsumerWrapper persistentMqConsumer; + + private final MQConsumerWrapper broadcastMqConsumer; + + private final MessageHandler messageHandler; + + private ServiceState serviceState; + + /** + * Key: topic + * Value: ConsumerGroupTopicConfig + **/ + private final Map consumerGroupTopicConfig = new ConcurrentHashMap<>(); + + public EventMeshConsumer(EventMeshGrpcServer eventMeshGrpcServer, String consumerGroup) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.eventMeshGrpcConfiguration = eventMeshGrpcServer.getEventMeshGrpcConfiguration(); + this.consumerGroup = consumerGroup; + this.messageHandler = new MessageHandler(consumerGroup, eventMeshGrpcServer.getPushMsgExecutor()); + this.persistentMqConsumer = new MQConsumerWrapper(eventMeshGrpcConfiguration.eventMeshConnectorPluginType); + this.broadcastMqConsumer = new MQConsumerWrapper(eventMeshGrpcConfiguration.eventMeshConnectorPluginType); + } + + /** + * Register client's topic information and return true if this EventMeshConsumer required restart because of the topic changes + * + * @param client ConsumerGroupClient + * @return true if the underlining EventMeshConsumer needs to restart later; false otherwise + */ + public synchronized boolean registerClient(ConsumerGroupClient client) { + boolean requireRestart = false; + GrpcType grpcType = client.getGrpcType(); + String topic = client.getTopic(); + SubscriptionMode subscriptionMode = client.getSubscriptionMode(); + + ConsumerGroupTopicConfig topicConfig = consumerGroupTopicConfig.get(topic); + if (topicConfig == null) { + topicConfig = ConsumerGroupTopicConfig.buildTopicConfig(consumerGroup, topic, subscriptionMode, grpcType); + consumerGroupTopicConfig.put(topic, topicConfig); + requireRestart = true; + } + topicConfig.registerClient(client); + return requireRestart; + } + + /** + * Deregister client's topic information and return true if this EventMeshConsumer required restart because of the topic changes + * + * @param client ConsumerGroupClient + * @return true if the underlining EventMeshConsumer needs to restart later; false otherwise + */ + public synchronized boolean deregisterClient(ConsumerGroupClient client) { + boolean requireRestart = false; + String topic = client.getTopic(); + ConsumerGroupTopicConfig topicConfig = consumerGroupTopicConfig.get(topic); + if (topicConfig != null) { + topicConfig.deregisterClient(client); + if (topicConfig.getSize() == 0) { + consumerGroupTopicConfig.remove(topic); + requireRestart = true; + } + } + return requireRestart; + } + + public synchronized void init() throws Exception { + if (consumerGroupTopicConfig.size() == 0) { + // no topics, don't init the consumer + return; + } + + Properties keyValue = new Properties(); + keyValue.put("isBroadcast", "false"); + keyValue.put("consumerGroup", consumerGroup); + keyValue.put("eventMeshIDC", eventMeshGrpcConfiguration.eventMeshIDC); + keyValue.put("instanceName", EventMeshUtil.buildMeshClientID(consumerGroup, + eventMeshGrpcConfiguration.eventMeshCluster)); + persistentMqConsumer.init(keyValue); + EventListener clusterEventListner = createEventListener(SubscriptionMode.CLUSTERING); + persistentMqConsumer.registerEventListener(clusterEventListner); + + Properties broadcastKeyValue = new Properties(); + broadcastKeyValue.put("isBroadcast", "true"); + broadcastKeyValue.put("consumerGroup", consumerGroup); + broadcastKeyValue.put("eventMeshIDC", eventMeshGrpcConfiguration.eventMeshIDC); + broadcastKeyValue.put("instanceName", EventMeshUtil.buildMeshClientID(consumerGroup, + eventMeshGrpcConfiguration.eventMeshCluster)); + broadcastMqConsumer.init(broadcastKeyValue); + EventListener broadcastEventListner = createEventListener(SubscriptionMode.BROADCASTING); + broadcastMqConsumer.registerEventListener(broadcastEventListner); + + serviceState = ServiceState.INITED; + logger.info("EventMeshConsumer [{}] initialized.............", consumerGroup); + } + + public synchronized void start() throws Exception { + if (consumerGroupTopicConfig.size() == 0) { + // no topics, don't start the consumer + return; + } + + for (Map.Entry entry : consumerGroupTopicConfig.entrySet()) { + subscribe(entry.getKey(), entry.getValue().getSubscriptionMode()); + } + + persistentMqConsumer.start(); + broadcastMqConsumer.start(); + + serviceState = ServiceState.RUNNING; + logger.info("EventMeshConsumer [{}] started..........", consumerGroup); + } + + public synchronized void shutdown() throws Exception { + persistentMqConsumer.shutdown(); + broadcastMqConsumer.shutdown(); + + serviceState = ServiceState.STOPED; + logger.info("EventMeshConsumer [{}] shutdown.........", consumerGroup); + } + + public ServiceState getStatus() { + return serviceState; + } + + public void subscribe(String topic, SubscriptionMode subscriptionMode) throws Exception { + if (SubscriptionMode.CLUSTERING.equals(subscriptionMode)) { + persistentMqConsumer.subscribe(topic); + } else if (SubscriptionMode.BROADCASTING.equals(subscriptionMode)) { + broadcastMqConsumer.subscribe(topic); + } else { + logger.error("Subscribe Failed. Incorrect Subscription Mode"); + throw new Exception("Subscribe Failed. Incorrect Subscription Mode"); + } + } + + public void unsubscribe(Subscription.SubscriptionItem subscriptionItem) throws Exception { + SubscriptionMode mode = subscriptionItem.getMode(); + String topic = subscriptionItem.getTopic(); + if (SubscriptionMode.CLUSTERING.equals(mode)) { + persistentMqConsumer.unsubscribe(topic); + } else if (SubscriptionMode.BROADCASTING.equals(mode)) { + broadcastMqConsumer.unsubscribe(topic); + } else { + logger.error("Unsubscribe Failed. Incorrect Subscription Mode"); + throw new Exception("Unsubscribe Failed. Incorrect Subscription Mode"); + } + } + + public void updateOffset(SubscriptionMode subscriptionMode, List events, + AbstractContext context) throws Exception { + if (SubscriptionMode.CLUSTERING.equals(subscriptionMode)) { + persistentMqConsumer.updateOffset(events, context); + } else if (SubscriptionMode.BROADCASTING.equals(subscriptionMode)) { + broadcastMqConsumer.updateOffset(events, context); + } else { + logger.error("Subscribe Failed. Incorrect Subscription Mode"); + throw new Exception("Subscribe Failed. Incorrect Subscription Mode"); + } + } + + private EventListener createEventListener(SubscriptionMode subscriptionMode) { + return (event, context) -> { + + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + + String topic = event.getSubject(); + Object bizSeqNo = event.getExtension(Constants.PROPERTY_MESSAGE_SEARCH_KEYS); + String strBizSeqNo = bizSeqNo == null ? "" : bizSeqNo.toString(); + + Object uniqueId = event.getExtension(Constants.RMB_UNIQ_ID); + String strUniqueId = uniqueId == null ? "" : uniqueId.toString(); + + if (logger.isDebugEnabled()) { + logger.debug("message|mq2eventMesh|topic={}|msg={}", topic, event); + } else { + logger.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", topic, bizSeqNo, uniqueId); + } + + EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = (EventMeshAsyncConsumeContext) context; + + ConsumerGroupTopicConfig topicConfig = consumerGroupTopicConfig.get(topic); + + if (topicConfig != null) { + GrpcType grpcType = topicConfig.getGrpcType(); + HandleMsgContext handleMsgContext = new HandleMsgContext(consumerGroup, event, subscriptionMode, grpcType, + eventMeshAsyncConsumeContext.getAbstractContext(), eventMeshGrpcServer, this, topicConfig); + + if (messageHandler.handle(handleMsgContext)) { + eventMeshAsyncConsumeContext.commit(EventMeshAction.ManualAck); + return; + } else { + // can not handle the message due to the capacity limit is reached + // wait for sometime and send this message back to mq and consume again + try { + Thread.sleep(5000); + sendMessageBack(consumerGroup, event, strUniqueId, strBizSeqNo); + } catch (Exception ignored) { + // ignore exception + } + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("no active consumer for topic={}|msg={}", topic, event); + } + } + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + }; + } + + public void sendMessageBack(String consumerGroup, final CloudEvent event, final String uniqueId, String bizSeqNo) throws Exception { + EventMeshProducer producer + = eventMeshGrpcServer.getProducerManager().getEventMeshProducer(consumerGroup); + + if (producer == null) { + logger.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", consumerGroup, bizSeqNo, uniqueId); + return; + } + + final SendMessageContext sendMessageBackContext = new SendMessageContext(bizSeqNo, event, producer, eventMeshGrpcServer); + + producer.send(sendMessageBackContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + } + + @Override + public void onException(OnExceptionContext context) { + logger.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", consumerGroup, bizSeqNo, uniqueId); + } + }); + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/ConsumerGroupClient.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/ConsumerGroupClient.java new file mode 100644 index 0000000000..679ed51779 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/ConsumerGroupClient.java @@ -0,0 +1,91 @@ +/* + * Licensed to Apache Software Foundation (ASF) under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; + +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; + +import java.util.Date; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class ConsumerGroupClient { + + private final String env; + + private final String idc; + + private final String consumerGroup; + + private final String topic; + + private final GrpcType grpcType; + + private String url; + + private EventEmitter eventEmitter; + + private final SubscriptionMode subscriptionMode; + + private final String sys; + + private final String ip; + + private final String pid; + + private final String hostname; + + private final String apiVersion; + + private Date lastUpTime; + + public void setUrl(String url) { + this.url = url; + } + + public void setEventEmitter(EventEmitter emitter) { + this.eventEmitter = emitter; + } + + public void setLastUpTime(Date lastUpTime) { + this.lastUpTime = lastUpTime; + } + + @Override + public String toString() { + return "endPoint={env=" + env + + ",idc=" + idc + + ",consumerGroup=" + consumerGroup + + ",topic=" + topic + + ",grpcType=" + grpcType + + ",url=" + url + + ",sys=" + sys + + ",ip=" + ip + + ",pid=" + pid + + ",hostname=" + hostname + + ",apiVersion=" + apiVersion + + ",lastUpTime=" + lastUpTime + "}"; + } +} + diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/ConsumerGroupTopicConfig.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/ConsumerGroupTopicConfig.java new file mode 100644 index 0000000000..1e4c608959 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/ConsumerGroupTopicConfig.java @@ -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 org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; + +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class ConsumerGroupTopicConfig { + private final Logger logger = LoggerFactory.getLogger(ConsumerGroupTopicConfig.class); + + protected final String consumerGroup; + + protected final String topic; + + protected final SubscriptionMode subscriptionMode; + + protected final GrpcType grpcType; + + protected ConsumerGroupTopicConfig(String consumerGroup, String topic, SubscriptionMode subscriptionMode, GrpcType grpcType) { + this.consumerGroup = consumerGroup; + this.topic = topic; + this.subscriptionMode = subscriptionMode; + this.grpcType = grpcType; + } + + public static ConsumerGroupTopicConfig buildTopicConfig(String consumerGroup, String topic, SubscriptionMode subscriptionMode, + GrpcType grpcType) { + if (GrpcType.STREAM.equals(grpcType)) { + return new StreamTopicConfig(consumerGroup, topic, subscriptionMode); + } else { + return new WebhookTopicConfig(consumerGroup, topic, subscriptionMode); + } + } + + public abstract void registerClient(ConsumerGroupClient client); + + public abstract void deregisterClient(ConsumerGroupClient client); + + public abstract int getSize(); + + public String getConsumerGroup() { + return consumerGroup; + } + + public String getTopic() { + return topic; + } + + public SubscriptionMode getSubscriptionMode() { + return subscriptionMode; + } + + public GrpcType getGrpcType() { + return grpcType; + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/GrpcType.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/GrpcType.java new file mode 100644 index 0000000000..507942a5f5 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/GrpcType.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; + +public enum GrpcType { + WEBHOOK, STREAM +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/StreamTopicConfig.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/StreamTopicConfig.java new file mode 100644 index 0000000000..b9f3d86615 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/StreamTopicConfig.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; + +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StreamTopicConfig extends ConsumerGroupTopicConfig { + private final Logger logger = LoggerFactory.getLogger(StreamTopicConfig.class); + + /** + * Key: IDC + * Value: list of emitters with Client_IP:port + */ + private final Map>> idcEmitterMap = new ConcurrentHashMap<>(); + + /** + * Key: IDC + * Value: list of emitters + */ + private Map>> idcEmitters = new ConcurrentHashMap<>(); + + private List> totalEmitters = new LinkedList<>(); + + public StreamTopicConfig(String consumerGroup, String topic, SubscriptionMode subscriptionMode) { + super(consumerGroup, topic, subscriptionMode, GrpcType.STREAM); + } + + @Override + public synchronized void registerClient(ConsumerGroupClient client) { + if (!client.getGrpcType().equals(grpcType)) { + logger.warn("Invalid grpc type: {}, expecting grpc type: {}, can not register client {}", + client.getGrpcType(), grpcType, client.toString()); + return; + } + String idc = client.getIdc(); + String clientIp = client.getIp(); + String clientPid = client.getPid(); + EventEmitter emitter = client.getEventEmitter(); + Map> emitters = idcEmitterMap.computeIfAbsent(idc, k -> new HashMap<>()); + emitters.put(clientIp + ":" + clientPid, emitter); + + idcEmitters = buildIdcEmitter(); + totalEmitters = buildTotalEmitter(); + } + + @Override + public void deregisterClient(ConsumerGroupClient client) { + String idc = client.getIdc(); + String clientIp = client.getIp(); + String clientPid = client.getPid(); + + Map> emitters = idcEmitterMap.get(idc); + if (emitters == null) { + return; + } + emitters.remove(clientIp + ":" + clientPid); + if (emitters.size() == 0) { + idcEmitterMap.remove(idc); + } + idcEmitters = buildIdcEmitter(); + totalEmitters = buildTotalEmitter(); + } + + @Override + public int getSize() { + return totalEmitters.size(); + } + + @Override + public String toString() { + return "StreamConsumeTopicConfig={consumerGroup=" + consumerGroup + + ",grpcType=" + grpcType + + ",topic=" + topic + "}"; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public String getTopic() { + return topic; + } + + public SubscriptionMode getSubscriptionMode() { + return subscriptionMode; + } + + public GrpcType getGrpcType() { + return grpcType; + } + + public Map>> getIdcEmitters() { + return idcEmitters; + } + + public List> getTotalEmitters() { + return totalEmitters; + } + + private Map>> buildIdcEmitter() { + Map>> result = new HashMap<>(); + for (Map.Entry>> entry : idcEmitterMap.entrySet()) { + List> emitterList = new LinkedList<>(entry.getValue().values()); + result.put(entry.getKey(), emitterList); + } + return result; + } + + private List> buildTotalEmitter() { + List> emitterList = new LinkedList<>(); + for (List> emitters : idcEmitters.values()) { + emitterList.addAll(emitters); + } + return emitterList; + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/WebhookTopicConfig.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/WebhookTopicConfig.java new file mode 100644 index 0000000000..018f1fee74 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/WebhookTopicConfig.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; + +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebhookTopicConfig extends ConsumerGroupTopicConfig { + private final Logger logger = LoggerFactory.getLogger(WebhookTopicConfig.class); + + /** + * PUSH URL + *

+ * Key: IDC + * Value: list of URls + */ + private final Map> idcUrls = new ConcurrentHashMap<>(); + + private List totalUrls = new LinkedList<>(); + + public WebhookTopicConfig(String consumerGroup, String topic, SubscriptionMode subscriptionMode) { + super(consumerGroup, topic, subscriptionMode, GrpcType.WEBHOOK); + } + + @Override + public synchronized void registerClient(ConsumerGroupClient client) { + if (!client.getGrpcType().equals(grpcType)) { + logger.warn("Invalid grpc type: {}, expecting grpc type: {}, can not register client {}", + client.getGrpcType(), grpcType, client.toString()); + return; + } + String idc = client.getIdc(); + String url = client.getUrl(); + List urls = idcUrls.computeIfAbsent(idc, k -> new LinkedList<>()); + if (!urls.contains(url)) { + urls.add(url); + } + totalUrls = buildTotalUrls(); + } + + @Override + public void deregisterClient(ConsumerGroupClient client) { + String idc = client.getIdc(); + String url = client.getUrl(); + + List urls = idcUrls.get(idc); + if (urls == null) { + return; + } + urls.remove(url); + if (urls.size() == 0) { + idcUrls.remove(idc); + } + totalUrls = buildTotalUrls(); + } + + @Override + public int getSize() { + return totalUrls.size(); + } + + @Override + public String toString() { + return "WebhookConsumeTopicConfig={consumerGroup=" + consumerGroup + + ",grpcType=" + grpcType + + ",topic=" + topic + + ",idcUrls=" + idcUrls + "}"; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public String getTopic() { + return topic; + } + + public SubscriptionMode getSubscriptionMode() { + return subscriptionMode; + } + + public GrpcType getGrpcType() { + return grpcType; + } + + public Map> getIdcUrls() { + return idcUrls; + } + + private List buildTotalUrls() { + Set totalUrls = new HashSet<>(); + for (List idcUrls : idcUrls.values()) { + totalUrls.addAll(idcUrls); + } + return new ArrayList<>(totalUrls); + } + + public List getTotalUrls() { + return totalUrls; + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/BatchPublishMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/BatchPublishMessageProcessor.java new file mode 100644 index 0000000000..2f2d5062d4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/BatchPublishMessageProcessor.java @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.common.BatchMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class BatchPublishMessageProcessor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final Logger aclLogger = LoggerFactory.getLogger("acl"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + public BatchPublishMessageProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(BatchMessage message, EventEmitter emitter) throws Exception { + RequestHeader requestHeader = message.getHeader(); + + if (!ServiceUtils.validateHeader(requestHeader)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateBatchMessage(message)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + try { + doAclCheck(message); + } catch (Exception e) { + aclLogger.warn("CLIENT HAS NO PERMISSION,BatchSendMessageProcessor send failed", e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + return; + } + + // control flow rate limit + if (!eventMeshGrpcServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + logger.error("Send message speed over limit."); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR, emitter); + return; + } + + String topic = message.getTopic(); + String producerGroup = message.getProducerGroup(); + + String protocolType = requestHeader.getProtocolType(); + ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + List cloudEvents = grpcCommandProtocolAdaptor.toBatchCloudEvent(new BatchMessageWrapper(message)); + + for (CloudEvent event : cloudEvents) { + String seqNum = event.getId(); + String uniqueId = event.getExtension(ProtocolKey.UNIQUE_ID).toString(); + ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); + EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); + + SendMessageContext sendMessageContext = new SendMessageContext(seqNum, event, eventMeshProducer, eventMeshGrpcServer); + + long startTime = System.currentTimeMillis(); + eventMeshProducer.send(sendMessageContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + long endTime = System.currentTimeMillis(); + logger.info("message|eventMesh2mq|REQ|BatchSend|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId); + } + + @Override + public void onException(OnExceptionContext context) { + long endTime = System.currentTimeMillis(); + logger.error("message|eventMesh2mq|REQ|BatchSend|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, context.getException()); + } + }); + } + ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, "batch publish success", emitter); + } + + private void doAclCheck(BatchMessage message) throws AclException { + RequestHeader requestHeader = message.getHeader(); + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshServerSecurityEnable) { + String remoteAdd = requestHeader.getIp(); + String user = requestHeader.getUsername(); + String pass = requestHeader.getPassword(); + String subsystem = requestHeader.getSys(); + String topic = message.getTopic(); + Acl.doAclCheckInHttpSend(remoteAdd, user, pass, subsystem, topic, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/HeartbeatProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/HeartbeatProcessor.java new file mode 100644 index 0000000000..684fcb26d6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/HeartbeatProcessor.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat; +import org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat.ClientType; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupClient; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; + +import java.util.Date; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HeartbeatProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final Logger aclLogger = LoggerFactory.getLogger("acl"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + public HeartbeatProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(Heartbeat heartbeat, EventEmitter emitter) throws Exception { + RequestHeader header = heartbeat.getHeader(); + + if (!ServiceUtils.validateHeader(header)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateHeartBeat(heartbeat)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + try { + doAclCheck(heartbeat); + } catch (AclException e) { + aclLogger.warn("CLIENT HAS NO PERMISSION, HeartbeatProcessor failed", e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + return; + } + + // only handle heartbeat for consumers + ClientType clientType = heartbeat.getClientType(); + if (!ClientType.SUB.equals(clientType)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); + + String consumerGroup = heartbeat.getConsumerGroup(); + + // update clients' timestamp in the heartbeat items + for (Heartbeat.HeartbeatItem item : heartbeat.getHeartbeatItemsList()) { + ConsumerGroupClient hbClient = ConsumerGroupClient.builder() + .env(header.getEnv()) + .idc(header.getIdc()) + .sys(header.getSys()) + .ip(header.getIp()) + .pid(header.getPid()) + .consumerGroup(consumerGroup) + .topic(item.getTopic()) + .lastUpTime(new Date()) + .build(); + consumerManager.updateClientTime(hbClient); + } + + ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, "heartbeat success", emitter); + } + + private void doAclCheck(Heartbeat heartbeat) throws AclException { + RequestHeader header = heartbeat.getHeader(); + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshServerSecurityEnable) { + String remoteAdd = header.getIp(); + String user = header.getUsername(); + String pass = header.getPassword(); + String sys = header.getSys(); + int requestCode = Integer.valueOf(RequestCode.HEARTBEAT.getRequestCode()); + for (Heartbeat.HeartbeatItem item : heartbeat.getHeartbeatItemsList()) { + Acl.doAclCheckInHttpHeartbeat(remoteAdd, user, pass, sys, item.getTopic(), requestCode); + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/ReplyMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/ReplyMessageProcessor.java new file mode 100644 index 0000000000..a9bfe05270 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/ReplyMessageProcessor.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class ReplyMessageProcessor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final Logger aclLogger = LoggerFactory.getLogger("acl"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + public ReplyMessageProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(SimpleMessage message, EventEmitter emitter) throws Exception { + RequestHeader requestHeader = message.getHeader(); + + if (!ServiceUtils.validateHeader(requestHeader)) { + ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateMessage(message)) { + ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + try { + doAclCheck(message); + } catch (Exception e) { + aclLogger.warn("CLIENT HAS NO PERMISSION,RequestReplyMessageProcessor reply failed", e); + ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + return; + } + + // control flow rate limit + if (!eventMeshGrpcServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + logger.error("Send message speed over limit."); + ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR, emitter); + return; + } + + String seqNum = message.getSeqNum(); + String uniqueId = message.getUniqueId(); + String producerGroup = message.getProducerGroup(); + + // set reply topic for ths message + String mqCluster = message.getPropertiesOrDefault(EventMeshConstants.PROPERTY_MESSAGE_CLUSTER, "defaultCluster"); + String replyTopic = mqCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC; + message = SimpleMessage.newBuilder(message).setTopic(replyTopic).build(); + + String protocolType = requestHeader.getProtocolType(); + ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new SimpleMessageWrapper(message)); + + ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); + EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); + + SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, eventMeshProducer, eventMeshGrpcServer); + + long startTime = System.currentTimeMillis(); + eventMeshProducer.reply(sendMessageContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + long endTime = System.currentTimeMillis(); + logger.info("message|mq2eventmesh|REPLY|ReplyToServer|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, replyTopic, seqNum, uniqueId); + } + + @Override + public void onException(OnExceptionContext onExceptionContext) { + ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_REPLY_MSG_ERR, + EventMeshUtil.stackTrace(onExceptionContext.getException(), 2), emitter); + long endTime = System.currentTimeMillis(); + logger.error("message|mq2eventmesh|REPLY|ReplyToServer|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, replyTopic, seqNum, uniqueId, onExceptionContext.getException()); + } + }); + } + + private void doAclCheck(SimpleMessage message) throws AclException { + RequestHeader requestHeader = message.getHeader(); + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshServerSecurityEnable) { + String remoteAdd = requestHeader.getIp(); + String user = requestHeader.getUsername(); + String pass = requestHeader.getPassword(); + String subsystem = requestHeader.getSys(); + String topic = message.getTopic(); + Acl.doAclCheckInHttpSend(remoteAdd, user, pass, subsystem, topic, RequestCode.REPLY_MESSAGE.getRequestCode()); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/RequestMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/RequestMessageProcessor.java new file mode 100644 index 0000000000..5935e2ab9d --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/RequestMessageProcessor.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class RequestMessageProcessor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final Logger aclLogger = LoggerFactory.getLogger("acl"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + public RequestMessageProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(SimpleMessage message, EventEmitter emitter) throws Exception { + RequestHeader requestHeader = message.getHeader(); + + if (!ServiceUtils.validateHeader(requestHeader)) { + ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateMessage(message)) { + ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + String seqNum = message.getSeqNum(); + String uniqueId = message.getUniqueId(); + String topic = message.getTopic(); + String producerGroup = message.getProducerGroup(); + + int ttl = Integer.parseInt(message.getTtl()); + try { + doAclCheck(message); + } catch (Exception e) { + aclLogger.warn("CLIENT HAS NO PERMISSION,RequestReplyMessageProcessor send failed", e); + ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + return; + } + + // control flow rate limit + if (!eventMeshGrpcServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + logger.error("Send message speed over limit."); + ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR, emitter); + return; + } + + String protocolType = requestHeader.getProtocolType(); + ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new SimpleMessageWrapper(message)); + + ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); + EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); + + SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, eventMeshProducer, eventMeshGrpcServer); + + long startTime = System.currentTimeMillis(); + eventMeshProducer.request(sendMessageContext, new RequestReplyCallback() { + @Override + public void onSuccess(CloudEvent event) { + try { + SimpleMessageWrapper wrapper = (SimpleMessageWrapper) grpcCommandProtocolAdaptor.fromCloudEvent(event); + + emitter.onNext(wrapper.getMessage()); + emitter.onCompleted(); + + long endTime = System.currentTimeMillis(); + logger.info("message|eventmesh2client|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId); + } catch (Exception e) { + ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, + EventMeshUtil.stackTrace(e, 2), emitter); + + long endTime = System.currentTimeMillis(); + logger.error("message|mq2eventmesh|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, e); + } + } + + @Override + public void onException(Throwable e) { + ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, + EventMeshUtil.stackTrace(e, 2), emitter); + long endTime = System.currentTimeMillis(); + logger.error("message|eventMesh2mq|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, e); + } + }, ttl); + } + + private void doAclCheck(SimpleMessage message) throws AclException { + RequestHeader requestHeader = message.getHeader(); + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshServerSecurityEnable) { + String remoteAdd = requestHeader.getIp(); + String user = requestHeader.getUsername(); + String pass = requestHeader.getPassword(); + String subsystem = requestHeader.getSys(); + String topic = message.getTopic(); + Acl.doAclCheckInHttpSend(remoteAdd, user, pass, subsystem, topic, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SendAsyncMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SendAsyncMessageProcessor.java new file mode 100644 index 0000000000..9558a37d84 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SendAsyncMessageProcessor.java @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class SendAsyncMessageProcessor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final Logger aclLogger = LoggerFactory.getLogger("acl"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + public SendAsyncMessageProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(SimpleMessage message, EventEmitter emitter) throws Exception { + RequestHeader requestHeader = message.getHeader(); + + if (!ServiceUtils.validateHeader(requestHeader)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateMessage(message)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + String seqNum = message.getSeqNum(); + String uniqueId = message.getUniqueId(); + String topic = message.getTopic(); + String producerGroup = message.getProducerGroup(); + + try { + doAclCheck(message); + } catch (Exception e) { + aclLogger.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + return; + } + + // control flow rate limit + if (!eventMeshGrpcServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + logger.error("Send message speed over limit."); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR, emitter); + return; + } + + String protocolType = requestHeader.getProtocolType(); + ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new SimpleMessageWrapper(message)); + + ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); + EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); + + SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, eventMeshProducer, eventMeshGrpcServer); + + long startTime = System.currentTimeMillis(); + eventMeshProducer.send(sendMessageContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, sendResult.toString(), emitter); + long endTime = System.currentTimeMillis(); + logger.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId); + } + + @Override + public void onException(OnExceptionContext context) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR, + EventMeshUtil.stackTrace(context.getException(), 2), emitter); + long endTime = System.currentTimeMillis(); + logger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, context.getException()); + } + }); + } + + private void doAclCheck(SimpleMessage message) throws AclException { + RequestHeader requestHeader = message.getHeader(); + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshServerSecurityEnable) { + String remoteAdd = requestHeader.getIp(); + String user = requestHeader.getUsername(); + String pass = requestHeader.getPassword(); + String subsystem = requestHeader.getSys(); + String topic = message.getTopic(); + Acl.doAclCheckInHttpSend(remoteAdd, user, pass, subsystem, topic, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SubscribeProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SubscribeProcessor.java new file mode 100644 index 0000000000..7e60cb59a6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SubscribeProcessor.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.EventMeshConsumer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupClient; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.GrpcType; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; + +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SubscribeProcessor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final Logger aclLogger = LoggerFactory.getLogger("acl"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final GrpcType grpcType = GrpcType.WEBHOOK; + + public SubscribeProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(Subscription subscription, EventEmitter emitter) throws Exception { + RequestHeader header = subscription.getHeader(); + + if (!ServiceUtils.validateHeader(header)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateSubscription(grpcType, subscription)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + try { + doAclCheck(subscription); + } catch (AclException e) { + aclLogger.warn("CLIENT HAS NO PERMISSION to Subscribe. failed", e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + return; + } + + ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); + + String consumerGroup = subscription.getConsumerGroup(); + String url = subscription.getUrl(); + List subscriptionItems = subscription.getSubscriptionItemsList(); + + // Collect new clients in the subscription + List newClients = new LinkedList<>(); + for (Subscription.SubscriptionItem item : subscriptionItems) { + ConsumerGroupClient newClient = ConsumerGroupClient.builder() + .env(header.getEnv()) + .idc(header.getIdc()) + .sys(header.getSys()) + .ip(header.getIp()) + .pid(header.getPid()) + .consumerGroup(consumerGroup) + .topic(item.getTopic()) + .grpcType(grpcType) + .subscriptionMode(item.getMode()) + .url(url) + .lastUpTime(new Date()) + .build(); + newClients.add(newClient); + } + + // register new clients into ConsumerManager + for (ConsumerGroupClient newClient : newClients) { + consumerManager.registerClient(newClient); + } + + // register new clients into EventMeshConsumer + EventMeshConsumer eventMeshConsumer = consumerManager.getEventMeshConsumer(consumerGroup); + + boolean requireRestart = false; + for (ConsumerGroupClient newClient : newClients) { + if (eventMeshConsumer.registerClient(newClient)) { + requireRestart = true; + } + } + + // restart consumer group if required + if (requireRestart) { + logger.info("ConsumerGroup {} topic info changed, restart EventMesh Consumer", consumerGroup); + consumerManager.restartEventMeshConsumer(consumerGroup); + } else { + logger.warn("EventMesh consumer [{}] didn't restart.", consumerGroup); + } + + ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, "subscribe success", emitter); + } + + private void doAclCheck(Subscription subscription) throws AclException { + RequestHeader header = subscription.getHeader(); + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshServerSecurityEnable) { + String remoteAdd = header.getIp(); + String user = header.getUsername(); + String pass = header.getPassword(); + String subsystem = header.getSys(); + for (Subscription.SubscriptionItem item : subscription.getSubscriptionItemsList()) { + Acl.doAclCheckInHttpReceive(remoteAdd, user, pass, subsystem, item.getTopic(), + RequestCode.SUBSCRIBE.getRequestCode()); + } + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SubscribeStreamProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SubscribeStreamProcessor.java new file mode 100644 index 0000000000..d742034126 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SubscribeStreamProcessor.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.EventMeshConsumer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupClient; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.GrpcType; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; + +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SubscribeStreamProcessor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final Logger aclLogger = LoggerFactory.getLogger("acl"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final GrpcType grpcType = GrpcType.STREAM; + + public SubscribeStreamProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(Subscription subscription, EventEmitter emitter) throws Exception { + + RequestHeader header = subscription.getHeader(); + + if (!ServiceUtils.validateHeader(header)) { + ServiceUtils.sendStreamRespAndDone(header, StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateSubscription(grpcType, subscription)) { + ServiceUtils.sendStreamRespAndDone(header, StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + try { + doAclCheck(subscription); + } catch (AclException e) { + aclLogger.warn("CLIENT HAS NO PERMISSION to Subscribe. failed", e); + ServiceUtils.sendStreamRespAndDone(header, StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + return; + } + + ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); + + String consumerGroup = subscription.getConsumerGroup(); + List subscriptionItems = subscription.getSubscriptionItemsList(); + + // Collect new clients in subscription + List newClients = new LinkedList<>(); + for (Subscription.SubscriptionItem item : subscriptionItems) { + ConsumerGroupClient newClient = ConsumerGroupClient.builder() + .env(header.getEnv()) + .idc(header.getIdc()) + .sys(header.getSys()) + .ip(header.getIp()) + .pid(header.getPid()) + .consumerGroup(consumerGroup) + .topic(item.getTopic()) + .subscriptionMode(item.getMode()) + .grpcType(grpcType) + .eventEmitter(emitter) + .lastUpTime(new Date()) + .build(); + newClients.add(newClient); + } + + // register new clients into ConsumerManager + for (ConsumerGroupClient newClient : newClients) { + consumerManager.registerClient(newClient); + } + + // register new clients into EventMeshConsumer + EventMeshConsumer eventMeshConsumer = consumerManager.getEventMeshConsumer(consumerGroup); + + boolean requireRestart = false; + for (ConsumerGroupClient newClient : newClients) { + if (eventMeshConsumer.registerClient(newClient)) { + requireRestart = true; + } + } + + // restart consumer group if required + if (requireRestart) { + logger.info("ConsumerGroup {} topic info changed, restart EventMesh Consumer", consumerGroup); + consumerManager.restartEventMeshConsumer(consumerGroup); + } else { + logger.warn("EventMesh consumer [{}] didn't restart.", consumerGroup); + } + + ServiceUtils.sendStreamResp(header, StatusCode.SUCCESS, "subscribe success", emitter); + } + + private void doAclCheck(Subscription subscription) throws AclException { + RequestHeader header = subscription.getHeader(); + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshServerSecurityEnable) { + String remoteAdd = header.getIp(); + String user = header.getUsername(); + String pass = header.getPassword(); + String subsystem = header.getSys(); + for (Subscription.SubscriptionItem item : subscription.getSubscriptionItemsList()) { + Acl.doAclCheckInHttpReceive(remoteAdd, user, pass, subsystem, item.getTopic(), + RequestCode.SUBSCRIBE.getRequestCode()); + } + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/UnsubscribeProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/UnsubscribeProcessor.java new file mode 100644 index 0000000000..e9276d516e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/UnsubscribeProcessor.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.EventMeshConsumer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupClient; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; + +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UnsubscribeProcessor { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + public UnsubscribeProcessor(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void process(Subscription subscription, EventEmitter emitter) throws Exception { + + RequestHeader header = subscription.getHeader(); + + if (!ServiceUtils.validateHeader(header)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + return; + } + + if (!ServiceUtils.validateSubscription(null, subscription)) { + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + return; + } + + ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); + + String consumerGroup = subscription.getConsumerGroup(); + String url = subscription.getUrl(); + List subscriptionItems = subscription.getSubscriptionItemsList(); + + // Collect clients to remove in the unsubscribe + List removeClients = new LinkedList<>(); + for (Subscription.SubscriptionItem item : subscriptionItems) { + ConsumerGroupClient newClient = ConsumerGroupClient.builder() + .env(header.getEnv()) + .idc(header.getIdc()) + .sys(header.getSys()) + .ip(header.getIp()) + .pid(header.getPid()) + .consumerGroup(consumerGroup) + .topic(item.getTopic()) + .subscriptionMode(item.getMode()) + .url(url) + .lastUpTime(new Date()) + .build(); + removeClients.add(newClient); + } + + // deregister clients from ConsumerManager + for (ConsumerGroupClient client : removeClients) { + consumerManager.deregisterClient(client); + } + + // deregister clients from EventMeshConsumer + EventMeshConsumer eventMeshConsumer = consumerManager.getEventMeshConsumer(consumerGroup); + + boolean requireRestart = false; + for (ConsumerGroupClient client : removeClients) { + if (eventMeshConsumer.deregisterClient(client)) { + requireRestart = true; + } + } + + // restart consumer group if required + if (requireRestart) { + logger.info("ConsumerGroup {} topic info changed, restart EventMesh Consumer", consumerGroup); + consumerManager.restartEventMeshConsumer(consumerGroup); + } else { + logger.warn("EventMesh consumer [{}] didn't restart.", consumerGroup); + } + + ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, "unsubscribe success", emitter); + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/EventMeshProducer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/EventMeshProducer.java new file mode 100644 index 0000000000..345576c865 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/EventMeshProducer.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.producer; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; +import org.apache.eventmesh.runtime.core.consumergroup.ProducerGroupConf; +import org.apache.eventmesh.runtime.core.plugin.MQProducerWrapper; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventMeshProducer { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private ProducerGroupConf producerGroupConfig; + + private MQProducerWrapper mqProducerWrapper; + + private ServiceState serviceState; + + public void send(SendMessageContext sendMsgContext, SendCallback sendCallback) + throws Exception { + mqProducerWrapper.send(sendMsgContext.getEvent(), sendCallback); + } + + public void request(SendMessageContext sendMsgContext, RequestReplyCallback rrCallback, long timeout) + throws Exception { + mqProducerWrapper.request(sendMsgContext.getEvent(), rrCallback, timeout); + } + + public void reply(SendMessageContext sendMessageContext, SendCallback sendCallback) throws Exception { + mqProducerWrapper.reply(sendMessageContext.getEvent(), sendCallback); + } + + public synchronized void init(EventMeshGrpcConfiguration eventMeshGrpcConfiguration, + ProducerGroupConf producerGroupConfig) throws Exception { + this.producerGroupConfig = producerGroupConfig; + + Properties keyValue = new Properties(); + keyValue.put("producerGroup", producerGroupConfig.getGroupName()); + keyValue.put("instanceName", EventMeshUtil.buildMeshClientID( + producerGroupConfig.getGroupName(), eventMeshGrpcConfiguration.eventMeshCluster)); + + //TODO for defibus + keyValue.put("eventMeshIDC", eventMeshGrpcConfiguration.eventMeshIDC); + mqProducerWrapper = new MQProducerWrapper( + eventMeshGrpcConfiguration.eventMeshConnectorPluginType); + mqProducerWrapper.init(keyValue); + serviceState = ServiceState.INITED; + logger.info("EventMeshProducer [{}] inited...........", producerGroupConfig.getGroupName()); + } + + public synchronized void start() throws Exception { + if (serviceState == null || ServiceState.RUNNING.equals(serviceState)) { + return; + } + + mqProducerWrapper.start(); + serviceState = ServiceState.RUNNING; + logger.info("EventMeshProducer [{}] started..........", producerGroupConfig.getGroupName()); + } + + public synchronized void shutdown() throws Exception { + if (serviceState == null || ServiceState.INITED.equals(serviceState)) { + return; + } + + mqProducerWrapper.shutdown(); + serviceState = ServiceState.STOPED; + logger.info("EventMeshProducer [{}] shutdown.........", producerGroupConfig.getGroupName()); + } + + public ServiceState getStatus() { + return this.serviceState; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("eventMeshProducer={").append("status=").append(serviceState.name()).append(",").append("producerGroupConfig=") + .append(producerGroupConfig).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/ProducerManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/ProducerManager.java new file mode 100644 index 0000000000..3bb566f38e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/ProducerManager.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.producer; + +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.core.consumergroup.ProducerGroupConf; + +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProducerManager { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private EventMeshGrpcServer eventMeshGrpcServer; + + private ConcurrentHashMap producerTable = new ConcurrentHashMap<>(); + + public ProducerManager(EventMeshGrpcServer eventMeshGrpcServer) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public void init() throws Exception { + logger.info("Grpc ProducerManager inited......"); + } + + public void start() throws Exception { + logger.info("Grpc ProducerManager started......"); + } + + public EventMeshProducer getEventMeshProducer(String producerGroup) throws Exception { + EventMeshProducer eventMeshProducer = null; + if (!producerTable.containsKey(producerGroup)) { + synchronized (producerTable) { + if (!producerTable.containsKey(producerGroup)) { + ProducerGroupConf producerGroupConfig = new ProducerGroupConf(producerGroup); + eventMeshProducer = createEventMeshProducer(producerGroupConfig); + eventMeshProducer.start(); + } + } + } + + eventMeshProducer = producerTable.get(producerGroup); + + if (!ServiceState.RUNNING.equals(eventMeshProducer.getStatus())) { + eventMeshProducer.start(); + } + + return eventMeshProducer; + } + + private synchronized EventMeshProducer createEventMeshProducer( + ProducerGroupConf producerGroupConfig) throws Exception { + if (producerTable.containsKey(producerGroupConfig.getGroupName())) { + return producerTable.get(producerGroupConfig.getGroupName()); + } + EventMeshProducer eventMeshProducer = new EventMeshProducer(); + eventMeshProducer.init(eventMeshGrpcServer.getEventMeshGrpcConfiguration(), + producerGroupConfig); + producerTable.put(producerGroupConfig.getGroupName(), eventMeshProducer); + return eventMeshProducer; + } + + public void shutdown() { + for (EventMeshProducer eventMeshProducer : producerTable.values()) { + try { + eventMeshProducer.shutdown(); + } catch (Exception ex) { + logger.error("shutdown eventMeshProducer[{}] err", eventMeshProducer, ex); + } + } + logger.info("producerManager shutdown......"); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/SendMessageContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/SendMessageContext.java new file mode 100644 index 0000000000..33ce346a86 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/SendMessageContext.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.producer; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.core.protocol.grpc.retry.RetryContext; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class SendMessageContext extends RetryContext { + + public static Logger logger = LoggerFactory.getLogger("retry"); + + private CloudEvent event; + + private String bizSeqNo; + + private EventMeshProducer eventMeshProducer; + + private long createTime = System.currentTimeMillis(); + + public EventMeshGrpcServer eventMeshGrpcServer; + + public SendMessageContext(String bizSeqNo, CloudEvent event, EventMeshProducer eventMeshProducer, + EventMeshGrpcServer eventMeshGrpcServer) { + this.bizSeqNo = bizSeqNo; + this.event = event; + this.eventMeshProducer = eventMeshProducer; + this.eventMeshGrpcServer = eventMeshGrpcServer; + } + + public String getBizSeqNo() { + return bizSeqNo; + } + + public void setBizSeqNo(String bizSeqNo) { + this.bizSeqNo = bizSeqNo; + } + + public CloudEvent getEvent() { + return event; + } + + public void setEvent(CloudEvent event) { + this.event = event; + } + + public EventMeshProducer getEventMeshProducer() { + return eventMeshProducer; + } + + public void setEventMeshProducer(EventMeshProducer eventMeshProducer) { + this.eventMeshProducer = eventMeshProducer; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageContext={") + .append("bizSeqNo=").append(bizSeqNo) + .append(",retryTimes=").append(retryTimes) + .append(",producer=") + .append(eventMeshProducer != null ? eventMeshProducer : null) + .append(",executeTime=") + .append(DateFormatUtils.format(executeTime, Constants.DATE_FORMAT)) + .append(",createTime=") + .append(DateFormatUtils.format(createTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public boolean retry() throws Exception { + if (eventMeshProducer == null) { + return false; + } + + if (retryTimes > 0) { //retry once + return false; + } + + retryTimes++; + eventMeshProducer.send(this, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + } + + @Override + public void onException(OnExceptionContext context) { + logger.warn("", context.getException()); + } + }); + return true; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/AbstractPushRequest.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/AbstractPushRequest.java new file mode 100644 index 0000000000..389caa1401 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/AbstractPushRequest.java @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.push; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.EventMeshConsumer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupTopicConfig; +import org.apache.eventmesh.runtime.core.protocol.grpc.retry.GrpcRetryer; +import org.apache.eventmesh.runtime.core.protocol.grpc.retry.RetryContext; + +import java.util.Collections; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +import com.google.common.collect.Sets; + +public abstract class AbstractPushRequest extends RetryContext { + + private final Logger logger = LoggerFactory.getLogger(ConsumerGroupTopicConfig.class); + + protected EventMeshGrpcServer eventMeshGrpcServer; + protected long createTime = System.currentTimeMillis(); + protected long lastPushTime = System.currentTimeMillis(); + + protected EventMeshConsumer eventMeshConsumer; + protected EventMeshGrpcConfiguration eventMeshGrpcConfiguration; + protected GrpcRetryer grpcRetryer; + + protected Map> waitingRequests; + + protected HandleMsgContext handleMsgContext; + // protected CloudEvent event; + protected SimpleMessage simpleMessage; + + private final AtomicBoolean complete = new AtomicBoolean(Boolean.FALSE); + + public AbstractPushRequest(HandleMsgContext handleMsgContext, Map> waitingRequests) { + this.eventMeshGrpcServer = handleMsgContext.getEventMeshGrpcServer(); + this.handleMsgContext = handleMsgContext; + this.waitingRequests = waitingRequests; + + this.eventMeshConsumer = handleMsgContext.getEventMeshConsumer(); + this.eventMeshGrpcConfiguration = handleMsgContext.getEventMeshGrpcServer().getEventMeshGrpcConfiguration(); + this.grpcRetryer = handleMsgContext.getEventMeshGrpcServer().getGrpcRetryer(); + CloudEvent event = handleMsgContext.getEvent(); + this.simpleMessage = getSimpleMessage(event); + } + + public abstract void tryPushRequest(); + + private SimpleMessage getSimpleMessage(CloudEvent cloudEvent) { + try { + String protocolType = Objects.requireNonNull(cloudEvent.getExtension(Constants.PROTOCOL_TYPE)).toString(); + ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + ProtocolTransportObject protocolTransportObject = protocolAdaptor.fromCloudEvent(cloudEvent); + return ((SimpleMessageWrapper) protocolTransportObject).getMessage(); + } catch (Exception e) { + logger.error("Error in getting EventMeshMessage from CloudEvent", e); + return null; + } + } + + private CloudEvent getCloudEvent(SimpleMessage simpleMessage) { + try { + String protocolType = Objects.requireNonNull(simpleMessage.getHeader().getProtocolType()); + ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + return protocolAdaptor.toCloudEvent(new SimpleMessageWrapper(simpleMessage)); + } catch (Exception e) { + logger.error("Error in getting CloudEvent from EventMeshMessage", e); + return null; + } + } + + @Override + public boolean retry() { + tryPushRequest(); + return true; + } + + protected void delayRetry() { + if (retryTimes < EventMeshConstants.DEFAULT_PUSH_RETRY_TIMES) { + retryTimes++; + delay((long) retryTimes * EventMeshConstants.DEFAULT_PUSH_RETRY_TIME_DISTANCE_IN_MILLSECONDS); + grpcRetryer.pushRetry(this); + } else { + complete(); + } + } + + protected boolean isComplete() { + return complete.get(); + } + + private void finish() { + AbstractContext context = handleMsgContext.getContext(); + SubscriptionMode subscriptionMode = handleMsgContext.getSubscriptionMode(); + CloudEvent event = getCloudEvent(simpleMessage); + if (eventMeshConsumer != null && context != null && event != null) { + try { + eventMeshConsumer.updateOffset(subscriptionMode, Collections.singletonList(event), context); + } catch (Exception e) { + logger.error("Error in updating offset in EventMeshConsumer", e); + } + } + } + + protected void complete() { + complete.compareAndSet(Boolean.FALSE, Boolean.TRUE); + finish(); + } + + protected void timeout() { + if (!isComplete() && System.currentTimeMillis() - lastPushTime >= Long.parseLong(simpleMessage.getTtl())) { + delayRetry(); + } + } + + public HandleMsgContext getHandleMsgContext() { + return handleMsgContext; + } + + protected void addToWaitingMap(WebhookPushRequest request) { + if (waitingRequests.containsKey(handleMsgContext.getConsumerGroup())) { + waitingRequests.get(handleMsgContext.getConsumerGroup()).add(request); + return; + } + waitingRequests.put(handleMsgContext.getConsumerGroup(), Sets.newConcurrentHashSet()); + waitingRequests.get(handleMsgContext.getConsumerGroup()).add(request); + } + + protected void removeWaitingMap(WebhookPushRequest request) { + if (waitingRequests.containsKey(handleMsgContext.getConsumerGroup())) { + waitingRequests.get(handleMsgContext.getConsumerGroup()).remove(request); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/HandleMsgContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/HandleMsgContext.java new file mode 100644 index 0000000000..f8bc92470c --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/HandleMsgContext.java @@ -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 org.apache.eventmesh.runtime.core.protocol.grpc.push; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.EventMeshConsumer; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.ConsumerGroupTopicConfig; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.GrpcType; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import io.cloudevents.CloudEvent; + +public class HandleMsgContext { + private final String msgRandomNo; + private final SubscriptionMode subscriptionMode; + private final EventMeshGrpcServer eventMeshGrpcServer; + private final EventMeshConsumer eventMeshConsumer; + private final ConsumerGroupTopicConfig consumeTopicConfig; + + private final GrpcType grpcType; + private final String consumerGroup; + + private final CloudEvent event; + private final AbstractContext context; + + public HandleMsgContext(String consumerGroup, CloudEvent event, SubscriptionMode subscriptionMode, GrpcType grpcType, + AbstractContext context, EventMeshGrpcServer eventMeshGrpcServer, + EventMeshConsumer eventMeshConsumer, ConsumerGroupTopicConfig consumeTopicConfig) { + this.msgRandomNo = EventMeshUtil.buildPushMsgSeqNo(); + this.consumerGroup = consumerGroup; + this.grpcType = grpcType; + this.subscriptionMode = subscriptionMode; + this.event = event; + this.context = context; + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.eventMeshConsumer = eventMeshConsumer; + this.consumeTopicConfig = consumeTopicConfig; + } + + public String getMsgRandomNo() { + return msgRandomNo; + } + + public ConsumerGroupTopicConfig getConsumeTopicConfig() { + return consumeTopicConfig; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public CloudEvent getEvent() { + return event; + } + + public AbstractContext getContext() { + return context; + } + + public EventMeshGrpcServer getEventMeshGrpcServer() { + return eventMeshGrpcServer; + } + + public EventMeshConsumer getEventMeshConsumer() { + return eventMeshConsumer; + } + + public SubscriptionMode getSubscriptionMode() { + return subscriptionMode; + } + + public GrpcType getGrpcType() { + return grpcType; + } + + + @Override + public String toString() { + return "handleMsgContext={" + + "consumerGroup=" + consumerGroup + + ",subscriptionMode=" + subscriptionMode + + ",consumeTopicConfig=" + consumeTopicConfig + + "}"; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/MessageHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/MessageHandler.java new file mode 100644 index 0000000000..5c4a271d1b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/MessageHandler.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.push; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.GrpcType; + +import org.apache.commons.collections4.MapUtils; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class MessageHandler { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final ScheduledExecutorService SCHEDULER = ThreadPoolFactory.createSingleScheduledExecutor("eventMesh-pushMsgTimeout-"); + + private final ThreadPoolExecutor pushExecutor; + + private static final Integer CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD = 10000; + + private static final Map> waitingRequests = Maps.newConcurrentMap(); + + public MessageHandler(String consumerGroup, ThreadPoolExecutor pushMsgExecutor) { + this.pushExecutor = pushMsgExecutor; + waitingRequests.put(consumerGroup, Sets.newConcurrentHashSet()); + SCHEDULER.scheduleAtFixedRate(this::checkTimeout, 0, 1000, TimeUnit.MILLISECONDS); + } + + private void checkTimeout() { + waitingRequests.forEach((key, value) -> { + for (AbstractPushRequest request : value) { + request.timeout(); + waitingRequests.get(request.getHandleMsgContext().getConsumerGroup()).remove(request); + } + }); + } + + public boolean handle(HandleMsgContext handleMsgContext) { + Set waitingRequests4Group = MapUtils.getObject(waitingRequests, + handleMsgContext.getConsumerGroup(), Sets.newConcurrentHashSet()); + if (waitingRequests4Group.size() > CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD) { + logger.warn("waitingRequests is too many, so reject, this message will be send back to MQ, consumerGroup:{}, threshold:{}", + handleMsgContext.getConsumerGroup(), CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD); + return false; + } + + try { + pushExecutor.submit(() -> { + AbstractPushRequest pushRequest = createHttpPushRequest(handleMsgContext); + pushRequest.tryPushRequest(); + }); + return true; + } catch (RejectedExecutionException e) { + return false; + } + } + + private AbstractPushRequest createHttpPushRequest(HandleMsgContext handleMsgContext) { + GrpcType grpcType = handleMsgContext.getGrpcType(); + if (GrpcType.WEBHOOK.equals(grpcType)) { + return new WebhookPushRequest(handleMsgContext, waitingRequests); + } else { + return new StreamPushRequest(handleMsgContext, waitingRequests); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/StreamPushRequest.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/StreamPushRequest.java new file mode 100644 index 0000000000..5a7989f7b5 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/StreamPushRequest.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.push; + +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.StreamTopicConfig; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.RandomUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.stub.StreamObserver; + +public class StreamPushRequest extends AbstractPushRequest { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + private final Map>> idcEmitters; + + private final List> totalEmitters; + + private final SubscriptionMode subscriptionMode; + + private final int startIdx; + + public StreamPushRequest(HandleMsgContext handleMsgContext, Map> waitingRequests) { + super(handleMsgContext, waitingRequests); + + StreamTopicConfig topicConfig = (StreamTopicConfig) handleMsgContext.getConsumeTopicConfig(); + this.idcEmitters = topicConfig.getIdcEmitters(); + this.totalEmitters = topicConfig.getTotalEmitters(); + this.subscriptionMode = topicConfig.getSubscriptionMode(); + this.startIdx = RandomUtils.nextInt(0, totalEmitters.size()); + } + + @Override + public void tryPushRequest() { + if (simpleMessage == null) { + return; + } + + List> eventEmitters = selectEmitter(); + + for (EventEmitter eventEmitter : eventEmitters) { + this.lastPushTime = System.currentTimeMillis(); + + simpleMessage = SimpleMessage.newBuilder(simpleMessage) + .putProperties(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, String.valueOf(lastPushTime)) + .build(); + try { + // catch the error and retry, don't use eventEmitter.onNext() to hide the error + StreamObserver emitter = eventEmitter.getEmitter(); + synchronized (emitter) { + emitter.onNext(simpleMessage); + } + + long cost = System.currentTimeMillis() - lastPushTime; + messageLogger.info( + "message|eventMesh2client|emitter|topic={}|bizSeqNo={}" + + "|uniqueId={}|cost={}", simpleMessage.getTopic(), + simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost); + complete(); + } catch (Throwable t) { + long cost = System.currentTimeMillis() - lastPushTime; + messageLogger.error( + "message|eventMesh2client|exception={} |emitter|topic={}|bizSeqNo={}" + + "|uniqueId={}|cost={}", t.getMessage(), simpleMessage.getTopic(), + simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost, t); + + delayRetry(); + } + } + } + + private List> selectEmitter() { + List> emitterList = MapUtils.getObject(idcEmitters, + eventMeshGrpcConfiguration.eventMeshIDC, null); + if (CollectionUtils.isNotEmpty(emitterList)) { + if (subscriptionMode.equals(SubscriptionMode.CLUSTERING)) { + return Collections.singletonList(emitterList.get((startIdx + retryTimes) % emitterList.size())); + } else if (subscriptionMode.equals(SubscriptionMode.BROADCASTING)) { + return emitterList; + } else { + messageLogger.error("Invalid Subscription Mode, no message returning back to subscriber."); + return Collections.emptyList(); + } + } + if (CollectionUtils.isNotEmpty(totalEmitters)) { + if (subscriptionMode.equals(SubscriptionMode.CLUSTERING)) { + return Collections.singletonList(totalEmitters.get((startIdx + retryTimes) % totalEmitters.size())); + } else if (subscriptionMode.equals(SubscriptionMode.BROADCASTING)) { + return totalEmitters; + } else { + messageLogger.error("Invalid Subscription Mode, no message returning back to subscriber."); + return Collections.emptyList(); + } + } + messageLogger.error("No event emitters from subscriber, no message returning."); + return Collections.emptyList(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/WebhookPushRequest.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/WebhookPushRequest.java new file mode 100644 index 0000000000..f5d6bcf0bf --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/push/WebhookPushRequest.java @@ -0,0 +1,262 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.push; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.common.protocol.http.body.message.PushMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.common.ClientRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.WebhookTopicConfig; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.RandomUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class WebhookPushRequest extends AbstractPushRequest { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + private final Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + /** + * Key: idc + * Value: list of URLs + **/ + private final Map> urls; + + private final List totalUrls; + + private final int startIdx; + + private final SubscriptionMode subscriptionMode; + + public WebhookPushRequest(HandleMsgContext handleMsgContext, + Map> waitingRequests) { + super(handleMsgContext, waitingRequests); + + WebhookTopicConfig topicConfig = (WebhookTopicConfig) handleMsgContext.getConsumeTopicConfig(); + + this.subscriptionMode = topicConfig.getSubscriptionMode(); + + this.urls = topicConfig.getIdcUrls(); + this.totalUrls = topicConfig.getTotalUrls(); + this.startIdx = RandomUtils.nextInt(0, totalUrls.size()); + } + + @Override + public void tryPushRequest() { + if (simpleMessage == null) { + return; + } + + List selectedPushUrls = getUrl(); + for (String selectedPushUrl : selectedPushUrls) { + + this.lastPushTime = System.currentTimeMillis(); + + HttpPost builder = new HttpPost(selectedPushUrl); + + String requestCode = String.valueOf(RequestCode.HTTP_PUSH_CLIENT_ASYNC.getRequestCode()); + builder.addHeader(ProtocolKey.REQUEST_CODE, requestCode); + builder.addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA); + builder.addHeader(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshGrpcConfiguration.eventMeshCluster); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, eventMeshGrpcConfiguration.eventMeshIp); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshGrpcConfiguration.eventMeshEnv); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshGrpcConfiguration.eventMeshIDC); + + RequestHeader requestHeader = simpleMessage.getHeader(); + builder.addHeader(ProtocolKey.PROTOCOL_TYPE, requestHeader.getProtocolType()); + builder.addHeader(ProtocolKey.PROTOCOL_DESC, requestHeader.getProtocolDesc()); + builder.addHeader(ProtocolKey.PROTOCOL_VERSION, requestHeader.getProtocolVersion()); + builder.addHeader(ProtocolKey.CONTENT_TYPE, simpleMessage.getPropertiesOrDefault(ProtocolKey.CONTENT_TYPE, + "application/cloudevents+json")); + + List body = new ArrayList<>(); + body.add(new BasicNameValuePair(PushMessageRequestBody.CONTENT, simpleMessage.getContent())); + body.add(new BasicNameValuePair(PushMessageRequestBody.BIZSEQNO, simpleMessage.getSeqNum())); + body.add(new BasicNameValuePair(PushMessageRequestBody.UNIQUEID, simpleMessage.getUniqueId())); + body.add(new BasicNameValuePair(PushMessageRequestBody.RANDOMNO, handleMsgContext.getMsgRandomNo())); + body.add(new BasicNameValuePair(PushMessageRequestBody.TOPIC, simpleMessage.getTopic())); + body.add(new BasicNameValuePair(PushMessageRequestBody.EXTFIELDS, + JsonUtils.serialize(simpleMessage.getPropertiesMap()))); + + simpleMessage = SimpleMessage.newBuilder(simpleMessage) + .putProperties(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, String.valueOf(lastPushTime)) + .build(); + + builder.setEntity(new UrlEncodedFormEntity(body, StandardCharsets.UTF_8)); + + //eventMeshHTTPServer.metrics.summaryMetrics.recordPushMsg(); + + addToWaitingMap(this); + + cmdLogger.info("cmd={}|eventMesh2client|from={}|to={}", requestCode, + IPUtils.getLocalAddress(), selectedPushUrl); + + try { + eventMeshGrpcServer.getHttpClient().execute(builder, handleResponse(selectedPushUrl)); + messageLogger + .info("message|eventMesh2client|url={}|topic={}|bizSeqNo={}|uniqueId={}", + selectedPushUrl, simpleMessage.getTopic(), simpleMessage.getSeqNum(), + simpleMessage.getUniqueId()); + } catch (IOException e) { + long cost = System.currentTimeMillis() - lastPushTime; + messageLogger.error( + "message|eventMesh2client|exception={} |emitter|topic={}|bizSeqNo={}" + + "|uniqueId={}|cost={}", e.getMessage(), simpleMessage.getTopic(), + simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost, e); + removeWaitingMap(this); + delayRetry(); + } + } + } + + @Override + public String toString() { + return "asyncPushRequest={" + + "bizSeqNo=" + simpleMessage.getSeqNum() + + ",startIdx=" + startIdx + + ",retryTimes=" + retryTimes + + ",uniqueId=" + simpleMessage.getUniqueId() + + ",executeTime=" + + DateFormatUtils.format(executeTime, Constants.DATE_FORMAT) + + ",lastPushTime=" + + DateFormatUtils.format(lastPushTime, Constants.DATE_FORMAT) + + ",createTime=" + + DateFormatUtils.format(createTime, Constants.DATE_FORMAT) + "}"; + } + + private ResponseHandler handleResponse(String selectedPushUrl) { + return response -> { + removeWaitingMap(WebhookPushRequest.this); + long cost = System.currentTimeMillis() - lastPushTime; + //eventMeshHTTPServer.metrics.summaryMetrics.recordHTTPPushTimeCost(cost); + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + //eventMeshHTTPServer.metrics.summaryMetrics.recordHttpPushMsgFailed(); + messageLogger.info( + "message|eventMesh2client|exception|url={}|topic={}|bizSeqNo={}" + + "|uniqueId={}|cost={}", selectedPushUrl, simpleMessage.getTopic(), + simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost); + + delayRetry(); + } else { + String res = ""; + try { + res = EntityUtils.toString(response.getEntity(), + Charset.forName(EventMeshConstants.DEFAULT_CHARSET)); + } catch (IOException e) { + complete(); + return new Object(); + } + ClientRetCode result = processResponseContent(res, selectedPushUrl); + messageLogger.info( + "message|eventMesh2client|{}|url={}|topic={}|bizSeqNo={}" + + "|uniqueId={}|cost={}", result, selectedPushUrl, simpleMessage.getTopic(), + simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost); + if (result == ClientRetCode.OK || result == ClientRetCode.FAIL) { + complete(); + } else if (result == ClientRetCode.RETRY || result == ClientRetCode.NOLISTEN) { + delayRetry(); + } + } + return new Object(); + }; + } + + private ClientRetCode processResponseContent(String content, String selectedPushUrl) { + if (StringUtils.isBlank(content)) { + return ClientRetCode.FAIL; + } + + try { + Map ret = + JsonUtils.deserialize(content, new TypeReference>() { + }); + Integer retCode = (Integer) ret.get("retCode"); + if (retCode != null && ClientRetCode.contains(retCode)) { + return ClientRetCode.get(retCode); + } + return ClientRetCode.FAIL; + } catch (Exception e) { + messageLogger.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", selectedPushUrl, + simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), content); + return ClientRetCode.FAIL; + } + } + + @SuppressWarnings("unchecked") + private List getUrl() { + List localIdcUrl = MapUtils.getObject(urls, + eventMeshGrpcConfiguration.eventMeshIDC, null); + if (CollectionUtils.isNotEmpty(localIdcUrl)) { + if (subscriptionMode.equals(SubscriptionMode.CLUSTERING)) { + return Collections.singletonList(localIdcUrl.get((startIdx + retryTimes) % localIdcUrl.size())); + } else if (subscriptionMode.equals(SubscriptionMode.BROADCASTING)) { + return localIdcUrl; + } else { + messageLogger.error("Invalid Subscription Mode, no message returning back to subscriber."); + return Collections.emptyList(); + } + } + + if (CollectionUtils.isNotEmpty(totalUrls)) { + if (subscriptionMode.equals(SubscriptionMode.CLUSTERING)) { + return Collections.singletonList(totalUrls.get((startIdx + retryTimes) % totalUrls.size())); + } else if (subscriptionMode.equals(SubscriptionMode.BROADCASTING)) { + return totalUrls; + } else { + messageLogger.error("Invalid Subscription Mode, no message returning back to subscriber."); + return Collections.emptyList(); + } + } + messageLogger.error("No event emitters from subscriber, no message returning."); + return Collections.EMPTY_LIST; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/DelayRetryable.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/DelayRetryable.java new file mode 100644 index 0000000000..9e4fbd2da5 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/DelayRetryable.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.retry; + +import java.util.concurrent.Delayed; + +/** + */ +public interface DelayRetryable extends Delayed { + boolean retry() throws Exception; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/GrpcRetryer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/GrpcRetryer.java new file mode 100644 index 0000000000..f65bfc63d2 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/GrpcRetryer.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.retry; + +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GrpcRetryer { + + private Logger retryLogger = LoggerFactory.getLogger("retry"); + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private EventMeshGrpcConfiguration grpcConfiguration; + + public GrpcRetryer(EventMeshGrpcServer eventMeshGrpcServer) { + this.grpcConfiguration = eventMeshGrpcServer.getEventMeshGrpcConfiguration(); + } + + private DelayQueue failed = new DelayQueue(); + + private ThreadPoolExecutor pool; + + private Thread dispatcher; + + public void pushRetry(DelayRetryable delayRetryable) { + if (failed.size() >= grpcConfiguration.eventMeshServerRetryBlockQueueSize) { + retryLogger.error("[RETRY-QUEUE] is full!"); + return; + } + failed.offer(delayRetryable); + } + + public void init() { + pool = new ThreadPoolExecutor(grpcConfiguration.eventMeshServerRetryThreadNum, + grpcConfiguration.eventMeshServerRetryThreadNum, + 60000, + TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<>(grpcConfiguration.eventMeshServerRetryBlockQueueSize), + new ThreadFactory() { + private AtomicInteger count = new AtomicInteger(); + + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r, "grpc-retry-" + count.incrementAndGet()); + thread.setPriority(Thread.NORM_PRIORITY); + thread.setDaemon(true); + return thread; + } + }, new ThreadPoolExecutor.AbortPolicy()); + + dispatcher = new Thread(() -> { + try { + DelayRetryable retryObj = null; + while (!Thread.currentThread().isInterrupted() + && (retryObj = failed.take()) != null) { + final DelayRetryable delayRetryable = retryObj; + pool.execute(() -> { + try { + delayRetryable.retry(); + if (retryLogger.isDebugEnabled()) { + retryLogger.debug("retryObj : {}", delayRetryable); + } + } catch (Exception e) { + retryLogger.error("grpc-retry-dispatcher error!", e); + } + }); + } + } catch (Exception e) { + retryLogger.error("grpc-retry-dispatcher error!", e); + } + }, "grpc-retry-dispatcher"); + dispatcher.setDaemon(true); + logger.info("GrpcRetryer inited......"); + } + + public int size() { + return failed.size(); + } + + public void shutdown() { + dispatcher.interrupt(); + pool.shutdown(); + logger.info("GrpcRetryer shutdown......"); + } + + public void start() throws Exception { + dispatcher.start(); + logger.info("GrpcRetryer started......"); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/RetryContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/RetryContext.java new file mode 100644 index 0000000000..c09f3b9f54 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/RetryContext.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.retry; + +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +public abstract class RetryContext implements DelayRetryable { + + public int retryTimes = 0; + + public long executeTime = System.currentTimeMillis(); + + public RetryContext delay(long delay) { + this.executeTime = System.currentTimeMillis() + delay; + return this; + } + + @Override + public int compareTo(Delayed delayed) { + RetryContext obj = (RetryContext) delayed; + if (this.executeTime > obj.executeTime) { + return 1; + } else if (this.executeTime == obj.executeTime) { + return 0; + } else { + return -1; + } + } + + @Override + public long getDelay(TimeUnit unit) { + return unit.convert(this.executeTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ConsumerService.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ConsumerService.java new file mode 100644 index 0000000000..ef13de8de0 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ConsumerService.java @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.service; + +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.ConsumerServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.ReplyMessageProcessor; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.SubscribeProcessor; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.SubscribeStreamProcessor; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.UnsubscribeProcessor; + +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.stub.StreamObserver; + +public class ConsumerService extends ConsumerServiceGrpc.ConsumerServiceImplBase { + + private final Logger logger = LoggerFactory.getLogger(ConsumerService.class); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final ThreadPoolExecutor subscribeThreadPoolExecutor; + + private final ThreadPoolExecutor replyThreadPoolExecutor; + + public ConsumerService(EventMeshGrpcServer eventMeshGrpcServer, + ThreadPoolExecutor subscribeThreadPoolExecutor, + ThreadPoolExecutor replyThreadPoolExecutor) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.subscribeThreadPoolExecutor = subscribeThreadPoolExecutor; + this.replyThreadPoolExecutor = replyThreadPoolExecutor; + } + + public void subscribe(Subscription request, StreamObserver responseObserver) { + logger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + "subscribe", EventMeshConstants.PROTOCOL_GRPC, + request.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + subscribeThreadPoolExecutor.submit(() -> { + SubscribeProcessor subscribeProcessor = new SubscribeProcessor(eventMeshGrpcServer); + try { + subscribeProcessor.process(request, emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_SUBSCRIBE_ERR.getRetCode(), + StatusCode.EVENTMESH_SUBSCRIBE_ERR.getErrMsg(), e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), emitter); + } + }); + } + + public StreamObserver subscribeStream(StreamObserver responseObserver) { + EventEmitter emitter = new EventEmitter<>(responseObserver); + + return new StreamObserver() { + @Override + public void onNext(Subscription subscription) { + if (!subscription.getSubscriptionItemsList().isEmpty()) { + logger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + "subscribeStream", EventMeshConstants.PROTOCOL_GRPC, + subscription.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + handleSubscriptionStream(subscription, emitter); + } else { + logger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + "reply-to-server", EventMeshConstants.PROTOCOL_GRPC, + subscription.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + handleSubscribeReply(subscription, emitter); + } + } + + @Override + public void onError(Throwable t) { + logger.error("Receive error from client: " + t.getMessage()); + emitter.onCompleted(); + } + + @Override + public void onCompleted() { + logger.info("Client finish sending messages"); + emitter.onCompleted(); + } + }; + } + + private void handleSubscriptionStream(Subscription request, EventEmitter emitter) { + subscribeThreadPoolExecutor.submit(() -> { + SubscribeStreamProcessor streamProcessor = new SubscribeStreamProcessor(eventMeshGrpcServer); + try { + streamProcessor.process(request, emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), e); + ServiceUtils.sendStreamRespAndDone(request.getHeader(), StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), emitter); + } + }); + } + + private void handleSubscribeReply(Subscription subscription, EventEmitter emitter) { + replyThreadPoolExecutor.submit(() -> { + ReplyMessageProcessor replyMessageProcessor = new ReplyMessageProcessor(eventMeshGrpcServer); + try { + replyMessageProcessor.process(buildSimpleMessage(subscription), emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), e); + ServiceUtils.sendStreamRespAndDone(subscription.getHeader(), StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), emitter); + } + }); + } + + private SimpleMessage buildSimpleMessage(Subscription subscription) { + Subscription.Reply reply = subscription.getReply(); + return SimpleMessage.newBuilder() + .setHeader(subscription.getHeader()) + .setProducerGroup(reply.getProducerGroup()) + .setContent(reply.getContent()) + .setUniqueId(reply.getUniqueId()) + .setSeqNum(reply.getSeqNum()) + .setTopic(reply.getTopic()) + .setTtl(reply.getTtl()) + .putAllProperties(reply.getPropertiesMap()) + .build(); + } + + public void unsubscribe(Subscription request, StreamObserver responseObserver) { + logger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + "unsubscribe", EventMeshConstants.PROTOCOL_GRPC, + request.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + subscribeThreadPoolExecutor.submit(() -> { + UnsubscribeProcessor unsubscribeProcessor = new UnsubscribeProcessor(eventMeshGrpcServer); + try { + unsubscribeProcessor.process(request, emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_UNSUBSCRIBE_ERR.getRetCode(), + StatusCode.EVENTMESH_UNSUBSCRIBE_ERR.getErrMsg(), e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_UNSUBSCRIBE_ERR, e.getMessage(), emitter); + } + }); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/EventEmitter.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/EventEmitter.java new file mode 100644 index 0000000000..36ff404d85 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/EventEmitter.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.stub.StreamObserver; + +public class EventEmitter { + private final Logger logger = LoggerFactory.getLogger(EventEmitter.class); + + private final StreamObserver emitter; + + public EventEmitter(StreamObserver emitter) { + this.emitter = emitter; + } + + public synchronized void onNext(T event) { + try { + emitter.onNext(event); + } catch (Throwable t) { + logger.warn("StreamObserver Error onNext. {}", t.getMessage()); + } + } + + public synchronized void onCompleted() { + try { + emitter.onCompleted(); + } catch (Throwable t) { + logger.warn("StreamObserver Error onCompleted. {}", t.getMessage()); + } + } + + public synchronized void onError(Throwable t) { + try { + emitter.onError(t); + } catch (Throwable t1) { + logger.warn("StreamObserver Error onError. {}", t1.getMessage()); + } + } + + public StreamObserver getEmitter() { + return emitter; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/HeartbeatService.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/HeartbeatService.java new file mode 100644 index 0000000000..94491b6c65 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/HeartbeatService.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.service; + +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat; +import org.apache.eventmesh.common.protocol.grpc.protos.HeartbeatServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.HeartbeatProcessor; + +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.stub.StreamObserver; + +public class HeartbeatService extends HeartbeatServiceGrpc.HeartbeatServiceImplBase { + + private final Logger logger = LoggerFactory.getLogger(ProducerService.class); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final ThreadPoolExecutor threadPoolExecutor; + + public HeartbeatService(EventMeshGrpcServer eventMeshGrpcServer, + ThreadPoolExecutor threadPoolExecutor) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.threadPoolExecutor = threadPoolExecutor; + } + + public void heartbeat(Heartbeat request, StreamObserver responseObserver) { + logger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + "heartbeat", EventMeshConstants.PROTOCOL_GRPC, + request.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + threadPoolExecutor.submit(() -> { + HeartbeatProcessor heartbeatProcessor = new HeartbeatProcessor(eventMeshGrpcServer); + try { + heartbeatProcessor.process(request, emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_HEARTBEAT_ERR.getRetCode(), + StatusCode.EVENTMESH_HEARTBEAT_ERR.getErrMsg(), e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_HEARTBEAT_ERR, e.getMessage(), emitter); + } + }); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ProducerService.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ProducerService.java new file mode 100644 index 0000000000..753aa254b0 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ProducerService.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.grpc.service; + +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.PublisherServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.BatchPublishMessageProcessor; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.RequestMessageProcessor; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.SendAsyncMessageProcessor; + +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.stub.StreamObserver; + +public class ProducerService extends PublisherServiceGrpc.PublisherServiceImplBase { + + private final Logger logger = LoggerFactory.getLogger(ProducerService.class); + + private final Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final ThreadPoolExecutor threadPoolExecutor; + + public ProducerService(EventMeshGrpcServer eventMeshGrpcServer, + ThreadPoolExecutor threadPoolExecutor) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.threadPoolExecutor = threadPoolExecutor; + } + + public void publish(SimpleMessage request, StreamObserver responseObserver) { + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", "AsyncPublish", + EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(), + eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + threadPoolExecutor.submit(() -> { + SendAsyncMessageProcessor sendAsyncMessageProcessor = new SendAsyncMessageProcessor(eventMeshGrpcServer); + try { + sendAsyncMessageProcessor.process(request, emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode(), + StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg(), e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR, e.getMessage(), emitter); + } + }); + } + + public void requestReply(SimpleMessage request, StreamObserver responseObserver) { + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", "RequestReply", + EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(), + eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + threadPoolExecutor.submit(() -> { + RequestMessageProcessor requestMessageProcessor = new RequestMessageProcessor(eventMeshGrpcServer); + try { + requestMessageProcessor.process(request, emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR.getRetCode(), + StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR.getErrMsg(), e); + ServiceUtils.sendStreamRespAndDone(request.getHeader(), StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, e.getMessage(), emitter); + } + }); + } + + public void batchPublish(BatchMessage request, StreamObserver responseObserver) { + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", "BatchPublish", + EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(), + eventMeshGrpcServer.getEventMeshGrpcConfiguration().eventMeshIp); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + threadPoolExecutor.submit(() -> { + BatchPublishMessageProcessor batchPublishMessageProcessor = new BatchPublishMessageProcessor(eventMeshGrpcServer); + try { + batchPublishMessageProcessor.process(request, emitter); + } catch (Exception e) { + logger.error("Error code {}, error message {}", StatusCode.EVENTMESH_BATCH_PUBLISH_ERR.getRetCode(), + StatusCode.EVENTMESH_BATCH_PUBLISH_ERR.getErrMsg(), e); + ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_BATCH_PUBLISH_ERR, e.getMessage(), emitter); + } + }); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ServiceUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ServiceUtils.java new file mode 100644 index 0000000000..163e8ecc90 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ServiceUtils.java @@ -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 org.apache.eventmesh.runtime.core.protocol.grpc.service; + +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat; +import org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat.ClientType; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.GrpcType; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +public class ServiceUtils { + + public static boolean validateHeader(RequestHeader header) { + return StringUtils.isNotEmpty(header.getIdc()) + && StringUtils.isNotEmpty(header.getEnv()) + && StringUtils.isNotEmpty(header.getIp()) + && StringUtils.isNotEmpty(header.getPid()) + && StringUtils.isNumeric(header.getPid()) + && StringUtils.isNotEmpty(header.getSys()) + && StringUtils.isNotEmpty(header.getUsername()) + && StringUtils.isNotEmpty(header.getPassword()) + && StringUtils.isNotEmpty(header.getLanguage()); + } + + public static boolean validateMessage(SimpleMessage message) { + return StringUtils.isNotEmpty(message.getUniqueId()) + && StringUtils.isNotEmpty(message.getProducerGroup()) + && StringUtils.isNotEmpty(message.getTopic()) + && StringUtils.isNotEmpty(message.getContent()) + && StringUtils.isNotEmpty(message.getTtl()); + } + + public static boolean validateBatchMessage(BatchMessage batchMessage) { + if (StringUtils.isEmpty(batchMessage.getTopic()) + || StringUtils.isEmpty(batchMessage.getProducerGroup())) { + return false; + } + for (BatchMessage.MessageItem item : batchMessage.getMessageItemList()) { + if (StringUtils.isEmpty(item.getContent()) || StringUtils.isEmpty(item.getSeqNum()) + || StringUtils.isEmpty(item.getTtl()) || StringUtils.isEmpty(item.getUniqueId())) { + return false; + } + } + return true; + } + + public static boolean validateSubscription(GrpcType grpcType, Subscription subscription) { + if (GrpcType.WEBHOOK.equals(grpcType) && StringUtils.isEmpty(subscription.getUrl())) { + return false; + } + if (CollectionUtils.isEmpty(subscription.getSubscriptionItemsList()) + || StringUtils.isEmpty(subscription.getConsumerGroup())) { + return false; + } + for (Subscription.SubscriptionItem item : subscription.getSubscriptionItemsList()) { + if (StringUtils.isEmpty(item.getTopic()) + || item.getMode() == Subscription.SubscriptionItem.SubscriptionMode.UNRECOGNIZED + || item.getType() == Subscription.SubscriptionItem.SubscriptionType.UNRECOGNIZED) { + return false; + } + } + return true; + } + + public static boolean validateHeartBeat(Heartbeat heartbeat) { + if (ClientType.SUB.equals(heartbeat.getClientType()) + && StringUtils.isEmpty(heartbeat.getConsumerGroup())) { + return false; + } + if (ClientType.PUB.equals(heartbeat.getClientType()) + && StringUtils.isEmpty(heartbeat.getProducerGroup())) { + return false; + } + for (Heartbeat.HeartbeatItem item : heartbeat.getHeartbeatItemsList()) { + if (StringUtils.isEmpty(item.getTopic())) { + return false; + } + } + return true; + } + + public static void sendRespAndDone(StatusCode code, EventEmitter emitter) { + Response response = Response.newBuilder() + .setRespCode(code.getRetCode()) + .setRespMsg(code.getErrMsg()) + .setRespTime(String.valueOf(System.currentTimeMillis())) + .build(); + emitter.onNext(response); + emitter.onCompleted(); + } + + public static void sendRespAndDone(StatusCode code, String message, EventEmitter emitter) { + Response response = Response.newBuilder() + .setRespCode(code.getRetCode()) + .setRespMsg(code.getErrMsg() + " " + message) + .setRespTime(String.valueOf(System.currentTimeMillis())) + .build(); + emitter.onNext(response); + emitter.onCompleted(); + } + + public static void sendStreamResp(RequestHeader header, StatusCode code, String message, EventEmitter emitter) { + Map resp = new HashMap<>(); + resp.put("respCode", code.getRetCode()); + resp.put("respMsg", code.getErrMsg() + " " + message); + + SimpleMessage simpleMessage = SimpleMessage.newBuilder() + .setHeader(header) + .setContent(JsonUtils.serialize(resp)) + .build(); + + emitter.onNext(simpleMessage); + } + + public static void sendStreamRespAndDone(RequestHeader header, StatusCode code, String message, EventEmitter emitter) { + sendStreamResp(header, code, message, emitter); + emitter.onCompleted(); + } + + public static void sendStreamRespAndDone(RequestHeader header, StatusCode code, EventEmitter emitter) { + Map resp = new HashMap<>(); + resp.put("respCode", code.getRetCode()); + resp.put("respMsg", code.getErrMsg()); + + SimpleMessage simpleMessage = SimpleMessage.newBuilder() + .setHeader(header) + .setContent(JsonUtils.serialize(resp)) + .build(); + + emitter.onNext(simpleMessage); + emitter.onCompleted(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/async/AsyncContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/async/AsyncContext.java new file mode 100644 index 0000000000..f78e04850a --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/async/AsyncContext.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.async; + +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadPoolExecutor; + +import com.google.common.base.Preconditions; + +public class AsyncContext { + + private T request; + + private T response; + + private volatile boolean complete = Boolean.FALSE; + + private ThreadPoolExecutor asyncContextExecutor; + + public AsyncContext(T request, T response, ThreadPoolExecutor asyncContextExecutor) { + Preconditions.checkState(request != null, "create async context err because of request is null"); + this.request = request; + this.response = response; + this.asyncContextExecutor = asyncContextExecutor; + } + + public void onComplete(final T response) { + Preconditions.checkState(Objects.nonNull(response), "response cant be null"); + this.response = response; + this.complete = Boolean.TRUE; + } + + public void onComplete(final T response, CompleteHandler handler) { + Preconditions.checkState(Objects.nonNull(response), "response cant be null"); + Preconditions.checkState(Objects.nonNull(handler), "handler cant be null"); + this.response = response; + CompletableFuture.runAsync(() -> handler.onResponse(response), asyncContextExecutor); + this.complete = Boolean.TRUE; + } + + public boolean isComplete() { + return complete; + } + + public T getRequest() { + return request; + } + + public void setRequest(T request) { + this.request = request; + } + + public T getResponse() { + return response; + } + + public void setResponse(T response) { + this.response = response; + } + + public ThreadPoolExecutor getAsyncContextExecutor() { + return asyncContextExecutor; + } + + public void setAsyncContextExecutor(ThreadPoolExecutor asyncContextExecutor) { + this.asyncContextExecutor = asyncContextExecutor; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/async/CompleteHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/async/CompleteHandler.java new file mode 100644 index 0000000000..49eeaaf585 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/async/CompleteHandler.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.async; + +/** + * CompleteHandler + * + * @param + */ +public interface CompleteHandler { + void onResponse(T t); +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/ConsumerGroupManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/ConsumerGroupManager.java new file mode 100644 index 0000000000..7d4ddab9bd --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/ConsumerGroupManager.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.consumer; + +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ConsumerGroupManager { + + protected AtomicBoolean started = new AtomicBoolean(Boolean.FALSE); + + protected AtomicBoolean inited = new AtomicBoolean(Boolean.FALSE); + + private EventMeshHTTPServer eventMeshHTTPServer; + + private EventMeshConsumer eventMeshConsumer; + + private ConsumerGroupConf consumerGroupConfig; + + public ConsumerGroupManager(EventMeshHTTPServer eventMeshHTTPServer, ConsumerGroupConf consumerGroupConfig) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + this.consumerGroupConfig = consumerGroupConfig; + eventMeshConsumer = new EventMeshConsumer(this.eventMeshHTTPServer, this.consumerGroupConfig); + } + + public synchronized void init() throws Exception { + eventMeshConsumer.init(); + inited.compareAndSet(false, true); + } + + public synchronized void start() throws Exception { + setupEventMeshConsumer(consumerGroupConfig); + eventMeshConsumer.start(); + started.compareAndSet(false, true); + } + + private synchronized void setupEventMeshConsumer(ConsumerGroupConf consumerGroupConfig) throws Exception { + for (Map.Entry conf : consumerGroupConfig.getConsumerGroupTopicConf().entrySet()) { + eventMeshConsumer.subscribe(conf.getKey(), conf.getValue().getSubscriptionItem()); + } + } + + public synchronized void shutdown() throws Exception { + eventMeshConsumer.shutdown(); + started.compareAndSet(true, false); + } + + public synchronized void refresh(ConsumerGroupConf consumerGroupConfig) throws Exception { + + if (consumerGroupConfig == null || this.consumerGroupConfig.equals(consumerGroupConfig)) { + return; + } + + if (started.get()) { + shutdown(); + } + + this.consumerGroupConfig = consumerGroupConfig; + init(); + start(); + } + + public ConsumerGroupConf getConsumerGroupConfig() { + return consumerGroupConfig; + } + + public void unsubscribe(String consumerGroup) throws Exception { + if (StringUtils.equals(consumerGroupConfig.getConsumerGroup(), consumerGroup)) { + Set topics = consumerGroupConfig.getConsumerGroupTopicConf().keySet(); + for (String topic : topics) { + ConsumerGroupTopicConf consumerGroupTopicConf = consumerGroupConfig.getConsumerGroupTopicConf().get(topic); + eventMeshConsumer.unsubscribe(topic, consumerGroupTopicConf.getSubscriptionItem().getMode()); + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/ConsumerManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/ConsumerManager.java new file mode 100644 index 0000000000..3e22d3078b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/ConsumerManager.java @@ -0,0 +1,343 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.consumer; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; +import org.apache.eventmesh.runtime.core.consumergroup.event.ConsumerGroupStateEvent; +import org.apache.eventmesh.runtime.core.consumergroup.event.ConsumerGroupTopicConfChangeEvent; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.eventbus.Subscribe; + +public class ConsumerManager { + + private EventMeshHTTPServer eventMeshHTTPServer; + + /** + * consumerGroup to ConsumerGroupManager. + */ + private ConcurrentHashMap consumerTable = + new ConcurrentHashMap<>(); + + private static final int DEFAULT_UPDATE_TIME = 3 * 30 * 1000; + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private ScheduledExecutorService scheduledExecutorService = + Executors.newSingleThreadScheduledExecutor(); + + public ConsumerManager(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + public void init() throws Exception { + eventMeshHTTPServer.getEventBus().register(this); + logger.info("consumerManager inited......"); + } + + public void start() throws Exception { + logger.info("consumerManager started......"); + + // scheduledExecutorService.scheduleAtFixedRate(() -> { + // logger.info("clientInfo check start....."); + // synchronized (eventMeshHTTPServer.localClientInfoMapping) { + // Map> clientInfoMap = + // eventMeshHTTPServer.localClientInfoMapping; + // if (clientInfoMap.size() > 0) { + // for (String key : clientInfoMap.keySet()) { + // String consumerGroup = key.split("@")[0]; + // String topic = key.split("@")[1]; + // List clientList = clientInfoMap.get(key); + // Iterator clientIterator = clientList.iterator(); + // boolean isChange = false; + // while (clientIterator.hasNext()) { + // Client client = clientIterator.next(); + // //The time difference is greater than 3 heartbeat cycles + // if (System.currentTimeMillis() - client.lastUpTime.getTime() + // > DEFAULT_UPDATE_TIME) { + // logger.warn( + // "client {} lastUpdate time {} over three heartbeat cycles", + // JsonUtils.serialize(client), client.lastUpTime); + // clientIterator.remove(); + // isChange = true; + // } + // } + // if (isChange) { + // if (clientList.size() > 0) { + // //change url + // logger.info("consumerGroup {} client info changing", + // consumerGroup); + // Map> idcUrls = new HashMap<>(); + // Set clientUrls = new HashSet<>(); + // for (Client client : clientList) { + // clientUrls.add(client.url); + // if (idcUrls.containsKey(client.idc)) { + // idcUrls.get(client.idc) + // .add(StringUtils.deleteWhitespace(client.url)); + // } else { + // List urls = new ArrayList<>(); + // urls.add(client.url); + // idcUrls.put(client.idc, urls); + // } + // } + // synchronized (eventMeshHTTPServer.localConsumerGroupMapping) { + // ConsumerGroupConf consumerGroupConf = + // eventMeshHTTPServer.localConsumerGroupMapping + // .get(consumerGroup); + // Map map = + // consumerGroupConf.getConsumerGroupTopicConf(); + // for (String topicKey : map.keySet()) { + // if (StringUtils.equals(topic, topicKey)) { + // ConsumerGroupTopicConf latestTopicConf = + // new ConsumerGroupTopicConf(); + // latestTopicConf.setConsumerGroup(consumerGroup); + // latestTopicConf.setTopic(topic); + // latestTopicConf.setSubscriptionItem( + // map.get(topicKey).getSubscriptionItem()); + // latestTopicConf.setUrls(clientUrls); + // + // latestTopicConf.setIdcUrls(idcUrls); + // + // map.put(topic, latestTopicConf); + // } + // } + // eventMeshHTTPServer.localConsumerGroupMapping + // .put(consumerGroup, consumerGroupConf); + // logger.info( + // "consumerGroup {} client info changed, " + // + "consumerGroupConf {}", consumerGroup, + // JsonUtils.serialize(consumerGroupConf)); + // + // try { + // notifyConsumerManager(consumerGroup, consumerGroupConf); + // } catch (Exception e) { + // logger.error("notifyConsumerManager error", e); + // } + // } + // + // } else { + // logger.info("consumerGroup {} client info removed", + // consumerGroup); + // //remove + // try { + // notifyConsumerManager(consumerGroup, null); + // } catch (Exception e) { + // logger.error("notifyConsumerManager error", e); + // } + // + // eventMeshHTTPServer.localConsumerGroupMapping.keySet() + // .removeIf(s -> StringUtils.equals(consumerGroup, s)); + // } + // } + // + // } + // } + // } + // }, 10000, 10000, TimeUnit.MILLISECONDS); + //TODO: update the subscription periodically from registry + } + + /** + * notify ConsumerManager groupLevel + */ + public void notifyConsumerManager(String consumerGroup, + ConsumerGroupConf latestConsumerGroupConfig) + throws Exception { + ConsumerGroupManager cgm = + eventMeshHTTPServer.getConsumerManager().getConsumer(consumerGroup); + if (latestConsumerGroupConfig == null) { + ConsumerGroupStateEvent notification = new ConsumerGroupStateEvent(); + notification.action = ConsumerGroupStateEvent.ConsumerGroupStateAction.DELETE; + notification.consumerGroup = consumerGroup; + eventMeshHTTPServer.getEventBus().post(notification); + return; + } + + if (cgm == null) { + ConsumerGroupStateEvent notification = new ConsumerGroupStateEvent(); + notification.action = ConsumerGroupStateEvent.ConsumerGroupStateAction.NEW; + notification.consumerGroup = consumerGroup; + notification.consumerGroupConfig = EventMeshUtil.cloneObject(latestConsumerGroupConfig); + eventMeshHTTPServer.getEventBus().post(notification); + return; + } + + if (!latestConsumerGroupConfig.equals(cgm.getConsumerGroupConfig())) { + ConsumerGroupStateEvent notification = new ConsumerGroupStateEvent(); + notification.action = ConsumerGroupStateEvent.ConsumerGroupStateAction.CHANGE; + notification.consumerGroup = consumerGroup; + notification.consumerGroupConfig = EventMeshUtil.cloneObject(latestConsumerGroupConfig); + eventMeshHTTPServer.getEventBus().post(notification); + return; + } + } + + public void shutdown() { + eventMeshHTTPServer.getEventBus().unregister(this); + for (ConsumerGroupManager consumerGroupManager : consumerTable.values()) { + try { + consumerGroupManager.shutdown(); + } catch (Exception ex) { + logger.error("shutdown consumerGroupManager[{}] err", consumerGroupManager, ex); + } + } + logger.info("consumerManager shutdown......"); + } + + public boolean contains(String consumerGroup) { + return consumerTable.containsKey(consumerGroup); + } + + /** + * add consumer + * + * @param consumerGroup + * @param consumerGroupConfig + * @throws Exception + */ + public synchronized void addConsumer(String consumerGroup, + ConsumerGroupConf consumerGroupConfig) throws Exception { + ConsumerGroupManager cgm = + new ConsumerGroupManager(eventMeshHTTPServer, consumerGroupConfig); + cgm.init(); + cgm.start(); + consumerTable.put(consumerGroup, cgm); + } + + /** + * restart consumer + */ + public synchronized void restartConsumer(String consumerGroup, + ConsumerGroupConf consumerGroupConfig) + throws Exception { + if (consumerTable.containsKey(consumerGroup)) { + ConsumerGroupManager cgm = consumerTable.get(consumerGroup); + cgm.refresh(consumerGroupConfig); + } + } + + /** + * get consumer + */ + public ConsumerGroupManager getConsumer(String consumerGroup) throws Exception { + ConsumerGroupManager cgm = consumerTable.get(consumerGroup); + return cgm; + } + + /** + * delete consumer + * + * @param consumerGroup + */ + public synchronized void delConsumer(String consumerGroup) throws Exception { + logger.info("start delConsumer with consumerGroup {}", consumerGroup); + if (consumerTable.containsKey(consumerGroup)) { + ConsumerGroupManager cgm = consumerTable.remove(consumerGroup); + logger.info("start unsubscribe topic with consumer group manager {}", + JsonUtils.serialize(cgm)); + cgm.unsubscribe(consumerGroup); + cgm.shutdown(); + } + logger.info("end delConsumer with consumerGroup {}", consumerGroup); + } + + @Subscribe + public void onChange(ConsumerGroupTopicConfChangeEvent event) { + try { + logger.info("onChange event:{}", event); + if (event.action + == ConsumerGroupTopicConfChangeEvent.ConsumerGroupTopicConfChangeAction.NEW) { + ConsumerGroupManager manager = getConsumer(event.consumerGroup); + if (Objects.isNull(manager)) { + return; + } + manager.getConsumerGroupConfig().getConsumerGroupTopicConf() + .put(event.topic, event.newTopicConf); + return; + } + + if (event.action + == ConsumerGroupTopicConfChangeEvent.ConsumerGroupTopicConfChangeAction.CHANGE) { + ConsumerGroupManager manager = getConsumer(event.consumerGroup); + if (Objects.isNull(manager)) { + return; + } + manager.getConsumerGroupConfig().getConsumerGroupTopicConf() + .replace(event.topic, event.newTopicConf); + return; + } + + if (event.action + == ConsumerGroupTopicConfChangeEvent.ConsumerGroupTopicConfChangeAction.DELETE) { + ConsumerGroupManager manager = getConsumer(event.consumerGroup); + if (Objects.isNull(manager)) { + return; + } + manager.getConsumerGroupConfig().getConsumerGroupTopicConf().remove(event.topic); + return; + } + } catch (Exception ex) { + logger.error("onChange event:{} err", event, ex); + } + } + + @Subscribe + public void onChange(ConsumerGroupStateEvent event) { + try { + logger.info("onChange event:{}", event); + if (event.action == ConsumerGroupStateEvent.ConsumerGroupStateAction.NEW) { + addConsumer(event.consumerGroup, event.consumerGroupConfig); + return; + } + + if (event.action == ConsumerGroupStateEvent.ConsumerGroupStateAction.CHANGE) { + restartConsumer(event.consumerGroup, event.consumerGroupConfig); + return; + } + + if (event.action == ConsumerGroupStateEvent.ConsumerGroupStateAction.DELETE) { + delConsumer(event.consumerGroup); + return; + } + } catch (Exception ex) { + logger.error("onChange event:{} err", event, ex); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/EventMeshConsumer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/EventMeshConsumer.java new file mode 100644 index 0000000000..0af8095274 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/EventMeshConsumer.java @@ -0,0 +1,327 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.api.AsyncConsumeContext; +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.EventMeshAction; +import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; +import org.apache.eventmesh.runtime.core.plugin.MQConsumerWrapper; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.core.protocol.http.push.HTTPMessageHandler; +import org.apache.eventmesh.runtime.core.protocol.http.push.MessageHandler; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.collections4.MapUtils; + +import java.util.List; +import java.util.Objects; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; + +public class EventMeshConsumer { + + private EventMeshHTTPServer eventMeshHTTPServer; + + private AtomicBoolean started4Persistent = new AtomicBoolean(Boolean.FALSE); + + private AtomicBoolean started4Broadcast = new AtomicBoolean(Boolean.FALSE); + + private AtomicBoolean inited4Persistent = new AtomicBoolean(Boolean.FALSE); + + private AtomicBoolean inited4Broadcast = new AtomicBoolean(Boolean.FALSE); + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + private ConsumerGroupConf consumerGroupConf; + + private MQConsumerWrapper persistentMqConsumer; + + private MQConsumerWrapper broadcastMqConsumer; + + public EventMeshConsumer(EventMeshHTTPServer eventMeshHTTPServer, ConsumerGroupConf consumerGroupConf) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + this.consumerGroupConf = consumerGroupConf; + this.persistentMqConsumer = new MQConsumerWrapper(eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshConnectorPluginType); + this.broadcastMqConsumer = new MQConsumerWrapper(eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshConnectorPluginType); + } + + private MessageHandler httpMessageHandler; + + public synchronized void init() throws Exception { + httpMessageHandler = new HTTPMessageHandler(this); + Properties keyValue = new Properties(); + keyValue.put("isBroadcast", "false"); + keyValue.put("consumerGroup", consumerGroupConf.getConsumerGroup()); + keyValue.put("eventMeshIDC", eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + keyValue.put("instanceName", EventMeshUtil.buildMeshClientID(consumerGroupConf.getConsumerGroup(), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster)); + persistentMqConsumer.init(keyValue); + + EventListener clusterEventListener = new EventListener() { + @Override + public void consume(CloudEvent event, AsyncConsumeContext context) { + String protocolVersion = + Objects.requireNonNull(event.getSpecVersion()).toString(); + + Span span = TraceUtils.prepareServerSpan( + EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), + EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_SERVER_SPAN, false); + try { + String topic = event.getSubject(); + String bizSeqNo = (String) event.getExtension(Constants.PROPERTY_MESSAGE_SEARCH_KEYS); + String uniqueId = (String) event.getExtension(Constants.RMB_UNIQ_ID); + + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_RECEIVE_EVENTMESH_IP, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerIp) + .build(); + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("message|mq2eventMesh|topic={}|event={}", topic, event); + } else { + messageLogger.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", topic, bizSeqNo, uniqueId); + } + + ConsumerGroupTopicConf currentTopicConfig = MapUtils.getObject(consumerGroupConf.getConsumerGroupTopicConf(), + topic, null); + EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = (EventMeshAsyncConsumeContext) context; + + if (currentTopicConfig == null) { + logger.error("no topicConfig found, consumerGroup:{} topic:{}", consumerGroupConf.getConsumerGroup(), topic); + try { + sendMessageBack(event, uniqueId, bizSeqNo); + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + return; + } catch (Exception ex) { + //ignore + } + } + + SubscriptionItem subscriptionItem = consumerGroupConf.getConsumerGroupTopicConf().get(topic).getSubscriptionItem(); + HandleMsgContext handleMsgContext = new HandleMsgContext(EventMeshUtil.buildPushMsgSeqNo(), + consumerGroupConf.getConsumerGroup(), EventMeshConsumer.this, + topic, event, subscriptionItem, eventMeshAsyncConsumeContext.getAbstractContext(), + consumerGroupConf, eventMeshHTTPServer, bizSeqNo, uniqueId, currentTopicConfig); + + if (httpMessageHandler.handle(handleMsgContext)) { + eventMeshAsyncConsumeContext.commit(EventMeshAction.ManualAck); + } else { + try { + sendMessageBack(event, uniqueId, bizSeqNo); + } catch (Exception e) { + //ignore + } + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + } + } finally { + TraceUtils.finishSpan(span, event); + } + } + }; + persistentMqConsumer.registerEventListener(clusterEventListener); + + //broacast consumer + Properties broadcastKeyValue = new Properties(); + broadcastKeyValue.put("isBroadcast", "true"); + broadcastKeyValue.put("consumerGroup", consumerGroupConf.getConsumerGroup()); + broadcastKeyValue.put("eventMeshIDC", eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + broadcastKeyValue.put("instanceName", EventMeshUtil.buildMeshClientID(consumerGroupConf.getConsumerGroup(), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster)); + broadcastMqConsumer.init(broadcastKeyValue); + + EventListener broadcastEventListener = new EventListener() { + @Override + public void consume(CloudEvent event, AsyncConsumeContext context) { + + String protocolVersion = + Objects.requireNonNull(event.getSpecVersion()).toString(); + + Span span = TraceUtils.prepareServerSpan( + EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), + EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_SERVER_SPAN, false); + try { + + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_RECEIVE_EVENTMESH_IP, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerIp) + .build(); + + String topic = event.getSubject(); + String bizSeqNo = + event.getExtension(Constants.PROPERTY_MESSAGE_SEARCH_KEYS).toString(); + String uniqueId = event.getExtension(Constants.RMB_UNIQ_ID).toString(); + + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("message|mq2eventMesh|topic={}|msg={}", topic, event); + } else { + messageLogger.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", + topic, bizSeqNo, + uniqueId); + } + + ConsumerGroupTopicConf currentTopicConfig = MapUtils.getObject( + consumerGroupConf.getConsumerGroupTopicConf(), topic, null); + EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = + (EventMeshAsyncConsumeContext) context; + + if (currentTopicConfig == null) { + logger.error("no topicConfig found, consumerGroup:{} topic:{}", + consumerGroupConf.getConsumerGroup(), topic); + try { + sendMessageBack(event, uniqueId, bizSeqNo); + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + return; + } catch (Exception ex) { + //ignore + } + } + + SubscriptionItem subscriptionItem = + consumerGroupConf.getConsumerGroupTopicConf().get(topic) + .getSubscriptionItem(); + HandleMsgContext handleMsgContext = + new HandleMsgContext(EventMeshUtil.buildPushMsgSeqNo(), + consumerGroupConf.getConsumerGroup(), EventMeshConsumer.this, + topic, event, subscriptionItem, + eventMeshAsyncConsumeContext.getAbstractContext(), + consumerGroupConf, eventMeshHTTPServer, bizSeqNo, uniqueId, + currentTopicConfig); + + if (httpMessageHandler.handle(handleMsgContext)) { + eventMeshAsyncConsumeContext.commit(EventMeshAction.ManualAck); + } else { + try { + sendMessageBack(event, uniqueId, bizSeqNo); + } catch (Exception e) { + //ignore + } + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + } + } finally { + TraceUtils.finishSpan(span, event); + } + } + }; + broadcastMqConsumer.registerEventListener(broadcastEventListener); + + inited4Persistent.compareAndSet(false, true); + inited4Broadcast.compareAndSet(false, true); + logger.info("EventMeshConsumer [{}] inited.............", consumerGroupConf.getConsumerGroup()); + } + + public synchronized void start() throws Exception { + persistentMqConsumer.start(); + started4Persistent.compareAndSet(false, true); + broadcastMqConsumer.start(); + started4Broadcast.compareAndSet(false, true); + } + + public void subscribe(String topic, SubscriptionItem subscriptionItem) throws Exception { + if (!SubscriptionMode.BROADCASTING.equals(subscriptionItem.getMode())) { + persistentMqConsumer.subscribe(topic); + } else { + broadcastMqConsumer.subscribe(topic); + } + } + + public void unsubscribe(String topic, SubscriptionMode subscriptionMode) throws Exception { + if (SubscriptionMode.BROADCASTING.equals(subscriptionMode)) { + broadcastMqConsumer.unsubscribe(topic); + } else { + persistentMqConsumer.unsubscribe(topic); + } + } + + public synchronized void shutdown() throws Exception { + persistentMqConsumer.shutdown(); + started4Persistent.compareAndSet(true, false); + broadcastMqConsumer.shutdown(); + started4Broadcast.compareAndSet(true, false); + } + + public void updateOffset(String topic, SubscriptionMode subscriptionMode, List events, + AbstractContext context) { + if (SubscriptionMode.BROADCASTING.equals(subscriptionMode)) { + broadcastMqConsumer.updateOffset(events, context); + } else { + persistentMqConsumer.updateOffset(events, context); + } + } + + public ConsumerGroupConf getConsumerGroupConf() { + return consumerGroupConf; + } + + public EventMeshHTTPServer getEventMeshHTTPServer() { + return eventMeshHTTPServer; + } + + public void sendMessageBack(final CloudEvent event, final String uniqueId, String bizSeqNo) throws Exception { + + EventMeshProducer sendMessageBack + = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(consumerGroupConf.getConsumerGroup()); + + if (sendMessageBack == null) { + logger.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", + consumerGroupConf.getConsumerGroup(), bizSeqNo, uniqueId); + return; + } + + final SendMessageContext sendMessageBackContext = new SendMessageContext(bizSeqNo, event, sendMessageBack, + eventMeshHTTPServer); + + sendMessageBack.send(sendMessageBackContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + } + + @Override + public void onException(OnExceptionContext context) { + logger.warn("consumer:{} consume fail, sendMessageBack, bizSeqno:{}, uniqueId:{}", + consumerGroupConf.getConsumerGroup(), bizSeqNo, uniqueId); + } + }); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/HandleMsgContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/HandleMsgContext.java new file mode 100644 index 0000000000..cf0ba7f642 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/HandleMsgContext.java @@ -0,0 +1,241 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.consumer; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class HandleMsgContext { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + private String msgRandomNo; + + private String consumerGroup; + + private EventMeshConsumer eventMeshConsumer; + + private String bizSeqNo; + + private String uniqueId; + + private String topic; + + private SubscriptionItem subscriptionItem; + + private CloudEvent event; + + private int ttl; + + private long createTime = System.currentTimeMillis(); + + private AbstractContext context; + + private ConsumerGroupConf consumerGroupConfig; + + private EventMeshHTTPServer eventMeshHTTPServer; + + private ConsumerGroupTopicConf consumeTopicConfig; + + private Map props; + + public HandleMsgContext(String msgRandomNo, String consumerGroup, EventMeshConsumer eventMeshConsumer, + String topic, CloudEvent event, SubscriptionItem subscriptionItem, + AbstractContext context, ConsumerGroupConf consumerGroupConfig, + EventMeshHTTPServer eventMeshHTTPServer, String bizSeqNo, String uniqueId, ConsumerGroupTopicConf consumeTopicConfig) { + this.msgRandomNo = msgRandomNo; + this.consumerGroup = consumerGroup; + this.eventMeshConsumer = eventMeshConsumer; + this.topic = topic; + this.event = event; + this.subscriptionItem = subscriptionItem; + this.context = context; + this.consumerGroupConfig = consumerGroupConfig; + this.eventMeshHTTPServer = eventMeshHTTPServer; + this.bizSeqNo = bizSeqNo; + this.uniqueId = uniqueId; + this.consumeTopicConfig = consumeTopicConfig; + + String ttlStr = (String) event.getExtension(Constants.PROPERTY_MESSAGE_TIMEOUT); + this.ttl = StringUtils.isNumeric(ttlStr) ? Integer.parseInt(ttlStr) : EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS; + } + + public void addProp(String key, String val) { + if (props == null) { + props = new HashMap<>(); + } + props.put(key, val); + } + + public String getProp(String key) { + return props.get(key); + } + + public String getMsgRandomNo() { + return msgRandomNo; + } + + public void setMsgRandomNo(String msgRandomNo) { + this.msgRandomNo = msgRandomNo; + } + + public ConsumerGroupTopicConf getConsumeTopicConfig() { + return consumeTopicConfig; + } + + public void setConsumeTopicConfig(ConsumerGroupTopicConf consumeTopicConfig) { + this.consumeTopicConfig = consumeTopicConfig; + } + + public String getBizSeqNo() { + return bizSeqNo; + } + + public void setBizSeqNo(String bizSeqNo) { + this.bizSeqNo = bizSeqNo; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public EventMeshConsumer getEventMeshConsumer() { + return eventMeshConsumer; + } + + public void setEventMeshConsumer(EventMeshConsumer eventMeshConsumer) { + this.eventMeshConsumer = eventMeshConsumer; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public CloudEvent getEvent() { + return event; + } + + public void setEvent(CloudEvent event) { + this.event = event; + } + + public SubscriptionItem getSubscriptionItem() { + return subscriptionItem; + } + + public void setSubscriptionItem(SubscriptionItem subscriptionItem) { + this.subscriptionItem = subscriptionItem; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public AbstractContext getContext() { + return context; + } + + public void setContext(AbstractContext context) { + this.context = context; + } + + public ConsumerGroupConf getConsumerGroupConfig() { + return consumerGroupConfig; + } + + public void setConsumerGroupConfig(ConsumerGroupConf consumerGroupConfig) { + this.consumerGroupConfig = consumerGroupConfig; + } + + public EventMeshHTTPServer getEventMeshHTTPServer() { + return eventMeshHTTPServer; + } + + public void finish() { + if (eventMeshConsumer != null && context != null && event != null) { + if (messageLogger.isDebugEnabled()) { + //messageLogger.debug("messageAcked|topic={}|msgId={}|cluster={}|broker={}|queueId={}|queueOffset={}", topic, + // msg.getMsgId(), msg.getProperty(DeFiBusConstant.PROPERTY_MESSAGE_CLUSTER), + // msg.getProperty(DeFiBusConstant.PROPERTY_MESSAGE_BROKER), + // msg.getQueueId(), msg.getQueueOffset()); + } + eventMeshConsumer.updateOffset(topic, subscriptionItem.getMode(), Arrays.asList(event), context); + } + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public int getTtl() { + return ttl; + } + + public void setTtl(int ttl) { + this.ttl = ttl; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("handleMsgContext={") + .append("consumerGroup=").append(consumerGroup) + .append(",topic=").append(topic) + .append(",subscriptionItem=").append(subscriptionItem) + .append(",consumeTopicConfig=").append(consumeTopicConfig) + .append(",bizSeqNo=").append(bizSeqNo) + .append(",uniqueId=").append(uniqueId) + .append(",ttl=").append(ttl) + .append(",createTime=").append(DateFormatUtils.format(createTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AdminMetricsProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AdminMetricsProcessor.java new file mode 100644 index 0000000000..b1e0688bd9 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AdminMetricsProcessor.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class AdminMetricsProcessor implements HttpRequestProcessor { + + private EventMeshHTTPServer eventMeshHTTPServer; + + public AdminMetricsProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { + } + + @Override + public boolean rejectRequest() { + return false; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AdminShutdownProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AdminShutdownProcessor.java new file mode 100644 index 0000000000..d1881ad983 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AdminShutdownProcessor.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.runtime.boot.EventMeshServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class AdminShutdownProcessor implements HttpRequestProcessor { + + public Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + private EventMeshServer eventMeshServer; + + public AdminShutdownProcessor(EventMeshServer eventMeshServer) { + this.eventMeshServer = eventMeshServer; + } + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { + + HttpCommand responseEventMeshCommand; + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + eventMeshServer.shutdown(); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(EventMeshRetCode.SUCCESS); + asyncContext.onComplete(responseEventMeshCommand); + } + + @Override + public boolean rejectRequest() { + return false; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AsyncHttpProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AsyncHttpProcessor.java new file mode 100644 index 0000000000..250415d14b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/AsyncHttpProcessor.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.runtime.core.protocol.http.processor.HandlerService.HandlerSpecific; + +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; + +/** + * async http processor + */ +public interface AsyncHttpProcessor extends HttpProcessor { + + public default HttpResponse handler(HttpRequest httpRequest) { + return null; + } + + public void handler(HandlerSpecific handlerSpecific, HttpRequest httpRequest) throws Exception; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/BatchSendMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/BatchSendMessageProcessor.java new file mode 100644 index 0000000000..13c0605f7c --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/BatchSendMessageProcessor.java @@ -0,0 +1,359 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchResponseBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.CloudEventData; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelHandlerContext; + +public class BatchSendMessageProcessor implements HttpRequestProcessor { + + public Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public BatchSendMessageProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + public Logger batchMessageLogger = LoggerFactory.getLogger("batchMessage"); + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { + + HttpCommand responseEventMeshCommand; + + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get( + Integer.valueOf(asyncContext.getRequest().getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + SendMessageBatchRequestHeader sendMessageBatchRequestHeader = + (SendMessageBatchRequestHeader) asyncContext.getRequest().getHeader(); + + SendMessageBatchResponseHeader sendMessageBatchResponseHeader = + SendMessageBatchResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + String protocolType = sendMessageBatchRequestHeader.getProtocolType(); + ProtocolAdaptor httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + List eventList = httpCommandProtocolAdaptor.toBatchCloudEvent(asyncContext.getRequest()); + + if (CollectionUtils.isEmpty(eventList)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String batchId = ""; + String producerGroup = ""; + int eventSize = eventList.size(); + + if (eventSize > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventBatchSize) { + batchMessageLogger.error("Event batch size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventBatchSize); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + "Event batch size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventBatchSize)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + for (CloudEvent event : eventList) { + //validate event + if (StringUtils.isBlank(event.getId()) + || event.getSource() == null + || event.getSpecVersion() == null + || StringUtils.isBlank(event.getType()) + || StringUtils.isBlank(event.getSubject())) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) { + batchMessageLogger.error("Event size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)).toString(); + String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)).toString(); + String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString(); + + //validate event-extension + if (StringUtils.isBlank(idc) + || StringUtils.isBlank(pid) + || !StringUtils.isNumeric(pid) + || StringUtils.isBlank(sys)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + + batchId = Objects.requireNonNull(event.getExtension(SendMessageBatchRequestBody.BATCHID)).toString(); + producerGroup = Objects.requireNonNull(event.getExtension(SendMessageBatchRequestBody.PRODUCERGROUP)).toString(); + String topic = event.getSubject(); + eventSize = Integer.parseInt(Objects.requireNonNull(event.getExtension(SendMessageBatchRequestBody.SIZE)).toString()); + CloudEventData eventData = event.getData(); + + if (eventData != null || StringUtils.isBlank(batchId) + || StringUtils.isBlank(producerGroup) + || eventSize != eventList.size()) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + } + + if (!eventMeshHTTPServer.getBatchRateLimiter() + .tryAcquire(eventSize, EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getErrMsg())); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsgDiscard(eventSize); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + EventMeshProducer batchEventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup); + + batchEventMeshProducer.getMqProducerWrapper().getMeshMQProducer().setExtFields(); + + if (!batchEventMeshProducer.getStarted().get()) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + final long batchStartTime = System.currentTimeMillis(); + + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + int requestCode = Integer.parseInt(asyncContext.getRequest().getRequestCode()); + + Map> topicBatchMessageMappings = new ConcurrentHashMap>(); + + for (CloudEvent cloudEvent : eventList) { + if (StringUtils.isBlank(cloudEvent.getSubject()) + || cloudEvent.getData() == null) { + continue; + } + + String user = Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.ClientInstanceKey.USERNAME)).toString(); + String pass = Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.ClientInstanceKey.PASSWD)).toString(); + String subsystem = Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString(); + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + try { + Acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, cloudEvent.getSubject(), requestCode); + } catch (Exception e) { + //String errorMsg = String.format("CLIENT HAS NO PERMISSION,send failed, topic:%s, subsys:%s, realIp:%s", topic, subsys, realIp); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage())); + asyncContext.onComplete(responseEventMeshCommand); + aclLogger.warn("CLIENT HAS NO PERMISSION,BatchSendMessageProcessor send failed", e); + return; + } + } + + try { + String ttl = Objects.requireNonNull(cloudEvent.getExtension(SendMessageRequestBody.TTL)).toString(); + + if (StringUtils.isBlank(ttl) || !StringUtils.isNumeric(ttl)) { + cloudEvent = CloudEventBuilder.from(cloudEvent) + .withExtension(SendMessageRequestBody.TTL, String.valueOf(EventMeshConstants.DEFAULT_MSG_TTL_MILLS)) + .withExtension("msgtype", "persistent") + .build(); + } + + if (topicBatchMessageMappings.containsKey(cloudEvent.getSubject())) { + topicBatchMessageMappings.get(cloudEvent.getSubject()).add(cloudEvent); + } else { + List tmp = new ArrayList<>(); + tmp.add(cloudEvent); + topicBatchMessageMappings.put(cloudEvent.getSubject(), tmp); + } + + if (batchMessageLogger.isDebugEnabled()) { + batchMessageLogger.debug("msg2MQMsg suc, event:{}", cloudEvent.getData()); + } + } catch (Exception e) { + batchMessageLogger.error("msg2MQMsg err, event:{}", cloudEvent.getData(), e); + } + + } + + if (CollectionUtils.isEmpty(eventList)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + long delta = eventSize; + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsg(delta); + + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerBatchMsgBatchEnabled) { + for (List eventlist : topicBatchMessageMappings.values()) { + // TODO: Implementation in API. Consider whether to put it in the plug-in. + CloudEvent event = null; + //Message omsMsg = new Message(); + //try { + // msgBatch = msgBatch.generateFromList(batchMsgs); + // for (Message message : msgBatch.getMessages()) { + // // TODO: Detect the maximum length of messages for different producers. + // Validators.checkMessage(message, batchEventMeshProducer.getMqProducerWrapper().getDefaultMQProducer()); + // MessageClientIDSetter.setUniqID(message); + // } + // msgBatch.setBody(msgBatch.encode()); + //} catch (Exception e) { + // continue; + //} + + final SendMessageContext sendMessageContext = new SendMessageContext(batchId, event, batchEventMeshProducer, + eventMeshHTTPServer); + sendMessageContext.setEventList(eventlist); + batchEventMeshProducer.send(sendMessageContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + } + + @Override + public void onException(OnExceptionContext context) { + batchMessageLogger.warn("", context.getException()); + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + } + + }); + } + } else { + for (CloudEvent event : eventList) { + final SendMessageContext sendMessageContext = new SendMessageContext(batchId, event, batchEventMeshProducer, + eventMeshHTTPServer); + batchEventMeshProducer.send(sendMessageContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + + } + + @Override + public void onException(OnExceptionContext context) { + batchMessageLogger.warn("", context.getException()); + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + } + + }); + } + } + + long batchEndTime = System.currentTimeMillis(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime); + batchMessageLogger.debug("batchMessage|eventMesh2mq|REQ|ASYNC|batchId={}|send2MQCost={}ms|msgNum={}|topics={}", + batchId, batchEndTime - batchStartTime, eventSize, topicBatchMessageMappings.keySet()); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchResponseHeader, + SendMessageBatchResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), + EventMeshRetCode.SUCCESS.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + + return; + } + + @Override + public boolean rejectRequest() { + return false; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/BatchSendMessageV2Processor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/BatchSendMessageV2Processor.java new file mode 100644 index 0000000000..2b23d786b6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/BatchSendMessageV2Processor.java @@ -0,0 +1,317 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchV2RequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageBatchV2ResponseBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchV2RequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchV2ResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelHandlerContext; + +public class BatchSendMessageV2Processor implements HttpRequestProcessor { + + public Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public BatchSendMessageV2Processor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + public Logger batchMessageLogger = LoggerFactory.getLogger("batchMessage"); + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) + throws Exception { + + HttpCommand responseEventMeshCommand; + final HttpCommand request = asyncContext.getRequest(); + final Integer requestCode = Integer.valueOf(request.getRequestCode()); + + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + RequestCode.get(requestCode), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + SendMessageBatchV2RequestHeader sendMessageBatchV2RequestHeader = + (SendMessageBatchV2RequestHeader) asyncContext.getRequest().getHeader(); + + String protocolType = sendMessageBatchV2RequestHeader.getProtocolType(); + ProtocolAdaptor httpCommandProtocolAdaptor = + ProtocolPluginFactory.getProtocolAdaptor(protocolType); + CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest()); + + SendMessageBatchV2ResponseHeader sendMessageBatchV2ResponseHeader = + SendMessageBatchV2ResponseHeader.buildHeader( + requestCode, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC + ); + + // todo: use validate processor to check + //validate event + if (StringUtils.isBlank(event.getId()) + || event.getSource() == null + || event.getSpecVersion() == null + || StringUtils.isBlank(event.getType()) + || StringUtils.isBlank(event.getSubject())) { + responseEventMeshCommand = request.createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)) + .toString(); + String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)) + .toString(); + String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)) + .toString(); + + //validate event-extension + if (StringUtils.isBlank(idc) + || StringUtils.isBlank(pid) + || !StringUtils.isNumeric(pid) + || StringUtils.isBlank(sys)) { + responseEventMeshCommand = request.createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String bizNo = + Objects.requireNonNull(event.getExtension(SendMessageBatchV2RequestBody.BIZSEQNO)) + .toString(); + String producerGroup = + Objects.requireNonNull(event.getExtension(SendMessageBatchV2RequestBody.PRODUCERGROUP)) + .toString(); + String topic = event.getSubject(); + + if (StringUtils.isBlank(bizNo) + || StringUtils.isBlank(topic) + || StringUtils.isBlank(producerGroup) + || event.getData() == null) { + responseEventMeshCommand = request.createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) { + batchMessageLogger.error("Event size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = event.getExtension(ProtocolKey.ClientInstanceKey.USERNAME).toString(); + String pass = event.getExtension(ProtocolKey.ClientInstanceKey.PASSWD).toString(); + String subsystem = event.getExtension(ProtocolKey.ClientInstanceKey.SYS).toString(); + try { + Acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, topic, requestCode); + } catch (Exception e) { + //String errorMsg = String.format("CLIENT HAS NO PERMISSION,send failed, topic:%s, subsys:%s, realIp:%s", topic, subsys, realIp); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), + e.getMessage())); + asyncContext.onComplete(responseEventMeshCommand); + aclLogger + .warn("CLIENT HAS NO PERMISSION,BatchSendMessageV2Processor send failed", e); + return; + } + } + + if (!eventMeshHTTPServer.getBatchRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, + TimeUnit.MILLISECONDS)) { + responseEventMeshCommand = request.createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getErrMsg())); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsgDiscard(1); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + EventMeshProducer batchEventMeshProducer = + eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup); + batchEventMeshProducer.getMqProducerWrapper().getMeshMQProducer().setExtFields(); + if (!batchEventMeshProducer.getStarted().get()) { + responseEventMeshCommand = request.createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + long batchStartTime = System.currentTimeMillis(); + + String ttl = String.valueOf(EventMeshConstants.DEFAULT_MSG_TTL_MILLS); + // todo: use hashmap to avoid copy + if (StringUtils.isBlank(event.getExtension(SendMessageRequestBody.TTL).toString()) + && !StringUtils.isNumeric(event.getExtension(SendMessageRequestBody.TTL).toString())) { + event = CloudEventBuilder.from(event).withExtension(SendMessageRequestBody.TTL, ttl) + .build(); + } + + + try { + event = CloudEventBuilder.from(event) + .withExtension("msgtype", "persistent") + .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .build(); + if (batchMessageLogger.isDebugEnabled()) { + batchMessageLogger.debug("msg2MQMsg suc, topic:{}, msg:{}", topic, event.getData()); + } + + } catch (Exception e) { + batchMessageLogger.error("msg2MQMsg err, topic:{}, msg:{}", topic, event.getData(), e); + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + + + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsg(1); + + final SendMessageContext sendMessageContext = + new SendMessageContext(bizNo, event, batchEventMeshProducer, eventMeshHTTPServer); + + try { + batchEventMeshProducer.send(sendMessageContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + long batchEndTime = System.currentTimeMillis(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime); + batchMessageLogger.debug( + "batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", + bizNo, batchEndTime - batchStartTime, topic); + } + + @Override + public void onException(OnExceptionContext context) { + long batchEndTime = System.currentTimeMillis(); + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime); + batchMessageLogger.error( + "batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", + bizNo, batchEndTime - batchStartTime, topic, context.getException()); + } + + }); + } catch (Exception e) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_SEND_BATCHLOG_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_SEND_BATCHLOG_MSG_ERR.getErrMsg() + + + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(responseEventMeshCommand); + long batchEndTime = System.currentTimeMillis(); + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime); + batchMessageLogger.error( + "batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", + bizNo, batchEndTime - batchStartTime, topic, e); + } + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageBatchV2ResponseHeader, + SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), + EventMeshRetCode.SUCCESS.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + + } + + @Override + public boolean rejectRequest() { + return false; + } +} + diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HandlerService.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HandlerService.java new file mode 100644 index 0000000000..12377241b4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HandlerService.java @@ -0,0 +1,365 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.boot.HTTPTrace; +import org.apache.eventmesh.runtime.boot.HTTPTrace.TraceOperation; +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.metrics.http.HTTPMetricsServer; +import org.apache.eventmesh.runtime.util.HttpResponseUtils; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.entity.ContentType; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.QueryStringDecoder; +import io.netty.handler.codec.http.multipart.Attribute; +import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory; +import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import io.netty.util.ReferenceCountUtil; + +import com.fasterxml.jackson.core.type.TypeReference; + +import lombok.Getter; +import lombok.Setter; + +public class HandlerService { + + private Logger httpServerLogger = LoggerFactory.getLogger(this.getClass()); + + private Logger httpLogger = LoggerFactory.getLogger("http"); + + private Map httpProcessorMap = new ConcurrentHashMap<>(); + + @Setter + private HTTPMetricsServer metrics; + + @Setter + private HTTPTrace httpTrace; + + public DefaultHttpDataFactory defaultHttpDataFactory = new DefaultHttpDataFactory(false); + + + public void init() { + httpServerLogger.info("HandlerService start "); + } + + public void register(HttpProcessor httpProcessor, ThreadPoolExecutor threadPoolExecutor) { + for (String path : httpProcessor.paths()) { + this.register(path, httpProcessor, threadPoolExecutor); + } + } + + public void register(String path, HttpProcessor httpProcessor, ThreadPoolExecutor threadPoolExecutor) { + + if (httpProcessorMap.containsKey(path)) { + throw new RuntimeException(String.format("HandlerService path %s repeat, repeat processor is %s ", + path, httpProcessor.getClass().getSimpleName())); + } + ProcessorWrapper processorWrapper = new ProcessorWrapper(); + processorWrapper.threadPoolExecutor = threadPoolExecutor; + if (httpProcessor instanceof AsyncHttpProcessor) { + processorWrapper.async = (AsyncHttpProcessor) httpProcessor; + } + processorWrapper.httpProcessor = httpProcessor; + processorWrapper.traceEnabled = httpProcessor.getClass().getAnnotation(EventMeshTrace.class).isEnable(); + httpProcessorMap.put(path, processorWrapper); + httpServerLogger.info("path is {} processor name is {}", path, httpProcessor.getClass().getSimpleName()); + } + + public boolean isProcessorWrapper(HttpRequest httpRequest) { + return Objects.nonNull(this.getProcessorWrapper(httpRequest)); + } + + private ProcessorWrapper getProcessorWrapper(HttpRequest httpRequest) { + String uri = httpRequest.uri(); + for (Entry e : httpProcessorMap.entrySet()) { + if (uri.startsWith(e.getKey())) { + return e.getValue(); + } + } + return null; + } + + /** + * @param httpRequest + */ + public void handler(ChannelHandlerContext ctx, HttpRequest httpRequest, ThreadPoolExecutor asyncContextCompleteHandler) { + + ProcessorWrapper processorWrapper = getProcessorWrapper(httpRequest); + if (Objects.isNull(processorWrapper)) { + this.sendResponse(ctx, httpRequest, HttpResponseUtils.createNotFound()); + return; + } + TraceOperation traceOperation = httpTrace.getTraceOperation(httpRequest, ctx.channel(), processorWrapper.traceEnabled); + try { + HandlerSpecific handlerSpecific = new HandlerSpecific(); + handlerSpecific.request = httpRequest; + handlerSpecific.ctx = ctx; + handlerSpecific.traceOperation = traceOperation; + handlerSpecific.asyncContext = new AsyncContext<>(new HttpEventWrapper(), null, asyncContextCompleteHandler); + processorWrapper.threadPoolExecutor.execute(handlerSpecific); + } catch (Exception e) { + httpServerLogger.error(e.getMessage(), e); + this.sendResponse(ctx, httpRequest, HttpResponseUtils.createInternalServerError()); + } + } + + private void sendResponse(ChannelHandlerContext ctx, HttpRequest request, HttpResponse response) { + this.sendResponse(ctx, request, response, true); + } + + private void sendResponse(ChannelHandlerContext ctx, HttpRequest httpRequest, HttpResponse response, boolean isClose) { + ReferenceCountUtil.release(httpRequest); + ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> { + if (!f.isSuccess()) { + httpLogger.warn("send response to [{}] fail, will close this channel", + RemotingHelper.parseChannelRemoteAddr(f.channel())); + if (isClose) { + f.channel().close(); + } + } + }); + } + + private HttpEventWrapper parseHttpRequest(HttpRequest httpRequest) throws IOException { + HttpEventWrapper httpEventWrapper = new HttpEventWrapper(); + httpEventWrapper.setHttpMethod(httpRequest.method().name()); + httpEventWrapper.setHttpVersion(httpRequest.protocolVersion().protocolName()); + httpEventWrapper.setRequestURI(httpRequest.uri()); + + //parse http header + for (String key : httpRequest.headers().names()) { + httpEventWrapper.getHeaderMap().put(key, httpRequest.headers().get(key)); + } + + final long bodyDecodeStart = System.currentTimeMillis(); + //parse http body + FullHttpRequest fullHttpRequest = (FullHttpRequest) httpRequest; + final Map bodyMap = new HashMap<>(); + if (HttpMethod.GET == fullHttpRequest.method()) { + QueryStringDecoder getDecoder = new QueryStringDecoder(fullHttpRequest.uri()); + getDecoder.parameters().forEach((key, value) -> bodyMap.put(key, value.get(0))); + } else if (HttpMethod.POST == fullHttpRequest.method()) { + + if (StringUtils.contains(httpRequest.headers().get("Content-Type"), ContentType.APPLICATION_JSON.getMimeType())) { + int length = fullHttpRequest.content().readableBytes(); + if (length > 0) { + byte[] body = new byte[length]; + fullHttpRequest.content().readBytes(body); + JsonUtils.deserialize(new String(body), new TypeReference>() { + }).forEach(bodyMap::put); + } + } else { + HttpPostRequestDecoder decoder = + new HttpPostRequestDecoder(defaultHttpDataFactory, httpRequest); + for (InterfaceHttpData parm : decoder.getBodyHttpDatas()) { + if (parm.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) { + Attribute data = (Attribute) parm; + bodyMap.put(data.getName(), data.getValue()); + } + } + decoder.destroy(); + } + + } else { + throw new RuntimeException("UnSupported Method " + fullHttpRequest.method()); + } + + byte[] requestBody = JsonUtils.serialize(bodyMap).getBytes(StandardCharsets.UTF_8); + httpEventWrapper.setBody(requestBody); + + metrics.getSummaryMetrics().recordDecodeTimeCost(System.currentTimeMillis() - bodyDecodeStart); + + return httpEventWrapper; + } + + @Getter + @Setter + class HandlerSpecific implements Runnable { + + private TraceOperation traceOperation; + + private ChannelHandlerContext ctx; + + private HttpRequest request; + + private HttpResponse response; + + private AsyncContext asyncContext; + + private Throwable exception; + + long requestTime = System.currentTimeMillis(); + + private Map traceMap; + + private CloudEvent ce; + + + public void run() { + String processorKey = "/"; + for (String eventProcessorKey : httpProcessorMap.keySet()) { + if (request.uri().startsWith(eventProcessorKey)) { + processorKey = eventProcessorKey; + break; + } + } + ProcessorWrapper processorWrapper = HandlerService.this.httpProcessorMap.get(processorKey); + try { + this.preHandler(); + if (processorWrapper.httpProcessor instanceof AsyncHttpProcessor) { + // set actual async request + HttpEventWrapper httpEventWrapper = parseHttpRequest(request); + this.asyncContext.setRequest(httpEventWrapper); + processorWrapper.async.handler(this, request); + return; + } + response = processorWrapper.httpProcessor.handler(request); + + this.postHandler(); + } catch (Throwable e) { + exception = e; + // todo: according exception to generate response + this.response = HttpResponseUtils.createInternalServerError(); + this.error(); + } + } + + private void postHandler() { + metrics.getSummaryMetrics().recordHTTPRequest(); + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", request); + } + if (Objects.isNull(response)) { + this.response = HttpResponseUtils.createSuccess(); + } + this.traceOperation.endTrace(ce); + HandlerService.this.sendResponse(ctx, this.request, this.response); + } + + private void preHandler() { + metrics.getSummaryMetrics().recordHTTPReqResTimeCost(System.currentTimeMillis() - requestTime); + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", response); + } + } + + private void error() { + httpServerLogger.error(this.exception.getMessage(), this.exception); + this.traceOperation.exceptionTrace(this.exception, this.traceMap); + metrics.getSummaryMetrics().recordHTTPDiscard(); + metrics.getSummaryMetrics().recordHTTPReqResTimeCost(System.currentTimeMillis() - requestTime); + HandlerService.this.sendResponse(ctx, this.request, this.response); + } + + + public void setResponseJsonBody(String body) { + this.sendResponse(HttpResponseUtils.setResponseJsonBody(body, ctx)); + } + + public void setResponseTextBody(String body) { + this.sendResponse(HttpResponseUtils.setResponseTextBody(body, ctx)); + } + + public void sendResponse(HttpResponse response) { + this.response = response; + this.postHandler(); + } + + public void sendResponse(Map responseHeaderMap, Map responseBodyMap) { + try { + HttpEventWrapper responseWrapper = asyncContext.getRequest().createHttpResponse(responseHeaderMap, responseBodyMap); + asyncContext.onComplete(responseWrapper); + this.response = asyncContext.getResponse().httpResponse(); + this.postHandler(); + } catch (Exception e) { + this.exception = e; + // todo: according exception to generate response + this.response = HttpResponseUtils.createInternalServerError(); + this.error(); + } + + } + + // for error response + public void sendErrorResponse(EventMeshRetCode retCode, Map responseHeaderMap, Map responseBodyMap, + Map traceMap) { + this.traceMap = traceMap; + try { + responseBodyMap.put("retCode", retCode.getRetCode()); + responseBodyMap.put("retMsg", retCode.getErrMsg()); + HttpEventWrapper responseWrapper = asyncContext.getRequest().createHttpResponse(responseHeaderMap, responseBodyMap); + asyncContext.onComplete(responseWrapper); + this.exception = new RuntimeException(retCode.getErrMsg()); + this.response = asyncContext.getResponse().httpResponse(); + this.error(); + } catch (Exception e) { + this.exception = e; + // todo: according exception to generate response + this.response = HttpResponseUtils.createInternalServerError(); + this.error(); + } + } + + /** + * @param count + */ + public void recordSendBatchMsgFailed(int count) { + metrics.getSummaryMetrics().recordSendBatchMsgFailed(1); + } + + } + + + private static class ProcessorWrapper { + + private ThreadPoolExecutor threadPoolExecutor; + + private HttpProcessor httpProcessor; + + private AsyncHttpProcessor async; + + private boolean traceEnabled; + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HeartBeatProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HeartBeatProcessor.java new file mode 100644 index 0000000000..cd0b8c463b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HeartBeatProcessor.java @@ -0,0 +1,239 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.client.HeartbeatRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.HeartbeatResponseBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.client.HeartbeatRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.client.HeartbeatResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class HeartBeatProcessor implements HttpRequestProcessor { + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public HeartBeatProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { + HttpCommand responseEventMeshCommand; + httpLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + HeartbeatRequestHeader heartbeatRequestHeader = (HeartbeatRequestHeader) asyncContext.getRequest().getHeader(); + HeartbeatRequestBody heartbeatRequestBody = (HeartbeatRequestBody) asyncContext.getRequest().getBody(); + + HeartbeatResponseHeader heartbeatResponseHeader = + HeartbeatResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + + //validate header + if (StringUtils.isBlank(heartbeatRequestHeader.getIdc()) + || StringUtils.isBlank(heartbeatRequestHeader.getPid()) + || !StringUtils.isNumeric(heartbeatRequestHeader.getPid()) + || StringUtils.isBlank(heartbeatRequestHeader.getSys())) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + heartbeatResponseHeader, + HeartbeatResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + //validate body + if (StringUtils.isBlank(heartbeatRequestBody.getClientType()) + || StringUtils.isBlank(heartbeatRequestBody.getConsumerGroup()) + || CollectionUtils.isEmpty(heartbeatRequestBody.getHeartbeatEntities())) { + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + heartbeatResponseHeader, + HeartbeatResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + ConcurrentHashMap> tmp = new ConcurrentHashMap<>(); + String env = heartbeatRequestHeader.getEnv(); + String idc = heartbeatRequestHeader.getIdc(); + String sys = heartbeatRequestHeader.getSys(); + String ip = heartbeatRequestHeader.getIp(); + String pid = heartbeatRequestHeader.getPid(); + String consumerGroup = heartbeatRequestBody.getConsumerGroup(); + List heartbeatEntities = heartbeatRequestBody.getHeartbeatEntities(); + for (HeartbeatRequestBody.HeartbeatEntity heartbeatEntity : heartbeatEntities) { + + Client client = new Client(); + client.env = env; + client.idc = idc; + client.sys = sys; + client.ip = ip; + client.pid = pid; + client.consumerGroup = consumerGroup; + client.topic = heartbeatEntity.topic; + client.url = heartbeatEntity.url; + + client.lastUpTime = new Date(); + + if (StringUtils.isBlank(client.topic)) { + continue; + } + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = heartbeatRequestHeader.getUsername(); + String pass = heartbeatRequestHeader.getPasswd(); + int requestCode = Integer.parseInt(heartbeatRequestHeader.getCode()); + try { + Acl.doAclCheckInHttpHeartbeat(remoteAddr, user, pass, sys, client.topic, requestCode); + } catch (Exception e) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + heartbeatResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage())); + asyncContext.onComplete(responseEventMeshCommand); + aclLogger.warn("CLIENT HAS NO PERMISSION,HeartBeatProcessor subscribe failed", e); + return; + } + } + + if (StringUtils.isBlank(client.url)) { + continue; + } + + String groupTopicKey = client.consumerGroup + "@" + client.topic; + + if (tmp.containsKey(groupTopicKey)) { + tmp.get(groupTopicKey).add(client); + } else { + List clients = new ArrayList<>(); + clients.add(client); + tmp.put(groupTopicKey, clients); + } + } + synchronized (eventMeshHTTPServer.localClientInfoMapping) { + for (Map.Entry> groupTopicClientMapping : tmp.entrySet()) { + List localClientList = + eventMeshHTTPServer.localClientInfoMapping.get(groupTopicClientMapping.getKey()); + if (CollectionUtils.isEmpty(localClientList)) { + eventMeshHTTPServer.localClientInfoMapping + .put(groupTopicClientMapping.getKey(), groupTopicClientMapping.getValue()); + } else { + List tmpClientList = groupTopicClientMapping.getValue(); + supplyClientInfoList(tmpClientList, localClientList); + eventMeshHTTPServer.localClientInfoMapping.put(groupTopicClientMapping.getKey(), localClientList); + } + + } + } + + long startTime = System.currentTimeMillis(); + try { + + final CompleteHandler handler = new CompleteHandler() { + @Override + public void onResponse(HttpCommand httpCommand) { + try { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", httpCommand); + } + eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - asyncContext.getRequest().getReqTime()); + } catch (Exception ex) { + //ignore + } + } + }; + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(EventMeshRetCode.SUCCESS); + asyncContext.onComplete(responseEventMeshCommand, handler); + } catch (Exception e) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + heartbeatResponseHeader, + HeartbeatResponseBody.buildBody(EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(err); + long endTime = System.currentTimeMillis(); + httpLogger.error("message|eventMesh2mq|REQ|ASYNC|heartBeatMessageCost={}ms", + endTime - startTime, e); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime); + } + + } + + private void supplyClientInfoList(List tmpClientList, List localClientList) { + for (Client tmpClient : tmpClientList) { + boolean isContains = false; + for (Client localClient : localClientList) { + if (StringUtils.equals(localClient.url, tmpClient.url)) { + isContains = true; + localClient.lastUpTime = tmpClient.lastUpTime; + break; + } + } + if (!isContains) { + localClientList.add(tmpClient); + } + } + } + + @Override + public boolean rejectRequest() { + return false; + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HttpProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HttpProcessor.java new file mode 100644 index 0000000000..34b0d330c7 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/HttpProcessor.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; + +/** + * http processor + */ +public interface HttpProcessor { + + public String[] paths(); + + public HttpResponse handler(HttpRequest httpRequest); +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/LocalSubscribeEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/LocalSubscribeEventProcessor.java new file mode 100644 index 0000000000..4c1810f282 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/LocalSubscribeEventProcessor.java @@ -0,0 +1,326 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.AbstractEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.WebhookUtil; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.HttpRequest; + +import com.fasterxml.jackson.core.type.TypeReference; + + +@EventMeshTrace(isEnable = false) +public class LocalSubscribeEventProcessor extends AbstractEventProcessor implements AsyncHttpProcessor { + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + public LocalSubscribeEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + super(eventMeshHTTPServer); + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) throws Exception { + + AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + + ChannelHandlerContext ctx = handlerSpecific.getCtx(); + + HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), + EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress() + ); + + // user request header + Map userRequestHeaderMap = requestWrapper.getHeaderMap(); + String requestIp = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, requestIp); + + // build sys header + requestWrapper.buildSysHeaderForClient(); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, + IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + Map sysHeaderMap = requestWrapper.getSysHeaderMap(); + + Map responseBodyMap = new HashMap<>(); + + //validate header + if (StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || !StringUtils.isNumeric(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString())) { + + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + //validate body + byte[] requestBody = requestWrapper.getBody(); + + Map requestBodyMap = JsonUtils.deserialize(new String(requestBody), new TypeReference>() { + }); + + if (requestBodyMap.get("url") == null || requestBodyMap.get("topic") == null || requestBodyMap.get("consumerGroup") == null) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + String url = requestBodyMap.get("url").toString(); + String consumerGroup = requestBodyMap.get("consumerGroup").toString(); + String topic = JsonUtils.serialize(requestBodyMap.get("topic")); + + // SubscriptionItem + List subscriptionList = JsonUtils.deserialize(topic, new TypeReference>() { + }); + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.USERNAME).toString(); + String pass = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PASSWD).toString(); + String subsystem = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString(); + for (SubscriptionItem item : subscriptionList) { + try { + Acl.doAclCheckInHttpReceive(remoteAddr, user, pass, subsystem, item.getTopic(), + requestWrapper.getRequestURI()); + } catch (Exception e) { + aclLogger.warn("CLIENT HAS NO PERMISSION,SubscribeProcessor subscribe failed", e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_ACL_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + } + } + + // validate URL + try { + if (!IPUtils.isValidDomainOrIp(url, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIpv4BlackList, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIpv6BlackList)) { + httpLogger.error("subscriber url {} is not valid", url); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + } catch (Exception e) { + httpLogger.error("subscriber url {} is not valid, error {}", url, e.getMessage()); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + // obtain webhook delivery agreement for Abuse Protection + boolean isWebhookAllowed = WebhookUtil.obtainDeliveryAgreement(eventMeshHTTPServer.httpClientPool.getClient(), + url, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshWebhookOrigin); + + if (!isWebhookAllowed) { + httpLogger.error("subscriber url {} is not allowed by the target system", url); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + synchronized (eventMeshHTTPServer.localClientInfoMapping) { + + registerClient(requestWrapper, consumerGroup, subscriptionList, url); + + for (SubscriptionItem subTopic : subscriptionList) { + List groupTopicClients = eventMeshHTTPServer.localClientInfoMapping + .get(consumerGroup + "@" + subTopic.getTopic()); + + if (CollectionUtils.isEmpty(groupTopicClients)) { + httpLogger.error("group {} topic {} clients is empty", consumerGroup, subTopic); + } + + Map> idcUrls = new HashMap<>(); + for (Client client : groupTopicClients) { + if (idcUrls.containsKey(client.idc)) { + idcUrls.get(client.idc).add(StringUtils.deleteWhitespace(client.url)); + } else { + List urls = new ArrayList<>(); + urls.add(client.url); + idcUrls.put(client.idc, urls); + } + } + ConsumerGroupConf consumerGroupConf = + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup); + if (consumerGroupConf == null) { + // new subscription + consumerGroupConf = new ConsumerGroupConf(consumerGroup); + ConsumerGroupTopicConf consumeTopicConfig = new ConsumerGroupTopicConf(); + consumeTopicConfig.setConsumerGroup(consumerGroup); + consumeTopicConfig.setTopic(subTopic.getTopic()); + consumeTopicConfig.setSubscriptionItem(subTopic); + consumeTopicConfig.setUrls(new HashSet<>(Arrays.asList(url))); + + consumeTopicConfig.setIdcUrls(idcUrls); + + Map map = new HashMap<>(); + map.put(subTopic.getTopic(), consumeTopicConfig); + consumerGroupConf.setConsumerGroupTopicConf(map); + } else { + // already subscribed + Map map = + consumerGroupConf.getConsumerGroupTopicConf(); + if (!map.containsKey(subTopic.getTopic())) { + //If there are multiple topics, append it + ConsumerGroupTopicConf newTopicConf = new ConsumerGroupTopicConf(); + newTopicConf.setConsumerGroup(consumerGroup); + newTopicConf.setTopic(subTopic.getTopic()); + newTopicConf.setSubscriptionItem(subTopic); + newTopicConf.setUrls(new HashSet<>(Arrays.asList(url))); + newTopicConf.setIdcUrls(idcUrls); + map.put(subTopic.getTopic(), newTopicConf); + } + for (String key : map.keySet()) { + if (StringUtils.equals(subTopic.getTopic(), key)) { + ConsumerGroupTopicConf latestTopicConf = new ConsumerGroupTopicConf(); + latestTopicConf.setConsumerGroup(consumerGroup); + latestTopicConf.setTopic(subTopic.getTopic()); + latestTopicConf.setSubscriptionItem(subTopic); + latestTopicConf.setUrls(new HashSet<>(Arrays.asList(url))); + + ConsumerGroupTopicConf currentTopicConf = map.get(key); + latestTopicConf.getUrls().addAll(currentTopicConf.getUrls()); + latestTopicConf.setIdcUrls(idcUrls); + + map.put(key, latestTopicConf); + } + } + } + eventMeshHTTPServer.localConsumerGroupMapping.put(consumerGroup, consumerGroupConf); + } + + long startTime = System.currentTimeMillis(); + try { + // subscription relationship change notification + eventMeshHTTPServer.getConsumerManager().notifyConsumerManager(consumerGroup, + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup)); + + responseBodyMap.put("retCode", EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.SUCCESS.getErrMsg()); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + + } catch (Exception e) { + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}" + + "|bizSeqNo={}|uniqueId={}", endTime - startTime, + JsonUtils.serialize(subscriptionList), url, e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR, responseHeaderMap, responseBodyMap, null); + } + + // Update service metadata + updateMetadata(); + } + + } + + @Override + public String[] paths() { + return new String[] {RequestURI.SUBSCRIBE_LOCAL.getRequestURI()}; + } + + private void registerClient(HttpEventWrapper requestWrapper, String consumerGroup, + List subscriptionItems, String url) { + Map requestHeaderMap = requestWrapper.getSysHeaderMap(); + for (SubscriptionItem item : subscriptionItems) { + Client client = new Client(); + client.env = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.ENV).toString(); + client.idc = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString(); + client.sys = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString(); + client.ip = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IP).toString(); + client.pid = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString(); + client.consumerGroup = consumerGroup; + client.topic = item.getTopic(); + client.url = url; + client.lastUpTime = new Date(); + + String groupTopicKey = client.consumerGroup + "@" + client.topic; + + if (eventMeshHTTPServer.localClientInfoMapping.containsKey(groupTopicKey)) { + List localClients = + eventMeshHTTPServer.localClientInfoMapping.get(groupTopicKey); + boolean isContains = false; + for (Client localClient : localClients) { + if (StringUtils.equals(localClient.url, client.url)) { + isContains = true; + localClient.lastUpTime = client.lastUpTime; + break; + } + } + if (!isContains) { + localClients.add(client); + } + } else { + List clients = new ArrayList<>(); + clients.add(client); + eventMeshHTTPServer.localClientInfoMapping.put(groupTopicKey, clients); + } + } + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/LocalUnSubscribeEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/LocalUnSubscribeEventProcessor.java new file mode 100644 index 0000000000..3f9c858d64 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/LocalUnSubscribeEventProcessor.java @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.AbstractEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.HttpRequest; + +import com.fasterxml.jackson.core.type.TypeReference; + +@EventMeshTrace(isEnable = false) +public class LocalUnSubscribeEventProcessor extends AbstractEventProcessor implements AsyncHttpProcessor { + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public LocalUnSubscribeEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + super(eventMeshHTTPServer); + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) throws Exception { + + AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + + ChannelHandlerContext ctx = handlerSpecific.getCtx(); + + HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + // user request header + Map userRequestHeaderMap = requestWrapper.getHeaderMap(); + String requestIp = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, requestIp); + + // build sys header + requestWrapper.buildSysHeaderForClient(); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, + IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + Map sysHeaderMap = requestWrapper.getSysHeaderMap(); + + Map responseBodyMap = new HashMap<>(); + + //validate header + if (StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || !StringUtils.isNumeric(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString())) { + + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + //validate body + byte[] requestBody = requestWrapper.getBody(); + + Map requestBodyMap = JsonUtils.deserialize(new String(requestBody), new TypeReference>() { + }); + + if (requestBodyMap.get("url") == null || requestBodyMap.get("topic") == null || requestBodyMap.get("consumerGroup") == null) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + String unSubscribeUrl = requestBodyMap.get("url").toString(); + String consumerGroup = requestBodyMap.get("consumerGroup").toString(); + String topic = JsonUtils.serialize(requestBodyMap.get("topic")); + + // unSubscriptionItem + List unSubTopicList = JsonUtils.deserialize(topic, new TypeReference>() { + }); + + String env = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.ENV).toString(); + String idc = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString(); + String sys = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString(); + String ip = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IP).toString(); + String pid = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString(); + + synchronized (eventMeshHTTPServer.localClientInfoMapping) { + boolean isChange = true; + + registerClient(requestWrapper, consumerGroup, unSubTopicList, unSubscribeUrl); + + for (String unSubTopic : unSubTopicList) { + List groupTopicClients = eventMeshHTTPServer.localClientInfoMapping + .get(consumerGroup + "@" + unSubTopic); + Iterator clientIterator = groupTopicClients.iterator(); + while (clientIterator.hasNext()) { + Client client = clientIterator.next(); + if (StringUtils.equals(client.pid, pid) + && StringUtils.equals(client.url, unSubscribeUrl)) { + httpLogger.warn("client {} start unsubscribe", JsonUtils.serialize(client)); + clientIterator.remove(); + } + } + if (groupTopicClients.size() > 0) { + //change url + Map> idcUrls = new HashMap<>(); + Set clientUrls = new HashSet<>(); + for (Client client : groupTopicClients) { + // remove subscribed url + if (!StringUtils.equals(unSubscribeUrl, client.url)) { + clientUrls.add(client.url); + if (idcUrls.containsKey(client.idc)) { + idcUrls.get(client.idc) + .add(StringUtils.deleteWhitespace(client.url)); + } else { + List urls = new ArrayList<>(); + urls.add(client.url); + idcUrls.put(client.idc, urls); + } + } + + } + synchronized (eventMeshHTTPServer.localConsumerGroupMapping) { + ConsumerGroupConf consumerGroupConf = + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup); + Map map = + consumerGroupConf.getConsumerGroupTopicConf(); + for (String topicKey : map.keySet()) { + // only modify the topic to subscribe + if (StringUtils.equals(unSubTopic, topicKey)) { + ConsumerGroupTopicConf latestTopicConf = + new ConsumerGroupTopicConf(); + latestTopicConf.setConsumerGroup(consumerGroup); + latestTopicConf.setTopic(unSubTopic); + latestTopicConf + .setSubscriptionItem(map.get(topicKey).getSubscriptionItem()); + latestTopicConf.setUrls(clientUrls); + + latestTopicConf.setIdcUrls(idcUrls); + + map.put(unSubTopic, latestTopicConf); + } + } + eventMeshHTTPServer.localConsumerGroupMapping + .put(consumerGroup, consumerGroupConf); + } + } else { + isChange = false; + break; + } + } + long startTime = System.currentTimeMillis(); + if (isChange) { + try { + eventMeshHTTPServer.getConsumerManager().notifyConsumerManager(consumerGroup, + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup)); + + responseBodyMap.put("retCode", EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.SUCCESS.getErrMsg()); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + + } catch (Exception e) { + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + + "|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, + JsonUtils.serialize(unSubTopicList), unSubscribeUrl, e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, responseHeaderMap, + responseBodyMap, null); + } + } else { + //remove + try { + eventMeshHTTPServer.getConsumerManager() + .notifyConsumerManager(consumerGroup, null); + responseBodyMap.put("retCode", EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.SUCCESS.getErrMsg()); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + // clean ClientInfo + eventMeshHTTPServer.localClientInfoMapping.keySet() + .removeIf(s -> StringUtils.contains(s, consumerGroup)); + // clean ConsumerGroupInfo + eventMeshHTTPServer.localConsumerGroupMapping.keySet() + .removeIf(s -> StringUtils.equals(consumerGroup, s)); + } catch (Exception e) { + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + + "|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, + JsonUtils.serialize(unSubTopicList), unSubscribeUrl, e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, responseHeaderMap, + responseBodyMap, null); + } + } + + // Update service metadata + updateMetadata(); + } + } + + @Override + public String[] paths() { + return new String[] {RequestURI.UNSUBSCRIBE_LOCAL.getRequestURI()}; + } + + + private void registerClient(HttpEventWrapper requestWrapper, + String consumerGroup, + List topicList, String url) { + Map requestHeaderMap = requestWrapper.getSysHeaderMap(); + for (String topic : topicList) { + Client client = new Client(); + client.env = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.ENV).toString(); + client.idc = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString(); + client.sys = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString(); + client.ip = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IP).toString(); + client.pid = requestHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString(); + client.consumerGroup = consumerGroup; + client.topic = topic; + client.url = url; + client.lastUpTime = new Date(); + + String groupTopicKey = client.consumerGroup + "@" + client.topic; + if (eventMeshHTTPServer.localClientInfoMapping.containsKey(groupTopicKey)) { + List localClients = + eventMeshHTTPServer.localClientInfoMapping.get(groupTopicKey); + boolean isContains = false; + for (Client localClient : localClients) { + if (StringUtils.equals(localClient.url, client.url)) { + isContains = true; + localClient.lastUpTime = client.lastUpTime; + break; + } + } + if (!isContains) { + localClients.add(client); + } + } else { + List clients = new ArrayList<>(); + clients.add(client); + eventMeshHTTPServer.localClientInfoMapping.put(groupTopicKey, clients); + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/RemoteSubscribeEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/RemoteSubscribeEventProcessor.java new file mode 100644 index 0000000000..f1a9d9c330 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/RemoteSubscribeEventProcessor.java @@ -0,0 +1,301 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.AbstractEventProcessor; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.WebhookUtil; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.HttpRequest; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.base.Preconditions; + +@EventMeshTrace(isEnable = false) +public class RemoteSubscribeEventProcessor extends AbstractEventProcessor implements AsyncHttpProcessor { + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + + public RemoteSubscribeEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + super(eventMeshHTTPServer); + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) throws Exception { + + AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + + ChannelHandlerContext ctx = handlerSpecific.getCtx(); + + HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), + EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress() + ); + + // user request header + Map userRequestHeaderMap = requestWrapper.getHeaderMap(); + String requestIp = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, requestIp); + + // build sys header + requestWrapper.buildSysHeaderForClient(); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap + .put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + Map sysHeaderMap = requestWrapper.getSysHeaderMap(); + + Map responseBodyMap = new HashMap<>(); + + //validate header + if (StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || !StringUtils.isNumeric(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString())) { + + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + + //validate body + byte[] requestBody = requestWrapper.getBody(); + + Map requestBodyMap = JsonUtils.deserialize(new String(requestBody), new TypeReference>() { + }); + + + if (requestBodyMap.get("url") == null || requestBodyMap.get("topic") == null || requestBodyMap.get("consumerGroup") == null) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + String url = requestBodyMap.get("url").toString(); + String consumerGroup = requestBodyMap.get("consumerGroup").toString(); + String topic = JsonUtils.serialize(requestBodyMap.get("topic")); + + + // SubscriptionItem + List subscriptionList = JsonUtils.deserialize(topic, new TypeReference>() { + }); + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.USERNAME).toString(); + String pass = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PASSWD).toString(); + String subsystem = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString(); + for (SubscriptionItem item : subscriptionList) { + try { + Acl.doAclCheckInHttpReceive(remoteAddr, user, pass, subsystem, item.getTopic(), + requestWrapper.getRequestURI()); + } catch (Exception e) { + aclLogger.warn("CLIENT HAS NO PERMISSION,SubscribeProcessor subscribe failed", e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_ACL_ERR, responseHeaderMap, + responseBodyMap, null); + + return; + } + } + } + + // validate URL + try { + if (!IPUtils.isValidDomainOrIp(url, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIpv4BlackList, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIpv6BlackList)) { + httpLogger.error("subscriber url {} is not valid", url); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + } catch (Exception e) { + httpLogger.error("subscriber url {} is not valid, error {}", url, e.getMessage()); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + // obtain webhook delivery agreement for Abuse Protection + boolean isWebhookAllowed = WebhookUtil.obtainDeliveryAgreement(eventMeshHTTPServer.httpClientPool.getClient(), + url, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshWebhookOrigin); + + if (!isWebhookAllowed) { + httpLogger.error("subscriber url {} is not allowed by the target system", url); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + long startTime = System.currentTimeMillis(); + try { + // request to remote + + String env = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv; + String idc = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC; + String cluster = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster; + String sysId = eventMeshHTTPServer.getEventMeshHttpConfiguration().sysID; + String meshGroup = env + "-" + idc + "-" + cluster + "-" + sysId; + + Map remoteHeaderMap = new HashMap<>(); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV, env); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC, idc); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, IPUtils.getLocalAddress()); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PID, String.valueOf(ThreadUtils.getPID())); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS, sysId); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.USERNAME, "eventmesh"); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PASSWD, "pass"); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP, meshGroup); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.CONSUMERGROUP, meshGroup); + + // local subscription url + String localUrl = "http://" + IPUtils.getLocalAddress() + ":" + + eventMeshHTTPServer.getEventMeshHttpConfiguration().httpServerPort + + RequestURI.PUBLISH_BRIDGE.getRequestURI(); + + Map remoteBodyMap = new HashMap<>(); + remoteBodyMap.put("url", localUrl); + remoteBodyMap.put("consumerGroup", meshGroup); + remoteBodyMap.put("topic", requestBodyMap.get("topic")); + + String targetMesh = requestBodyMap.get("remoteMesh") == null ? "" : requestBodyMap.get("remoteMesh").toString(); + + // Get mesh address from registry + String meshAddress = getTargetMesh(consumerGroup, subscriptionList); + if (StringUtils.isNotBlank(meshAddress)) { + targetMesh = meshAddress; + } + + + CloseableHttpClient closeableHttpClient = eventMeshHTTPServer.httpClientPool.getClient(); + + String remoteResult = post(closeableHttpClient, targetMesh, remoteHeaderMap, remoteBodyMap, + response -> EntityUtils.toString(response.getEntity(), Charset.forName(Constants.DEFAULT_CHARSET))); + + Map remoteResultMap = JsonUtils.deserialize(remoteResult, new TypeReference>() { + }); + + if (String.valueOf(EventMeshRetCode.SUCCESS.getRetCode()).equals(remoteResultMap.get("retCode"))) { + responseBodyMap.put("retCode", EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.SUCCESS.getErrMsg()); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + } else { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR, responseHeaderMap, + responseBodyMap, null); + } + + } catch (Exception e) { + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}" + + "|bizSeqNo={}|uniqueId={}", endTime - startTime, + JsonUtils.serialize(subscriptionList), url, e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR, responseHeaderMap, + responseBodyMap, null); + } + } + + @Override + public String[] paths() { + return new String[] {RequestURI.SUBSCRIBE_REMOTE.getRequestURI()}; + } + + public static String post(CloseableHttpClient client, String uri, + Map requestHeader, Map requestBody, + ResponseHandler responseHandler) throws IOException { + Preconditions.checkState(client != null, "client can't be null"); + Preconditions.checkState(StringUtils.isNotBlank(uri), "uri can't be null"); + Preconditions.checkState(requestHeader != null, "requestParam can't be null"); + Preconditions.checkState(responseHandler != null, "responseHandler can't be null"); + + HttpPost httpPost = new HttpPost(uri); + + httpPost.addHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType()); + + //header + if (MapUtils.isNotEmpty(requestHeader)) { + for (Map.Entry entry : requestHeader.entrySet()) { + httpPost.addHeader(entry.getKey(), entry.getValue()); + } + } + + //body + if (MapUtils.isNotEmpty(requestBody)) { + String jsonStr = JsonUtils.serialize(requestBody); + httpPost.setEntity(new StringEntity(jsonStr, ContentType.APPLICATION_JSON)); + } + + //ttl + RequestConfig.Builder configBuilder = RequestConfig.custom(); + configBuilder.setSocketTimeout(Integer.parseInt(String.valueOf(Constants.DEFAULT_HTTP_TIME_OUT))) + .setConnectTimeout(Integer.parseInt(String.valueOf(Constants.DEFAULT_HTTP_TIME_OUT))) + .setConnectionRequestTimeout(Integer.parseInt(String.valueOf(Constants.DEFAULT_HTTP_TIME_OUT))); + + httpPost.setConfig(configBuilder.build()); + + return client.execute(httpPost, responseHandler); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/RemoteUnSubscribeEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/RemoteUnSubscribeEventProcessor.java new file mode 100644 index 0000000000..9c3d9ff7c6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/RemoteUnSubscribeEventProcessor.java @@ -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 org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.AbstractEventProcessor; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.HttpRequest; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.base.Preconditions; + +@EventMeshTrace(isEnable = false) +public class RemoteUnSubscribeEventProcessor extends AbstractEventProcessor implements AsyncHttpProcessor { + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + public RemoteUnSubscribeEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + super(eventMeshHTTPServer); + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) throws Exception { + + AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + + ChannelHandlerContext ctx = handlerSpecific.getCtx(); + + HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), + EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress() + ); + + // user request header + Map userRequestHeaderMap = requestWrapper.getHeaderMap(); + String requestIp = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, requestIp); + + // build sys header + requestWrapper.buildSysHeaderForClient(); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap + .put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + Map sysHeaderMap = requestWrapper.getSysHeaderMap(); + + Map responseBodyMap = new HashMap<>(); + + //validate header + if (StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || !StringUtils.isNumeric(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()) + || StringUtils.isBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString())) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + + //validate body + byte[] requestBody = requestWrapper.getBody(); + + Map requestBodyMap = JsonUtils.deserialize(new String(requestBody), new TypeReference>() { + }); + + + if (requestBodyMap.get("url") == null || requestBodyMap.get("topic") == null || requestBodyMap.get("consumerGroup") == null) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + String unSubscribeUrl = requestBodyMap.get("url").toString(); + String consumerGroup = requestBodyMap.get("consumerGroup").toString(); + String topic = requestBodyMap.get("topic").toString(); + + long startTime = System.currentTimeMillis(); + try { + // request to remote + + String env = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv; + String idc = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC; + String cluster = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster; + String sysId = eventMeshHTTPServer.getEventMeshHttpConfiguration().sysID; + String meshGroup = env + "-" + idc + "-" + cluster + "-" + sysId; + + Map remoteHeaderMap = new HashMap<>(); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV, env); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC, idc); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, IPUtils.getLocalAddress()); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PID, String.valueOf(ThreadUtils.getPID())); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS, sysId); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.USERNAME, "eventmesh"); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PASSWD, "pass"); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP, meshGroup); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.CONSUMERGROUP, meshGroup); + + // local unSubscription url + String unsubscribeUrl = "http://" + IPUtils.getLocalAddress() + ":" + + eventMeshHTTPServer.getEventMeshHttpConfiguration().httpServerPort + + RequestURI.PUBLISH_BRIDGE.getRequestURI(); + + Map remoteBodyMap = new HashMap<>(); + remoteBodyMap.put("url", unsubscribeUrl); + remoteBodyMap.put("consumerGroup", meshGroup); + remoteBodyMap.put("topic", requestBodyMap.get("topic")); + + List unSubTopicList = JsonUtils.deserialize(topic, new TypeReference>() { + }); + + String targetMesh = requestBodyMap.get("remoteMesh").toString(); + + List subscriptionList = unSubTopicList.stream().map(s -> { + SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setTopic(s); + return subscriptionItem; + }).collect(Collectors.toList()); + // Get mesh address from registry + String meshAddress = getTargetMesh(consumerGroup, subscriptionList); + if (StringUtils.isNotBlank(meshAddress)) { + targetMesh = meshAddress; + } + + CloseableHttpClient closeableHttpClient = eventMeshHTTPServer.httpClientPool.getClient(); + + String remoteResult = post(closeableHttpClient, targetMesh, remoteHeaderMap, remoteBodyMap, + response -> EntityUtils.toString(response.getEntity(), Charset.forName(Constants.DEFAULT_CHARSET))); + + Map remoteResultMap = JsonUtils.deserialize(remoteResult, new TypeReference>() { + }); + + if (String.valueOf(EventMeshRetCode.SUCCESS.getRetCode()).equals(remoteResultMap.get("retCode"))) { + responseBodyMap.put("retCode", EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.SUCCESS.getErrMsg()); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + } else { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, responseHeaderMap, + responseBodyMap, null); + } + + } catch (Exception e) { + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}" + + "|bizSeqNo={}|uniqueId={}", endTime - startTime, + topic, unSubscribeUrl, e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, responseHeaderMap, + responseBodyMap, null); + } + + } + + @Override + public String[] paths() { + return new String[] {RequestURI.UNSUBSCRIBE_REMOTE.getRequestURI()}; + } + + public static String post(CloseableHttpClient client, String uri, + Map requestHeader, Map requestBody, + ResponseHandler responseHandler) throws IOException { + Preconditions.checkState(client != null, "client can't be null"); + Preconditions.checkState(StringUtils.isNotBlank(uri), "uri can't be null"); + Preconditions.checkState(requestHeader != null, "requestParam can't be null"); + Preconditions.checkState(responseHandler != null, "responseHandler can't be null"); + + HttpPost httpPost = new HttpPost(uri); + + httpPost.addHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType()); + + //header + if (MapUtils.isNotEmpty(requestHeader)) { + for (Map.Entry entry : requestHeader.entrySet()) { + httpPost.addHeader(entry.getKey(), entry.getValue()); + } + } + + //body + if (MapUtils.isNotEmpty(requestBody)) { + String jsonStr = JsonUtils.serialize(requestBody); + httpPost.setEntity(new StringEntity(jsonStr, ContentType.APPLICATION_JSON)); + } + + //ttl + RequestConfig.Builder configBuilder = RequestConfig.custom(); + configBuilder.setSocketTimeout(Integer.parseInt(String.valueOf(Constants.DEFAULT_HTTP_TIME_OUT))) + .setConnectTimeout(Integer.parseInt(String.valueOf(Constants.DEFAULT_HTTP_TIME_OUT))) + .setConnectionRequestTimeout(Integer.parseInt(String.valueOf(Constants.DEFAULT_HTTP_TIME_OUT))); + + httpPost.setConfig(configBuilder.build()); + + return client.execute(httpPost, responseHandler); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/ReplyMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/ReplyMessageProcessor.java new file mode 100644 index 0000000000..aadb17e456 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/ReplyMessageProcessor.java @@ -0,0 +1,292 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.message.ReplyMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelHandlerContext; + +public class ReplyMessageProcessor implements HttpRequestProcessor { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + public Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public ReplyMessageProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { + HttpCommand responseEventMeshCommand; + + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + ReplyMessageRequestHeader replyMessageRequestHeader = (ReplyMessageRequestHeader) asyncContext.getRequest().getHeader(); + //ReplyMessageRequestBody replyMessageRequestBody = (ReplyMessageRequestBody) asyncContext.getRequest().getBody(); + + String protocolType = replyMessageRequestHeader.getProtocolType(); + ProtocolAdaptor httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest()); + + ReplyMessageResponseHeader replyMessageResponseHeader = + ReplyMessageResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + //validate event + if (event == null + || StringUtils.isBlank(event.getId()) + || event.getSource() == null + || event.getSpecVersion() == null + || StringUtils.isBlank(event.getType()) + || StringUtils.isBlank(event.getSubject())) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)).toString(); + String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)).toString(); + String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString(); + + //validate HEADER + if (StringUtils.isBlank(idc) + || StringUtils.isBlank(pid) + || !StringUtils.isNumeric(pid) + || StringUtils.isBlank(sys)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String bizNo = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.BIZSEQNO)).toString(); + String uniqueId = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.UNIQUEID)).toString(); + String producerGroup = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.PRODUCERGROUP)).toString(); + + //validate body + if (StringUtils.isBlank(bizNo) + || StringUtils.isBlank(uniqueId) + || StringUtils.isBlank(producerGroup) + || event.getData() == null) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + // control flow rate limit + if (!eventMeshHTTPServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getErrMsg())); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPDiscard(); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) { + httpLogger.error("Event size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + EventMeshProducer eventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup); + + if (!eventMeshProducer.getStarted().get()) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + long startTime = System.currentTimeMillis(); + + String replyTopic = EventMeshConstants.RR_REPLY_TOPIC; + + String origTopic = event.getSubject(); + + final String replyMQCluster = event.getExtension(EventMeshConstants.PROPERTY_MESSAGE_CLUSTER).toString(); + if (!org.apache.commons.lang3.StringUtils.isEmpty(replyMQCluster)) { + replyTopic = replyMQCluster + "-" + replyTopic; + } else { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + try { + // body + //omsMsg.setBody(replyMessageRequestBody.getContent().getBytes(EventMeshConstants.DEFAULT_CHARSET)); + event = CloudEventBuilder.from(event) + .withSubject(replyTopic) + .withExtension("msgtype", "persistent") + .withExtension(Constants.PROPERTY_MESSAGE_TIMEOUT, String.valueOf(EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS)) + .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, replyTopic); + } + + } catch (Exception e) { + messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, replyTopic, e); + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + final SendMessageContext sendMessageContext = new SendMessageContext(bizNo, event, eventMeshProducer, eventMeshHTTPServer); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsg(); + + CompleteHandler handler = httpCommand -> { + try { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", httpCommand); + } + eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - asyncContext.getRequest().getReqTime()); + } catch (Exception ex) { + //ignore + } + }; + + + try { + CloudEvent clone = CloudEventBuilder.from(sendMessageContext.getEvent()) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + sendMessageContext.setEvent(clone); + eventMeshProducer.reply(sendMessageContext, new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + HttpCommand succ = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), EventMeshRetCode.SUCCESS.getErrMsg())); + asyncContext.onComplete(succ, handler); + long endTime = System.currentTimeMillis(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgCost(endTime - startTime); + messageLogger.info("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, replyMQCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC, + origTopic, bizNo, uniqueId); + } + + @Override + public void onException(OnExceptionContext context) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(context.getException(), 2))); + asyncContext.onComplete(err, handler); + long endTime = System.currentTimeMillis(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgCost(endTime - startTime); + messageLogger.error("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, replyMQCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC, + origTopic, bizNo, uniqueId, context.getException()); + } + }); + } catch (Exception ex) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + replyMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(ex, 2))); + asyncContext.onComplete(err); + long endTime = System.currentTimeMillis(); + messageLogger.error("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, replyTopic, origTopic, bizNo, uniqueId, ex); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgCost(endTime - startTime); + } + } + + @Override + public boolean rejectRequest() { + return false; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncEventProcessor.java new file mode 100644 index 0000000000..51076199ec --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncEventProcessor.java @@ -0,0 +1,286 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.HttpRequest; + +@EventMeshTrace(isEnable = true) +public class SendAsyncEventProcessor implements AsyncHttpProcessor { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public SendAsyncEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) throws Exception { + + AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + + ChannelHandlerContext ctx = handlerSpecific.getCtx(); + + HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), + EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + // user request header + Map requestHeaderMap = requestWrapper.getHeaderMap(); + String source = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, source); + + // build sys header + requestWrapper.buildSysHeaderForClient(); + + // build cloudevents attributes + requestHeaderMap.putIfAbsent("source", source); + requestWrapper.buildSysHeaderForCE(); + + String bizNo = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.BIZSEQNO, RandomStringUtils.generateNum(30)).toString(); + String uniqueId = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.UNIQUEID, RandomStringUtils.generateNum(30)).toString(); + String ttl = requestHeaderMap.getOrDefault(Constants.EVENTMESH_MESSAGE_CONST_TTL, 4 * 1000).toString(); + + + requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.BIZSEQNO, bizNo); + requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.UNIQUEID, uniqueId); + requestWrapper.getSysHeaderMap().putIfAbsent(Constants.EVENTMESH_MESSAGE_CONST_TTL, ttl); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, + IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + Map responseBodyMap = new HashMap<>(); + + String protocolType = requestHeaderMap.getOrDefault(ProtocolKey.PROTOCOL_TYPE, "http").toString(); + + ProtocolAdaptor httpProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + + CloudEvent event = httpProtocolAdaptor.toCloudEvent(requestWrapper); + + //validate event + if (event == null + || StringUtils.isBlank(event.getId()) + || event.getSource() == null + || event.getSpecVersion() == null + || StringUtils.isBlank(event.getType()) + || StringUtils.isBlank(event.getSubject())) { + + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + + return; + } + + String idc = event.getExtension(ProtocolKey.ClientInstanceKey.IDC).toString(); + String pid = event.getExtension(ProtocolKey.ClientInstanceKey.PID).toString(); + String sys = event.getExtension(ProtocolKey.ClientInstanceKey.SYS).toString(); + + //validate event-extension + if (StringUtils.isBlank(idc) + || StringUtils.isBlank(pid) + || !StringUtils.isNumeric(pid) + || StringUtils.isBlank(sys)) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + + String producerGroup = event.getExtension(ProtocolKey.ClientInstanceKey.PRODUCERGROUP).toString(); + String topic = event.getSubject(); + + //validate body + if (StringUtils.isBlank(bizNo) + || StringUtils.isBlank(uniqueId) + || StringUtils.isBlank(producerGroup) + || StringUtils.isBlank(topic) + || event.getData() == null) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = event.getExtension(ProtocolKey.ClientInstanceKey.USERNAME).toString(); + String pass = event.getExtension(ProtocolKey.ClientInstanceKey.PASSWD).toString(); + String subsystem = event.getExtension(ProtocolKey.ClientInstanceKey.SYS).toString(); + String requestURI = requestWrapper.getRequestURI(); + try { + Acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, topic, requestURI); + } catch (Exception e) { + //String errorMsg = String.format("CLIENT HAS NO PERMISSION,send failed, topic:%s, subsys:%s, realIp:%s", topic, subsys, realIp); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_ACL_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + aclLogger.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e); + return; + } + } + + // control flow rate limit + if (!eventMeshHTTPServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + EventMeshProducer eventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup); + + if (!eventMeshProducer.getStarted().get()) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) { + httpLogger.error("Event size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + try { + event = CloudEventBuilder.from(event) + .withExtension("msgtype", "persistent") + .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); + } + } catch (Exception e) { + messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + final SendMessageContext sendMessageContext = new SendMessageContext(bizNo, event, eventMeshProducer, + eventMeshHTTPServer); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsg(); + + long startTime = System.currentTimeMillis(); + + try { + event = CloudEventBuilder.from(sendMessageContext.getEvent()) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + handlerSpecific.getTraceOperation().createClientTraceOperation(EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN, false); + + eventMeshProducer.send(sendMessageContext, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + responseBodyMap.put("retCode", EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.SUCCESS.getErrMsg() + sendResult.toString()); + + messageLogger.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + System.currentTimeMillis() - startTime, topic, bizNo, uniqueId); + handlerSpecific.getTraceOperation().endLatestTrace(sendMessageContext.getEvent()); + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + } + + @Override + public void onException(OnExceptionContext context) { + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(context.getException(), 2)); + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + handlerSpecific.getTraceOperation().exceptionLatestTrace(context.getException(), + EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), sendMessageContext.getEvent())); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + System.currentTimeMillis() - startTime, topic, bizNo, uniqueId, context.getException()); + } + }); + } catch (Exception ex) { + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR, responseHeaderMap, responseBodyMap, null); + + long endTime = System.currentTimeMillis(); + messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, bizNo, uniqueId, ex); + } + } + + @Override + public String[] paths() { + return new String[] {RequestURI.PUBLISH.getRequestURI()}; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncMessageProcessor.java new file mode 100644 index 0000000000..f2e01c04ff --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncMessageProcessor.java @@ -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 org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelHandlerContext; +import io.opentelemetry.api.trace.Span; + +public class SendAsyncMessageProcessor implements HttpRequestProcessor { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public SendAsyncMessageProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { + + HttpCommand responseEventMeshCommand; + + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get( + Integer.valueOf(asyncContext.getRequest().getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + SendMessageRequestHeader sendMessageRequestHeader = (SendMessageRequestHeader) asyncContext.getRequest().getHeader(); + + SendMessageResponseHeader sendMessageResponseHeader = + SendMessageResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + String protocolType = sendMessageRequestHeader.getProtocolType(); + String protocolVersin = sendMessageRequestHeader.getProtocolVersion(); + ProtocolAdaptor httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest()); + + Span span = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, true); + + //validate event + if (event == null + || StringUtils.isBlank(event.getId()) + || event.getSource() == null + || event.getSpecVersion() == null + || StringUtils.isBlank(event.getType()) + || StringUtils.isBlank(event.getSubject())) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg(), null); + return; + } + + String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)).toString(); + String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)).toString(); + String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString(); + + //validate event-extension + if (StringUtils.isBlank(idc) + || StringUtils.isBlank(pid) + || !StringUtils.isNumeric(pid) + || StringUtils.isBlank(sys)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg(), null); + return; + } + + String bizNo = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.BIZSEQNO)).toString(); + String uniqueId = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.UNIQUEID)).toString(); + String producerGroup = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.PRODUCERGROUP)).toString(); + String topic = event.getSubject(); + + //validate body + if (StringUtils.isBlank(bizNo) + || StringUtils.isBlank(uniqueId) + || StringUtils.isBlank(producerGroup) + || StringUtils.isBlank(topic) + || event.getData() == null) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg(), null); + return; + } + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = event.getExtension(ProtocolKey.ClientInstanceKey.USERNAME).toString(); + String pass = event.getExtension(ProtocolKey.ClientInstanceKey.PASSWD).toString(); + String subsystem = event.getExtension(ProtocolKey.ClientInstanceKey.SYS).toString(); + int requestCode = Integer.parseInt(asyncContext.getRequest().getRequestCode()); + try { + Acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, topic, requestCode); + } catch (Exception e) { + //String errorMsg = String.format("CLIENT HAS NO PERMISSION,send failed, topic:%s, subsys:%s, realIp:%s", topic, subsys, realIp); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage())); + asyncContext.onComplete(responseEventMeshCommand); + aclLogger.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_ACL_ERR.getErrMsg(), null); + return; + } + } + + // control flow rate limit + if (!eventMeshHTTPServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getErrMsg())); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPDiscard(); + asyncContext.onComplete(responseEventMeshCommand); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getErrMsg(), null); + return; + } + + EventMeshProducer eventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup); + + if (!eventMeshProducer.getStarted().get()) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getErrMsg(), null); + + return; + } + + String ttl = String.valueOf(EventMeshConstants.DEFAULT_MSG_TTL_MILLS); + if (StringUtils.isBlank(event.getExtension(SendMessageRequestBody.TTL).toString()) + && !StringUtils.isNumeric(event.getExtension(SendMessageRequestBody.TTL).toString())) { + event = CloudEventBuilder.from(event).withExtension(SendMessageRequestBody.TTL, ttl).build(); + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) { + httpLogger.error("Event size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR.getRetCode(), + "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize)); + asyncContext.onComplete(responseEventMeshCommand); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR.getErrMsg(), null); + return; + } + + try { + event = CloudEventBuilder.from(event) + .withExtension("msgtype", "persistent") + .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, asyncContext.getRequest().reqTime) + .withExtension(EventMeshConstants.REQ_SEND_EVENTMESH_IP, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerIp) + .build(); + + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); + } + } catch (Exception e) { + messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(responseEventMeshCommand); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg(), null); + return; + } + + final SendMessageContext sendMessageContext = new SendMessageContext(bizNo, event, eventMeshProducer, + eventMeshHTTPServer); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsg(); + + long startTime = System.currentTimeMillis(); + + final CompleteHandler handler = new CompleteHandler() { + @Override + public void onResponse(HttpCommand httpCommand) { + try { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", httpCommand); + } + eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); + + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - asyncContext.getRequest().getReqTime()); + } catch (Exception ex) { + //ignore + } + } + }; + + + try { + event = CloudEventBuilder.from(sendMessageContext.getEvent()) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + sendMessageContext.setEvent(event); + + Span clientSpan = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN, false); + try { + eventMeshProducer.send(sendMessageContext, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + HttpCommand succ = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), + EventMeshRetCode.SUCCESS.getErrMsg() + sendResult.toString())); + asyncContext.onComplete(succ, handler); + long endTime = System.currentTimeMillis(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime); + messageLogger.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, bizNo, uniqueId); + + TraceUtils.finishSpan(span, sendMessageContext.getEvent()); + } + + @Override + public void onException(OnExceptionContext context) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(context.getException(), 2))); + asyncContext.onComplete(err, handler); + + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + long endTime = System.currentTimeMillis(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime); + messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, bizNo, uniqueId, context.getException()); + + TraceUtils.finishSpanWithException(span, + EventMeshUtil.getCloudEventExtensionMap(protocolVersin, sendMessageContext.getEvent()), + EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg(), context.getException()); + } + }); + } finally { + TraceUtils.finishSpan(clientSpan, event); + } + + + } catch (Exception ex) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(ex, 2))); + asyncContext.onComplete(err); + + Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersin, event), + EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg(), null); + + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + long endTime = System.currentTimeMillis(); + messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, bizNo, uniqueId, ex); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime); + } + + return; + } + + @Override + public boolean rejectRequest() { + return false; + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncRemoteEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncRemoteEventProcessor.java new file mode 100644 index 0000000000..9d1eb94a68 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendAsyncRemoteEventProcessor.java @@ -0,0 +1,316 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestURI; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.HttpRequest; + +import com.fasterxml.jackson.core.type.TypeReference; + +@EventMeshTrace(isEnable = true) +public class SendAsyncRemoteEventProcessor implements AsyncHttpProcessor { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public SendAsyncRemoteEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) throws Exception { + + AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + + ChannelHandlerContext ctx = handlerSpecific.getCtx(); + + HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), + EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + // user request header + Map requestHeaderMap = requestWrapper.getHeaderMap(); + String source = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + + String env = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv; + String idc = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC; + String cluster = eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster; + String sysId = eventMeshHTTPServer.getEventMeshHttpConfiguration().sysID; + String meshGroup = env + "-" + idc + "-" + cluster + "-" + sysId; + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, source); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS, eventMeshHTTPServer.getEventMeshHttpConfiguration().sysID); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP, meshGroup); + + // build sys header + requestWrapper.buildSysHeaderForClient(); + + // build cloudevents attributes + requestHeaderMap.putIfAbsent("source", source); + requestWrapper.buildSysHeaderForCE(); + + // process remote event body + Map bodyMap = JsonUtils.deserialize(new String(requestWrapper.getBody()), new TypeReference>() { + }); + + byte[] convertedBody = bodyMap.get("content").toString().getBytes(StandardCharsets.UTF_8); + requestWrapper.setBody(convertedBody); + + String bizNo = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.BIZSEQNO, RandomStringUtils.generateNum(30)).toString(); + String uniqueId = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.UNIQUEID, RandomStringUtils.generateNum(30)).toString(); + String ttl = requestHeaderMap.getOrDefault(Constants.EVENTMESH_MESSAGE_CONST_TTL, 4 * 1000).toString(); + + + requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.BIZSEQNO, bizNo); + requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.UNIQUEID, uniqueId); + requestWrapper.getSysHeaderMap().putIfAbsent(Constants.EVENTMESH_MESSAGE_CONST_TTL, ttl); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + Map responseBodyMap = new HashMap<>(); + + Map sysHeaderMap = requestWrapper.getSysHeaderMap(); + Iterator> it = requestHeaderMap.entrySet().iterator(); + while (it.hasNext()) { + String key = it.next().getKey(); + if (sysHeaderMap.containsKey(key)) { + it.remove(); + } + } + + String protocolType = requestHeaderMap.getOrDefault(ProtocolKey.PROTOCOL_TYPE, "http").toString(); + + ProtocolAdaptor httpProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + CloudEvent event = httpProtocolAdaptor.toCloudEvent(requestWrapper); + + + //validate event + if (event == null + || StringUtils.isBlank(event.getId()) + || event.getSource() == null + || event.getSpecVersion() == null + || StringUtils.isBlank(event.getType()) + || StringUtils.isBlank(event.getSubject())) { + + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + + return; + } + + idc = event.getExtension(ProtocolKey.ClientInstanceKey.IDC).toString(); + String pid = event.getExtension(ProtocolKey.ClientInstanceKey.PID).toString(); + String sys = event.getExtension(ProtocolKey.ClientInstanceKey.SYS).toString(); + + //validate event-extension + if (StringUtils.isBlank(idc) + || StringUtils.isBlank(pid) + || !StringUtils.isNumeric(pid) + || StringUtils.isBlank(sys)) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + + String producerGroup = event.getExtension(ProtocolKey.ClientInstanceKey.PRODUCERGROUP).toString(); + String topic = event.getSubject(); + + //validate body + if (StringUtils.isBlank(bizNo) + || StringUtils.isBlank(uniqueId) + || StringUtils.isBlank(producerGroup) + || StringUtils.isBlank(topic) + || event.getData() == null) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = event.getExtension(ProtocolKey.ClientInstanceKey.USERNAME).toString(); + String pass = event.getExtension(ProtocolKey.ClientInstanceKey.PASSWD).toString(); + String subsystem = event.getExtension(ProtocolKey.ClientInstanceKey.SYS).toString(); + String requestURI = requestWrapper.getRequestURI(); + try { + Acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, topic, requestURI); + } catch (Exception e) { + //String errorMsg = String.format("CLIENT HAS NO PERMISSION,send failed, topic:%s, subsys:%s, realIp:%s", topic, subsys, realIp); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_ACL_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + aclLogger.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e); + return; + } + } + + // control flow rate limit + if (!eventMeshHTTPServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + EventMeshProducer eventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup); + + if (!eventMeshProducer.getStarted().get()) { + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) { + httpLogger.error("Event size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + try { + event = CloudEventBuilder.from(event) + .withExtension("msgtype", "persistent") + .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); + } + } catch (Exception e) { + messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, responseHeaderMap, + responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + return; + } + + final SendMessageContext sendMessageContext = new SendMessageContext(bizNo, event, eventMeshProducer, + eventMeshHTTPServer); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsg(); + + long startTime = System.currentTimeMillis(); + + try { + event = CloudEventBuilder.from(sendMessageContext.getEvent()) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + handlerSpecific.getTraceOperation().createClientTraceOperation(EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN, false); + + eventMeshProducer.send(sendMessageContext, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + responseBodyMap.put("retCode", EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.SUCCESS.getErrMsg() + sendResult.toString()); + + messageLogger.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + System.currentTimeMillis() - startTime, topic, bizNo, uniqueId); + handlerSpecific.getTraceOperation().endLatestTrace(sendMessageContext.getEvent()); + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + } + + @Override + public void onException(OnExceptionContext context) { + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(context.getException(), 2)); + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + handlerSpecific.getTraceOperation().exceptionLatestTrace(context.getException(), + EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), sendMessageContext.getEvent())); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); + messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + System.currentTimeMillis() - startTime, topic, bizNo, uniqueId, context.getException()); + } + }); + } catch (Exception ex) { + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR, responseHeaderMap, responseBodyMap, null); + + long endTime = System.currentTimeMillis(); + messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, bizNo, uniqueId, ex); + } + } + + @Override + public String[] paths() { + return new String[] {RequestURI.PUBLISH_BRIDGE.getRequestURI()}; + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendSyncMessageProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendSyncMessageProcessor.java new file mode 100644 index 0000000000..529d3ce94e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SendSyncMessageProcessor.java @@ -0,0 +1,349 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.message.SendMessageResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelHandlerContext; + +public class SendSyncMessageProcessor implements HttpRequestProcessor { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + public Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public SendSyncMessageProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) + throws Exception { + + HttpCommand responseEventMeshCommand; + + cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + ProtocolAdaptor httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor("cloudevents"); + CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest()); + + SendMessageResponseHeader sendMessageResponseHeader = + SendMessageResponseHeader + .buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + //validate event + if (event == null + || StringUtils.isBlank(event.getId()) + || event.getSource() == null + || event.getSpecVersion() == null + || StringUtils.isBlank(event.getType()) + || StringUtils.isBlank(event.getSubject())) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)) + .toString(); + String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)) + .toString(); + String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)) + .toString(); + + //validate event-extension + if (StringUtils.isBlank(idc) + || StringUtils.isBlank(pid) + || !StringUtils.isNumeric(pid) + || StringUtils.isBlank(sys)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String bizNo = + Objects.requireNonNull(event.getExtension(SendMessageRequestBody.BIZSEQNO)).toString(); + String uniqueId = + Objects.requireNonNull(event.getExtension(SendMessageRequestBody.UNIQUEID)).toString(); + String producerGroup = + Objects.requireNonNull(event.getExtension(SendMessageRequestBody.PRODUCERGROUP)) + .toString(); + String topic = event.getSubject(); + String ttl = + Objects.requireNonNull(event.getExtension(SendMessageRequestBody.TTL)).toString(); + + //validate body + if (StringUtils.isBlank(bizNo) + || StringUtils.isBlank(uniqueId) + || StringUtils.isBlank(producerGroup) + || StringUtils.isBlank(topic) + || event.getData() == null + || StringUtils.isBlank(ttl)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = event.getExtension(ProtocolKey.ClientInstanceKey.USERNAME).toString(); + String pass = event.getExtension(ProtocolKey.ClientInstanceKey.PASSWD).toString(); + int requestCode = Integer.parseInt(asyncContext.getRequest().getRequestCode()); + + try { + Acl.doAclCheckInHttpSend(remoteAddr, user, pass, sys, topic, requestCode); + } catch (Exception e) { + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), + e.getMessage())); + asyncContext.onComplete(responseEventMeshCommand); + aclLogger.warn("CLIENT HAS NO PERMISSION,SendSyncMessageProcessor send failed", e); + return; + } + } + + // control flow rate limit + if (!eventMeshHTTPServer.getMsgRateLimiter() + .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, + TimeUnit.MILLISECONDS)) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getErrMsg())); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPDiscard(); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) { + httpLogger.error("Event size exceeds the limit: {}", + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize); + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + EventMeshProducer eventMeshProducer = + eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup); + + if (!eventMeshProducer.getStarted().get()) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + try { + event = CloudEventBuilder.from(event) + .withExtension("msgtype", "persistent") + .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); + } + + } catch (Exception e) { + messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + final SendMessageContext sendMessageContext = + new SendMessageContext(bizNo, event, eventMeshProducer, + eventMeshHTTPServer); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsg(); + + long startTime = System.currentTimeMillis(); + + final CompleteHandler handler = new CompleteHandler() { + @Override + public void onResponse(HttpCommand httpCommand) { + try { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", httpCommand); + } + eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - asyncContext.getRequest().getReqTime()); + } catch (Exception ex) { + // ignore + } + } + }; + + + try { + eventMeshProducer.request(sendMessageContext, new RequestReplyCallback() { + @Override + public void onSuccess(CloudEvent event) { + messageLogger.info("message|mq2eventMesh|RSP|SYNC|rrCost={}ms|topic={}" + + "|bizSeqNo={}|uniqueId={}", System.currentTimeMillis() - startTime, + topic, bizNo, uniqueId); + + try { + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.RSP_EVENTMESH2C_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.RSP_MQ2EVENTMESH_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .build(); + final String rtnMsg = new String(event.getData().toBytes(), + EventMeshConstants.DEFAULT_CHARSET); + + HttpCommand succ = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), + JsonUtils.serialize(SendMessageResponseBody.ReplyMessage.builder() + .topic(topic) + .body(rtnMsg) + .properties(EventMeshUtil.getEventProp(event)) + .build()))); + asyncContext.onComplete(succ, handler); + } catch (Exception ex) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody.buildBody( + EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(ex, 2))); + asyncContext.onComplete(err, handler); + messageLogger.warn("message|mq2eventMesh|RSP", ex); + } + } + + @Override + public void onException(Throwable e) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(err, handler); + + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + messageLogger.error( + "message|mq2eventMesh|RSP|SYNC|rrCost={}ms|topic={}" + + "|bizSeqNo={}|uniqueId={}", System.currentTimeMillis() - startTime, + topic, bizNo, uniqueId, e); + } + }, Integer.parseInt(ttl)); + } catch (Exception ex) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + sendMessageResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_SEND_SYNC_MSG_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_SEND_SYNC_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(ex, 2))); + asyncContext.onComplete(err); + + eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + long endTime = System.currentTimeMillis(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime); + messageLogger.error( + "message|eventMesh2mq|REQ|SYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, bizNo, uniqueId, ex); + } + + return; + } + + @Override + public boolean rejectRequest() { + return false; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SubscribeProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SubscribeProcessor.java new file mode 100644 index 0000000000..fa521f8716 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/SubscribeProcessor.java @@ -0,0 +1,349 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.client.SubscribeRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.SubscribeResponseBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.client.SubscribeRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.client.SubscribeResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.WebhookUtil; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class SubscribeProcessor implements HttpRequestProcessor { + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + public Logger aclLogger = LoggerFactory.getLogger("acl"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public SubscribeProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) + throws Exception { + HttpCommand responseEventMeshCommand; + final HttpCommand request = asyncContext.getRequest(); + final Integer requestCode = Integer.valueOf(asyncContext.getRequest().getRequestCode()); + + httpLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + RequestCode.get(requestCode), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress() + ); + SubscribeRequestHeader subscribeRequestHeader = (SubscribeRequestHeader) request.getHeader(); + SubscribeRequestBody subscribeRequestBody = (SubscribeRequestBody) request.getBody(); + + SubscribeResponseHeader subscribeResponseHeader = + SubscribeResponseHeader + .buildHeader(requestCode, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + //validate header + if (StringUtils.isBlank(subscribeRequestHeader.getIdc()) + || StringUtils.isBlank(subscribeRequestHeader.getPid()) + || !StringUtils.isNumeric(subscribeRequestHeader.getPid()) + || StringUtils.isBlank(subscribeRequestHeader.getSys())) { + responseEventMeshCommand = request.createHttpCommandResponse( + subscribeResponseHeader, + SubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + //validate body + if (StringUtils.isBlank(subscribeRequestBody.getUrl()) + || CollectionUtils.isEmpty(subscribeRequestBody.getTopics()) + || StringUtils.isBlank(subscribeRequestBody.getConsumerGroup())) { + + responseEventMeshCommand = request.createHttpCommandResponse( + subscribeResponseHeader, + SubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + List subTopicList = subscribeRequestBody.getTopics(); + + //do acl check + if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String user = subscribeRequestHeader.getUsername(); + String pass = subscribeRequestHeader.getPasswd(); + String subsystem = subscribeRequestHeader.getSys(); + for (SubscriptionItem item : subTopicList) { + try { + Acl.doAclCheckInHttpReceive(remoteAddr, user, pass, subsystem, item.getTopic(), + requestCode); + } catch (Exception e) { + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + subscribeResponseHeader, + SendMessageResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), + e.getMessage())); + asyncContext.onComplete(responseEventMeshCommand); + aclLogger + .warn("CLIENT HAS NO PERMISSION,SubscribeProcessor subscribe failed", e); + return; + } + } + } + + String url = subscribeRequestBody.getUrl(); + String consumerGroup = subscribeRequestBody.getConsumerGroup(); + + // validate URL + try { + if (!IPUtils.isValidDomainOrIp(url, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIpv4BlackList, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIpv6BlackList)) { + httpLogger.error("subscriber url {} is not valid", url); + responseEventMeshCommand = request.createHttpCommandResponse( + subscribeResponseHeader, + SubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg() + " invalid URL: " + url)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + } catch (Exception e) { + httpLogger.error("subscriber url {} is not valid, error {}", url, e.getMessage()); + responseEventMeshCommand = request.createHttpCommandResponse( + subscribeResponseHeader, + SubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg() + " invalid URL: " + url)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + // obtain webhook delivery agreement for Abuse Protection + boolean isWebhookAllowed = WebhookUtil.obtainDeliveryAgreement(eventMeshHTTPServer.httpClientPool.getClient(), + url, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshWebhookOrigin); + + if (!isWebhookAllowed) { + httpLogger.error("subscriber url {} is not allowed by the target system", url); + responseEventMeshCommand = request.createHttpCommandResponse( + subscribeResponseHeader, + SubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg() + " unauthorized webhook URL: " + url)); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + synchronized (eventMeshHTTPServer.localClientInfoMapping) { + + registerClient(subscribeRequestHeader, consumerGroup, subTopicList, url); + + for (SubscriptionItem subTopic : subTopicList) { + List groupTopicClients = eventMeshHTTPServer.localClientInfoMapping + .get(consumerGroup + "@" + subTopic.getTopic()); + + if (CollectionUtils.isEmpty(groupTopicClients)) { + httpLogger.error("group {} topic {} clients is empty", consumerGroup, subTopic); + } + + Map> idcUrls = new HashMap<>(); + for (Client client : groupTopicClients) { + if (idcUrls.containsKey(client.idc)) { + idcUrls.get(client.idc).add(StringUtils.deleteWhitespace(client.url)); + } else { + List urls = new ArrayList<>(); + urls.add(client.url); + idcUrls.put(client.idc, urls); + } + } + ConsumerGroupConf consumerGroupConf = + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup); + if (consumerGroupConf == null) { + // new subscription + consumerGroupConf = new ConsumerGroupConf(consumerGroup); + ConsumerGroupTopicConf consumeTopicConfig = new ConsumerGroupTopicConf(); + consumeTopicConfig.setConsumerGroup(consumerGroup); + consumeTopicConfig.setTopic(subTopic.getTopic()); + consumeTopicConfig.setSubscriptionItem(subTopic); + consumeTopicConfig.setUrls(new HashSet<>(Arrays.asList(url))); + + consumeTopicConfig.setIdcUrls(idcUrls); + + Map map = new HashMap<>(); + map.put(subTopic.getTopic(), consumeTopicConfig); + consumerGroupConf.setConsumerGroupTopicConf(map); + } else { + // already subscribed + Map map = + consumerGroupConf.getConsumerGroupTopicConf(); + if (!map.containsKey(subTopic.getTopic())) { + //If there are multiple topics, append it + ConsumerGroupTopicConf newTopicConf = new ConsumerGroupTopicConf(); + newTopicConf.setConsumerGroup(consumerGroup); + newTopicConf.setTopic(subTopic.getTopic()); + newTopicConf.setSubscriptionItem(subTopic); + newTopicConf.setUrls(new HashSet<>(Arrays.asList(url))); + newTopicConf.setIdcUrls(idcUrls); + map.put(subTopic.getTopic(), newTopicConf); + } + for (String key : map.keySet()) { + if (StringUtils.equals(subTopic.getTopic(), key)) { + ConsumerGroupTopicConf latestTopicConf = new ConsumerGroupTopicConf(); + latestTopicConf.setConsumerGroup(consumerGroup); + latestTopicConf.setTopic(subTopic.getTopic()); + latestTopicConf.setSubscriptionItem(subTopic); + latestTopicConf.setUrls(new HashSet<>(Arrays.asList(url))); + + ConsumerGroupTopicConf currentTopicConf = map.get(key); + latestTopicConf.getUrls().addAll(currentTopicConf.getUrls()); + latestTopicConf.setIdcUrls(idcUrls); + + map.put(key, latestTopicConf); + } + } + } + eventMeshHTTPServer.localConsumerGroupMapping.put(consumerGroup, consumerGroupConf); + } + + long startTime = System.currentTimeMillis(); + try { + // subscription relationship change notification + eventMeshHTTPServer.getConsumerManager().notifyConsumerManager(consumerGroup, + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup)); + + final CompleteHandler handler = new CompleteHandler() { + @Override + public void onResponse(HttpCommand httpCommand) { + try { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", httpCommand); + } + eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - request.getReqTime()); + } catch (Exception ex) { + // ignore + } + } + }; + + responseEventMeshCommand = request.createHttpCommandResponse(EventMeshRetCode.SUCCESS); + asyncContext.onComplete(responseEventMeshCommand, handler); + } catch (Exception e) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + subscribeResponseHeader, + SubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR.getErrMsg() + + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(err); + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}" + + "|bizSeqNo={}|uniqueId={}", endTime - startTime, + JsonUtils.serialize(subscribeRequestBody.getTopics()), + subscribeRequestBody.getUrl(), e); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime); + } + } + } + + @Override + public boolean rejectRequest() { + return false; + } + + private void registerClient(SubscribeRequestHeader subscribeRequestHeader, String consumerGroup, + List subscriptionItems, String url) { + for (SubscriptionItem item : subscriptionItems) { + Client client = new Client(); + client.env = subscribeRequestHeader.getEnv(); + client.idc = subscribeRequestHeader.getIdc(); + client.sys = subscribeRequestHeader.getSys(); + client.ip = subscribeRequestHeader.getIp(); + client.pid = subscribeRequestHeader.getPid(); + client.consumerGroup = consumerGroup; + client.topic = item.getTopic(); + client.url = url; + client.lastUpTime = new Date(); + + String groupTopicKey = client.consumerGroup + "@" + client.topic; + + if (eventMeshHTTPServer.localClientInfoMapping.containsKey(groupTopicKey)) { + List localClients = + eventMeshHTTPServer.localClientInfoMapping.get(groupTopicKey); + boolean isContains = false; + for (Client localClient : localClients) { + if (StringUtils.equals(localClient.url, client.url)) { + isContains = true; + localClient.lastUpTime = client.lastUpTime; + break; + } + } + if (!isContains) { + localClients.add(client); + } + } else { + List clients = new ArrayList<>(); + clients.add(client); + eventMeshHTTPServer.localClientInfoMapping.put(groupTopicKey, clients); + } + } + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/UnSubscribeProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/UnSubscribeProcessor.java new file mode 100644 index 0000000000..43eeb3835e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/UnSubscribeProcessor.java @@ -0,0 +1,310 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.body.client.UnSubscribeRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.UnSubscribeResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.protocol.http.header.client.UnSubscribeRequestHeader; +import org.apache.eventmesh.common.protocol.http.header.client.UnSubscribeResponseHeader; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class UnSubscribeProcessor implements HttpRequestProcessor { + + public Logger httpLogger = LoggerFactory.getLogger("http"); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public UnSubscribeProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) + throws Exception { + HttpCommand responseEventMeshCommand; + httpLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + UnSubscribeRequestHeader unSubscribeRequestHeader = + (UnSubscribeRequestHeader) asyncContext.getRequest().getHeader(); + UnSubscribeRequestBody unSubscribeRequestBody = + (UnSubscribeRequestBody) asyncContext.getRequest().getBody(); + + UnSubscribeResponseHeader unSubscribeResponseHeader = + UnSubscribeResponseHeader + .buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, + IPUtils.getLocalAddress(), + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC); + + //validate header + if (StringUtils.isBlank(unSubscribeRequestHeader.getIdc()) + || StringUtils.isBlank(unSubscribeRequestHeader.getPid()) + || !StringUtils.isNumeric(unSubscribeRequestHeader.getPid()) + || StringUtils.isBlank(unSubscribeRequestHeader.getSys())) { + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + unSubscribeResponseHeader, + UnSubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + + //validate body + if (StringUtils.isBlank(unSubscribeRequestBody.getUrl()) + || CollectionUtils.isEmpty(unSubscribeRequestBody.getTopics()) + || StringUtils.isBlank(unSubscribeRequestBody.getConsumerGroup())) { + + responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse( + unSubscribeResponseHeader, + UnSubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg())); + asyncContext.onComplete(responseEventMeshCommand); + return; + } + String env = unSubscribeRequestHeader.getEnv(); + String idc = unSubscribeRequestHeader.getIdc(); + String sys = unSubscribeRequestHeader.getSys(); + String ip = unSubscribeRequestHeader.getIp(); + String pid = unSubscribeRequestHeader.getPid(); + String consumerGroup = unSubscribeRequestBody.getConsumerGroup(); + String unSubscribeUrl = unSubscribeRequestBody.getUrl(); + List unSubTopicList = unSubscribeRequestBody.getTopics(); + + final CompleteHandler handler = new CompleteHandler() { + @Override + public void onResponse(HttpCommand httpCommand) { + try { + if (httpLogger.isDebugEnabled()) { + httpLogger.debug("{}", httpCommand); + } + eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - asyncContext.getRequest().getReqTime()); + } catch (Exception ex) { + // ignore + } + } + }; + + synchronized (eventMeshHTTPServer.localClientInfoMapping) { + boolean isChange = true; + + registerClient(unSubscribeRequestHeader, consumerGroup, unSubTopicList, unSubscribeUrl); + + for (String unSubTopic : unSubTopicList) { + List groupTopicClients = eventMeshHTTPServer.localClientInfoMapping + .get(consumerGroup + "@" + unSubTopic); + Iterator clientIterator = groupTopicClients.iterator(); + while (clientIterator.hasNext()) { + Client client = clientIterator.next(); + if (StringUtils.equals(client.pid, pid) + && StringUtils.equals(client.url, unSubscribeUrl)) { + httpLogger.warn("client {} start unsubscribe", JsonUtils.serialize(client)); + clientIterator.remove(); + } + } + if (groupTopicClients.size() > 0) { + //change url + Map> idcUrls = new HashMap<>(); + Set clientUrls = new HashSet<>(); + for (Client client : groupTopicClients) { + // remove subscribed url + if (!StringUtils.equals(unSubscribeUrl, client.url)) { + clientUrls.add(client.url); + if (idcUrls.containsKey(client.idc)) { + idcUrls.get(client.idc) + .add(StringUtils.deleteWhitespace(client.url)); + } else { + List urls = new ArrayList<>(); + urls.add(client.url); + idcUrls.put(client.idc, urls); + } + } + + } + synchronized (eventMeshHTTPServer.localConsumerGroupMapping) { + ConsumerGroupConf consumerGroupConf = + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup); + Map map = + consumerGroupConf.getConsumerGroupTopicConf(); + for (String topicKey : map.keySet()) { + // only modify the topic to subscribe + if (StringUtils.equals(unSubTopic, topicKey)) { + ConsumerGroupTopicConf latestTopicConf = + new ConsumerGroupTopicConf(); + latestTopicConf.setConsumerGroup(consumerGroup); + latestTopicConf.setTopic(unSubTopic); + latestTopicConf + .setSubscriptionItem(map.get(topicKey).getSubscriptionItem()); + latestTopicConf.setUrls(clientUrls); + + latestTopicConf.setIdcUrls(idcUrls); + + map.put(unSubTopic, latestTopicConf); + } + } + eventMeshHTTPServer.localConsumerGroupMapping + .put(consumerGroup, consumerGroupConf); + } + } else { + isChange = false; + break; + } + } + long startTime = System.currentTimeMillis(); + if (isChange) { + try { + eventMeshHTTPServer.getConsumerManager().notifyConsumerManager(consumerGroup, + eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup)); + + responseEventMeshCommand = + asyncContext.getRequest().createHttpCommandResponse(EventMeshRetCode.SUCCESS); + asyncContext.onComplete(responseEventMeshCommand, handler); + + } catch (Exception e) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + unSubscribeResponseHeader, + UnSubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getErrMsg() + + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(err); + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + + "|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, + JsonUtils.serialize(unSubscribeRequestBody.getTopics()), + unSubscribeRequestBody.getUrl(), e); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics() + .recordSendMsgCost(endTime - startTime); + } + } else { + //remove + try { + eventMeshHTTPServer.getConsumerManager() + .notifyConsumerManager(consumerGroup, null); + responseEventMeshCommand = + asyncContext.getRequest().createHttpCommandResponse(EventMeshRetCode.SUCCESS); + asyncContext.onComplete(responseEventMeshCommand, handler); + // clean ClientInfo + eventMeshHTTPServer.localClientInfoMapping.keySet() + .removeIf(s -> StringUtils.contains(s, consumerGroup)); + // clean ConsumerGroupInfo + eventMeshHTTPServer.localConsumerGroupMapping.keySet() + .removeIf(s -> StringUtils.equals(consumerGroup, s)); + } catch (Exception e) { + HttpCommand err = asyncContext.getRequest().createHttpCommandResponse( + unSubscribeResponseHeader, + UnSubscribeResponseBody + .buildBody(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getRetCode(), + EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getErrMsg() + + EventMeshUtil.stackTrace(e, 2))); + asyncContext.onComplete(err); + long endTime = System.currentTimeMillis(); + httpLogger.error( + "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + + "|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, + JsonUtils.serialize(unSubscribeRequestBody.getTopics()), + unSubscribeRequestBody.getUrl(), e); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime); + } + } + } + } + + @Override + public boolean rejectRequest() { + return false; + } + + private void registerClient(UnSubscribeRequestHeader unSubscribeRequestHeader, + String consumerGroup, + List topicList, String url) { + for (String topic : topicList) { + Client client = new Client(); + client.env = unSubscribeRequestHeader.getEnv(); + client.idc = unSubscribeRequestHeader.getIdc(); + client.sys = unSubscribeRequestHeader.getSys(); + client.ip = unSubscribeRequestHeader.getIp(); + client.pid = unSubscribeRequestHeader.getPid(); + client.consumerGroup = consumerGroup; + client.topic = topic; + client.url = url; + client.lastUpTime = new Date(); + + String groupTopicKey = client.consumerGroup + "@" + client.topic; + if (eventMeshHTTPServer.localClientInfoMapping.containsKey(groupTopicKey)) { + List localClients = + eventMeshHTTPServer.localClientInfoMapping.get(groupTopicKey); + boolean isContains = false; + for (Client localClient : localClients) { + if (StringUtils.equals(localClient.url, client.url)) { + isContains = true; + localClient.lastUpTime = client.lastUpTime; + break; + } + } + if (!isContains) { + localClients.add(client); + } + } else { + List clients = new ArrayList<>(); + clients.add(client); + eventMeshHTTPServer.localClientInfoMapping.put(groupTopicKey, clients); + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/WebHookProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/WebHookProcessor.java new file mode 100644 index 0000000000..2bc878fa79 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/WebHookProcessor.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor; + +import org.apache.eventmesh.runtime.common.EventMeshTrace; +import org.apache.eventmesh.runtime.util.HttpResponseUtils; +import org.apache.eventmesh.webhook.receive.WebHookController; + +import java.util.HashMap; +import java.util.Map; + +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; + +import lombok.Setter; + +@EventMeshTrace(isEnable = true) +public class WebHookProcessor implements HttpProcessor { + + @Setter + private WebHookController webHookController; + + @Override + public String[] paths() { + return new String[]{"/webhook"}; + } + + @Override + public HttpResponse handler(HttpRequest httpRequest) { + try { + Map header = new HashMap<>(); + for (Map.Entry entry : httpRequest.headers().entries()) { + header.put(entry.getKey().toLowerCase(), entry.getValue()); + } + byte[] bytes = ((DefaultFullHttpRequest) httpRequest).content().array(); + webHookController.execute(httpRequest.uri(), header, bytes); + return HttpResponseUtils.createSuccess(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/AbstractEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/AbstractEventProcessor.java new file mode 100644 index 0000000000..2fe7f25bad --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/AbstractEventProcessor.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor.inf; + +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.registry.nacos.constant.NacosConstant; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupMetadata; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicMetadata; +import org.apache.eventmesh.runtime.registry.Registry; + +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * EventProcessor + */ +public class AbstractEventProcessor { + + private static final Logger LOGGER = LoggerFactory.getLogger("AbstractEventProcessor"); + + protected EventMeshHTTPServer eventMeshHTTPServer; + + public AbstractEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + /** + * Add a topic with subscribers to the service's metadata. + */ + protected void updateMetadata() { + if (!eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerRegistryEnable) { + return; + } + try { + Map metadata = new HashMap<>(1 << 4); + for (Map.Entry consumerGroupMap : eventMeshHTTPServer.localConsumerGroupMapping.entrySet()) { + String consumerGroupKey = consumerGroupMap.getKey(); + ConsumerGroupConf consumerGroupConf = consumerGroupMap.getValue(); + + ConsumerGroupMetadata consumerGroupMetadata = new ConsumerGroupMetadata(); + consumerGroupMetadata.setConsumerGroup(consumerGroupKey); + + Map consumerGroupTopicMetadataMap = new HashMap<>(1 << 4); + for (Map.Entry consumerGroupTopicConfEntry : consumerGroupConf.getConsumerGroupTopicConf() + .entrySet()) { + final String topic = consumerGroupTopicConfEntry.getKey(); + ConsumerGroupTopicConf consumerGroupTopicConf = consumerGroupTopicConfEntry.getValue(); + ConsumerGroupTopicMetadata consumerGroupTopicMetadata = new ConsumerGroupTopicMetadata(); + consumerGroupTopicMetadata.setConsumerGroup(consumerGroupTopicConf.getConsumerGroup()); + consumerGroupTopicMetadata.setTopic(consumerGroupTopicConf.getTopic()); + consumerGroupTopicMetadata.setUrls(consumerGroupTopicConf.getUrls()); + + consumerGroupTopicMetadataMap.put(topic, consumerGroupTopicMetadata); + } + consumerGroupMetadata.setConsumerGroupTopicMetadataMap(consumerGroupTopicMetadataMap); + metadata.put(consumerGroupKey, JsonUtils.serialize(consumerGroupMetadata)); + } + Registry registry = eventMeshHTTPServer.getRegistry(); + registry.registerMetadata(metadata); + } catch (Exception e) { + LOGGER.error("[LocalSubscribeEventProcessor] update eventmesh metadata error", e); + } + } + + + protected String getTargetMesh(String consumerGroup, List subscriptionList) + throws Exception { + // Currently only supports http + CommonConfiguration httpConfiguration = eventMeshHTTPServer.getEventMeshHttpConfiguration(); + if (!httpConfiguration.eventMeshServerRegistryEnable) { + return ""; + } + + String targetMesh = ""; + Registry registry = eventMeshHTTPServer.getRegistry(); + List allEventMeshInfo = registry.findAllEventMeshInfo(); + String httpServiceName = + ConfigurationContextUtil.HTTP + "-" + NacosConstant.GROUP + "@@" + httpConfiguration.eventMeshName + "-" + ConfigurationContextUtil.HTTP; + for (EventMeshDataInfo eventMeshDataInfo : allEventMeshInfo) { + if (!eventMeshDataInfo.getEventMeshName().equals(httpServiceName)) { + continue; + } + if (httpConfiguration.eventMeshCluster.equals(eventMeshDataInfo.getEventMeshClusterName())) { + continue; + } + Map metadata = eventMeshDataInfo.getMetadata(); + String topicMetadataJson = metadata.get(consumerGroup); + if (StringUtils.isBlank(topicMetadataJson)) { + continue; + } + + ConsumerGroupMetadata consumerGroupMetadata = JsonUtils.deserialize(topicMetadataJson, ConsumerGroupMetadata.class); + Map consumerGroupTopicMetadataMap = consumerGroupMetadata.getConsumerGroupTopicMetadataMap(); + + for (SubscriptionItem subscriptionItem : subscriptionList) { + if (consumerGroupTopicMetadataMap.containsKey(subscriptionItem.getTopic())) { + targetMesh = "http://" + eventMeshDataInfo.getEndpoint() + "/eventmesh/subscribe/local"; + break; + } + } + break; + } + return targetMesh; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/Client.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/Client.java new file mode 100644 index 0000000000..119c1dea2e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/Client.java @@ -0,0 +1,65 @@ +/* + * Licensed to Apache Software Foundation (ASF) under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor.inf; + +import java.util.Date; + +public class Client { + + public String env; + + public String idc; + + public String consumerGroup; + + public String topic; + + public String url; + + public String sys; + + public String ip; + + public String pid; + + public String hostname; + + public String apiVersion; + + public Date lastUpTime; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("endPoint={env=").append(env) + .append(",idc=").append(idc) + .append(",consumerGroup=").append(consumerGroup) + .append(",topic=").append(topic) + .append(",url=").append(url) + .append(",sys=").append(sys) + .append(",ip=").append(ip) + .append(",pid=").append(pid) + .append(",hostname=").append(hostname) + .append(",apiVersion=").append(apiVersion) + .append(",registerTime=").append("}"); + return sb.toString(); + } +} + diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/EventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/EventProcessor.java new file mode 100644 index 0000000000..ea9be37c36 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/EventProcessor.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor.inf; + +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; + +import io.netty.channel.ChannelHandlerContext; + +/** + * EventProcessor + */ +public interface EventProcessor { + + void processRequest(final ChannelHandlerContext ctx, final AsyncContext asyncContext) + throws Exception; + + boolean rejectRequest(); + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/HttpRequestProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/HttpRequestProcessor.java new file mode 100644 index 0000000000..41354f44c3 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/inf/HttpRequestProcessor.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.processor.inf; + +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext; + +import io.netty.channel.ChannelHandlerContext; + +/** + * HttpRequestProcessor + */ +public interface HttpRequestProcessor { + + void processRequest(final ChannelHandlerContext ctx, final AsyncContext asyncContext) + throws Exception; + + boolean rejectRequest(); + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/EventMeshProducer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/EventMeshProducer.java new file mode 100644 index 0000000000..ff488d3fbc --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/EventMeshProducer.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.producer; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; +import org.apache.eventmesh.runtime.core.consumergroup.ProducerGroupConf; +import org.apache.eventmesh.runtime.core.plugin.MQProducerWrapper; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventMeshProducer { + + protected AtomicBoolean started = new AtomicBoolean(Boolean.FALSE); + + protected AtomicBoolean inited = new AtomicBoolean(Boolean.FALSE); + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + public AtomicBoolean getInited() { + return inited; + } + + public AtomicBoolean getStarted() { + return started; + } + + protected ProducerGroupConf producerGroupConfig; + + protected EventMeshHTTPConfiguration eventMeshHttpConfiguration; + + public void send(SendMessageContext sendMsgContext, SendCallback sendCallback) throws Exception { + mqProducerWrapper.send(sendMsgContext.getEvent(), sendCallback); + } + + public void request(SendMessageContext sendMsgContext, RequestReplyCallback rrCallback, long timeout) + throws Exception { + mqProducerWrapper.request(sendMsgContext.getEvent(), rrCallback, timeout); + } + + public boolean reply(final SendMessageContext sendMsgContext, final SendCallback sendCallback) throws Exception { + mqProducerWrapper.reply(sendMsgContext.getEvent(), sendCallback); + return true; + } + + protected MQProducerWrapper mqProducerWrapper; + + public MQProducerWrapper getMqProducerWrapper() { + return mqProducerWrapper; + } + + public synchronized void init(EventMeshHTTPConfiguration eventMeshHttpConfiguration, + ProducerGroupConf producerGroupConfig) throws Exception { + this.producerGroupConfig = producerGroupConfig; + this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; + + Properties keyValue = new Properties(); + keyValue.put("producerGroup", producerGroupConfig.getGroupName()); + keyValue.put("instanceName", EventMeshUtil.buildMeshClientID(producerGroupConfig.getGroupName(), + eventMeshHttpConfiguration.eventMeshCluster)); + + //TODO for defibus + keyValue.put("eventMeshIDC", eventMeshHttpConfiguration.eventMeshIDC); + mqProducerWrapper = new MQProducerWrapper(eventMeshHttpConfiguration.eventMeshConnectorPluginType); + mqProducerWrapper.init(keyValue); + inited.compareAndSet(false, true); + logger.info("EventMeshProducer [{}] inited.............", producerGroupConfig.getGroupName()); + } + + + public synchronized void start() throws Exception { + if (started.get()) { + return; + } + + mqProducerWrapper.start(); + started.compareAndSet(false, true); + logger.info("EventMeshProducer [{}] started.............", producerGroupConfig.getGroupName()); + } + + public synchronized void shutdown() throws Exception { + if (!inited.get()) { + return; + } + + if (!started.get()) { + return; + } + mqProducerWrapper.shutdown(); + inited.compareAndSet(true, false); + started.compareAndSet(true, false); + logger.info("EventMeshProducer [{}] shutdown.............", producerGroupConfig.getGroupName()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("eventMeshProducer={") + .append("inited=").append(inited.get()).append(",") + .append("started=").append(started.get()).append(",") + .append("producerGroupConfig=").append(producerGroupConfig).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/ProducerManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/ProducerManager.java new file mode 100644 index 0000000000..ebf65b4e50 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/ProducerManager.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.producer; + +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.core.consumergroup.ProducerGroupConf; + +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProducerManager { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private EventMeshHTTPServer eventMeshHTTPServer; + + private ConcurrentHashMap producerTable = new ConcurrentHashMap(); + + public ProducerManager(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + public void init() throws Exception { + logger.info("producerManager inited......"); + } + + public void start() throws Exception { + logger.info("producerManager started......"); + } + + public EventMeshProducer getEventMeshProducer(String producerGroup) throws Exception { + EventMeshProducer eventMeshProducer = null; + if (!producerTable.containsKey(producerGroup)) { + synchronized (producerTable) { + if (!producerTable.containsKey(producerGroup)) { + ProducerGroupConf producerGroupConfig = new ProducerGroupConf(producerGroup); + eventMeshProducer = createEventMeshProducer(producerGroupConfig); + eventMeshProducer.start(); + } + } + } + + eventMeshProducer = producerTable.get(producerGroup); + + if (!eventMeshProducer.getStarted().get()) { + eventMeshProducer.start(); + } + + return eventMeshProducer; + } + + public synchronized EventMeshProducer createEventMeshProducer(ProducerGroupConf producerGroupConfig) throws Exception { + if (producerTable.containsKey(producerGroupConfig.getGroupName())) { + return producerTable.get(producerGroupConfig.getGroupName()); + } + EventMeshProducer eventMeshProducer = new EventMeshProducer(); + eventMeshProducer.init(eventMeshHTTPServer.getEventMeshHttpConfiguration(), producerGroupConfig); + producerTable.put(producerGroupConfig.getGroupName(), eventMeshProducer); + return eventMeshProducer; + } + + public void shutdown() { + for (EventMeshProducer eventMeshProducer : producerTable.values()) { + try { + eventMeshProducer.shutdown(); + } catch (Exception ex) { + logger.error("shutdown eventMeshProducer[{}] err", eventMeshProducer, ex); + } + } + logger.info("producerManager shutdown......"); + } + + public EventMeshHTTPServer getEventMeshHTTPServer() { + return eventMeshHTTPServer; + } + + public ConcurrentHashMap getProducerTable() { + return producerTable; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/SendMessageContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/SendMessageContext.java new file mode 100644 index 0000000000..054e283c50 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/SendMessageContext.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.producer; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.core.protocol.http.retry.RetryContext; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class SendMessageContext extends RetryContext { + + public static Logger logger = LoggerFactory.getLogger("retry"); + + private CloudEvent event; + + private String bizSeqNo; + + private EventMeshProducer eventMeshProducer; + + private long createTime = System.currentTimeMillis(); + + private Map props; + + public EventMeshHTTPServer eventMeshHTTPServer; + + private List eventList; + + public SendMessageContext(String bizSeqNo, CloudEvent event, EventMeshProducer eventMeshProducer, EventMeshHTTPServer eventMeshHTTPServer) { + this.bizSeqNo = bizSeqNo; + this.event = event; + this.eventMeshProducer = eventMeshProducer; + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + public void addProp(String key, String val) { + if (props == null) { + props = new HashMap<>(); + } + props.put(key, val); + } + + public String getProp(String key) { + return props.get(key); + } + + public String getBizSeqNo() { + return bizSeqNo; + } + + public void setBizSeqNo(String bizSeqNo) { + this.bizSeqNo = bizSeqNo; + } + + public CloudEvent getEvent() { + return event; + } + + public void setEvent(CloudEvent event) { + this.event = event; + } + + public EventMeshProducer getEventMeshProducer() { + return eventMeshProducer; + } + + public void setEventMeshProducer(EventMeshProducer eventMeshProducer) { + this.eventMeshProducer = eventMeshProducer; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public List getEventList() { + return eventList; + } + + public void setEventList(List eventList) { + this.eventList = eventList; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("sendMessageContext={") + .append("bizSeqNo=").append(bizSeqNo) + .append(",retryTimes=").append(retryTimes) + .append(",producer=").append(eventMeshProducer != null ? eventMeshProducer.producerGroupConfig.getGroupName() : null) + .append(",executeTime=").append(DateFormatUtils.format(executeTime, Constants.DATE_FORMAT)) + .append(",createTime=").append(DateFormatUtils.format(createTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + @Override + public boolean retry() throws Exception { + if (eventMeshProducer == null) { + return false; + } + + if (retryTimes > 0) { //retry once + return false; + } + + retryTimes++; + eventMeshProducer.send(this, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + } + + @Override + public void onException(OnExceptionContext context) { + logger.warn("", context.getException()); + eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsgFailed(1); + } + + }); + + return true; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/AbstractHTTPPushRequest.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/AbstractHTTPPushRequest.java new file mode 100644 index 0000000000..1f7c3a5f61 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/AbstractHTTPPushRequest.java @@ -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 org.apache.eventmesh.runtime.core.protocol.http.push; + +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.HandleMsgContext; +import org.apache.eventmesh.runtime.core.protocol.http.retry.HttpRetryer; +import org.apache.eventmesh.runtime.core.protocol.http.retry.RetryContext; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.RandomUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.google.common.collect.Lists; + +public abstract class AbstractHTTPPushRequest extends RetryContext { + + public EventMeshHTTPServer eventMeshHTTPServer; + + public long createTime = System.currentTimeMillis(); + + public long lastPushTime = System.currentTimeMillis(); + + public Map> urls; + + public List totalUrls; + + public volatile int startIdx; + + public EventMeshHTTPConfiguration eventMeshHttpConfiguration; + + public HttpRetryer retryer; + + public int ttl; + + public HandleMsgContext handleMsgContext; + + private AtomicBoolean complete = new AtomicBoolean(Boolean.FALSE); + + public AbstractHTTPPushRequest(HandleMsgContext handleMsgContext) { + this.eventMeshHTTPServer = handleMsgContext.getEventMeshHTTPServer(); + this.handleMsgContext = handleMsgContext; + this.urls = handleMsgContext.getConsumeTopicConfig().getIdcUrls(); + this.totalUrls = Lists.newArrayList(handleMsgContext.getConsumeTopicConfig().getUrls()); + this.eventMeshHttpConfiguration = handleMsgContext.getEventMeshHTTPServer().getEventMeshHttpConfiguration(); + this.retryer = handleMsgContext.getEventMeshHTTPServer().getHttpRetryer(); + this.ttl = handleMsgContext.getTtl(); + this.startIdx = RandomUtils.nextInt(0, totalUrls.size()); + } + + public void tryHTTPRequest() { + } + + public void delayRetry(long delayTime) { + if (retryTimes < EventMeshConstants.DEFAULT_PUSH_RETRY_TIMES && delayTime > 0) { + retryTimes++; + delay(delayTime); + retryer.pushRetry(this); + } else { + complete.compareAndSet(Boolean.FALSE, Boolean.TRUE); + } + } + + public void delayRetry() { + if (retryTimes < EventMeshConstants.DEFAULT_PUSH_RETRY_TIMES) { + retryTimes++; + delay(retryTimes * EventMeshConstants.DEFAULT_PUSH_RETRY_TIME_DISTANCE_IN_MILLSECONDS); + retryer.pushRetry(this); + } else { + complete.compareAndSet(Boolean.FALSE, Boolean.TRUE); + } + } + + public String getUrl() { + List localIDCUrl = MapUtils.getObject(urls, + eventMeshHttpConfiguration.eventMeshIDC, null); + if (CollectionUtils.isNotEmpty(localIDCUrl)) { + return localIDCUrl.get((startIdx + retryTimes) % localIDCUrl.size()); + } + + List otherIDCUrl = new ArrayList(); + for (List tmp : urls.values()) { + otherIDCUrl.addAll(tmp); + } + + if (CollectionUtils.isNotEmpty(otherIDCUrl)) { + return otherIDCUrl.get((startIdx + retryTimes) % otherIDCUrl.size()); + } + + return null; + } + + public boolean isComplete() { + return complete.get(); + } + + public void complete() { + complete.compareAndSet(Boolean.FALSE, Boolean.TRUE); + } + + public void timeout() { + if (!isComplete() && System.currentTimeMillis() - lastPushTime >= ttl) { + delayRetry(); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/AsyncHTTPPushRequest.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/AsyncHTTPPushRequest.java new file mode 100644 index 0000000000..5abc9932d1 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/AsyncHTTPPushRequest.java @@ -0,0 +1,371 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.push; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.exception.JsonException; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.http.HttpCommand; +import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; +import org.apache.eventmesh.common.protocol.http.body.message.PushMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.common.ClientRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.HandleMsgContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.WebhookUtil; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.collect.Sets; + +public class AsyncHTTPPushRequest extends AbstractHTTPPushRequest { + + public Logger messageLogger = LoggerFactory.getLogger("message"); + + public Logger cmdLogger = LoggerFactory.getLogger("cmd"); + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + public String currPushUrl; + private Map> waitingRequests; + + public AsyncHTTPPushRequest(HandleMsgContext handleMsgContext, + Map> waitingRequests) { + super(handleMsgContext); + this.waitingRequests = waitingRequests; + } + + @Override + public void tryHTTPRequest() { + + currPushUrl = getUrl(); + + if (StringUtils.isBlank(currPushUrl)) { + return; + } + + HttpPost builder = new HttpPost(currPushUrl); + + String requestCode = ""; + + if (SubscriptionType.SYNC.equals(handleMsgContext.getSubscriptionItem().getType())) { + requestCode = String.valueOf(RequestCode.HTTP_PUSH_CLIENT_SYNC.getRequestCode()); + } else { + requestCode = String.valueOf(RequestCode.HTTP_PUSH_CLIENT_ASYNC.getRequestCode()); + } + + builder.addHeader(ProtocolKey.REQUEST_CODE, requestCode); + builder.addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA); + builder.addHeader(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, + handleMsgContext.getEventMeshHTTPServer() + .getEventMeshHttpConfiguration().eventMeshCluster); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, IPUtils.getLocalAddress()); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, + handleMsgContext.getEventMeshHTTPServer().getEventMeshHttpConfiguration().eventMeshEnv); + builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, + handleMsgContext.getEventMeshHTTPServer().getEventMeshHttpConfiguration().eventMeshIDC); + + CloudEvent event = CloudEventBuilder.from(handleMsgContext.getEvent()) + .withExtension(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.RSP_URL, currPushUrl) + .withExtension(EventMeshConstants.RSP_GROUP, handleMsgContext.getConsumerGroup()) + .build(); + handleMsgContext.setEvent(event); + + String content = ""; + try { + String protocolType = Objects.requireNonNull(event.getExtension(Constants.PROTOCOL_TYPE)).toString(); + + ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + + ProtocolTransportObject protocolTransportObject = + protocolAdaptor.fromCloudEvent(handleMsgContext.getEvent()); + if (protocolTransportObject instanceof HttpCommand) { + content = ((HttpCommand) protocolTransportObject).getBody().toMap().get("content").toString(); + } else { + HttpEventWrapper httpEventWrapper = (HttpEventWrapper) protocolTransportObject; + Map sysHeaderMap = httpEventWrapper.getSysHeaderMap(); + content = new String(httpEventWrapper.getBody(), StandardCharsets.UTF_8); + for (String header : sysHeaderMap.keySet()) { + if (!builder.containsHeader(header)) { + builder.addHeader(header, sysHeaderMap.get(header).toString()); + } + } + } + + } catch (Exception ex) { + return; + } + + List body = new ArrayList<>(); + body.add(new BasicNameValuePair(PushMessageRequestBody.CONTENT, content)); + if (StringUtils.isBlank(handleMsgContext.getBizSeqNo())) { + body.add(new BasicNameValuePair(PushMessageRequestBody.BIZSEQNO, + RandomStringUtils.generateNum(20))); + } else { + body.add(new BasicNameValuePair(PushMessageRequestBody.BIZSEQNO, + handleMsgContext.getBizSeqNo())); + } + if (StringUtils.isBlank(handleMsgContext.getUniqueId())) { + body.add(new BasicNameValuePair(PushMessageRequestBody.UNIQUEID, + RandomStringUtils.generateNum(20))); + } else { + body.add(new BasicNameValuePair(PushMessageRequestBody.UNIQUEID, + handleMsgContext.getUniqueId())); + } + + body.add(new BasicNameValuePair(PushMessageRequestBody.RANDOMNO, + handleMsgContext.getMsgRandomNo())); + body.add(new BasicNameValuePair(PushMessageRequestBody.TOPIC, handleMsgContext.getTopic())); + + body.add(new BasicNameValuePair(PushMessageRequestBody.EXTFIELDS, + JsonUtils.serialize(EventMeshUtil.getEventProp(handleMsgContext.getEvent())))); + + HttpEntity httpEntity = new UrlEncodedFormEntity(body, StandardCharsets.UTF_8); + + builder.setEntity(httpEntity); + + // for CloudEvents Webhook spec + String urlAuthType = handleMsgContext.getConsumerGroupConfig().getConsumerGroupTopicConf() + .get(handleMsgContext.getTopic()).getHttpAuthTypeMap().get(currPushUrl); + + WebhookUtil.setWebhookHeaders(builder, httpEntity.getContentType().getValue(), eventMeshHttpConfiguration.eventMeshWebhookOrigin, + urlAuthType); + + eventMeshHTTPServer.metrics.getSummaryMetrics().recordPushMsg(); + + this.lastPushTime = System.currentTimeMillis(); + + addToWaitingMap(this); + + cmdLogger.info("cmd={}|eventMesh2client|from={}|to={}", requestCode, + IPUtils.getLocalAddress(), currPushUrl); + + try { + eventMeshHTTPServer.httpClientPool.getClient().execute(builder, new ResponseHandler() { + @Override + public Object handleResponse(HttpResponse response) { + removeWaitingMap(AsyncHTTPPushRequest.this); + long cost = System.currentTimeMillis() - lastPushTime; + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPPushTimeCost(cost); + + if (processResponseStatus(response.getStatusLine().getStatusCode(), response)) { + // this is successful response, process response payload + String res = ""; + try { + res = EntityUtils.toString(response.getEntity(), + Charset.forName(EventMeshConstants.DEFAULT_CHARSET)); + } catch (IOException e) { + handleMsgContext.finish(); + return new Object(); + } + ClientRetCode result = processResponseContent(res); + messageLogger.info( + "message|eventMesh2client|{}|url={}|topic={}|bizSeqNo={}" + + "|uniqueId={}|cost={}", + result, currPushUrl, handleMsgContext.getTopic(), + handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), cost); + if (result == ClientRetCode.OK || result == ClientRetCode.REMOTE_OK) { + complete(); + if (isComplete()) { + handleMsgContext.finish(); + } + } else if (result == ClientRetCode.RETRY) { + delayRetry(); + if (isComplete()) { + handleMsgContext.finish(); + } + } else if (result == ClientRetCode.NOLISTEN) { + delayRetry(); + if (isComplete()) { + handleMsgContext.finish(); + } + } else if (result == ClientRetCode.FAIL) { + complete(); + if (isComplete()) { + handleMsgContext.finish(); + } + } + } else { + eventMeshHTTPServer.metrics.getSummaryMetrics().recordHttpPushMsgFailed(); + messageLogger.info( + "message|eventMesh2client|exception|url={}|topic={}|bizSeqNo={}" + + "|uniqueId={}|cost={}", currPushUrl, handleMsgContext.getTopic(), + handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), cost); + + if (isComplete()) { + handleMsgContext.finish(); + } + } + return new Object(); + } + }); + + if (messageLogger.isDebugEnabled()) { + messageLogger.debug("message|eventMesh2client|url={}|topic={}|event={}", currPushUrl, + handleMsgContext.getTopic(), + handleMsgContext.getEvent()); + } else { + messageLogger + .info("message|eventMesh2client|url={}|topic={}|bizSeqNo={}|uniqueId={}", + currPushUrl, handleMsgContext.getTopic(), + handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId()); + } + } catch (IOException e) { + messageLogger.error("push2client err", e); + removeWaitingMap(this); + delayRetry(); + if (isComplete()) { + handleMsgContext.finish(); + } + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("asyncPushRequest={") + .append("bizSeqNo=").append(handleMsgContext.getBizSeqNo()) + .append(",startIdx=").append(startIdx) + .append(",retryTimes=").append(retryTimes) + .append(",uniqueId=").append(handleMsgContext.getUniqueId()) + .append(",executeTime=") + .append(DateFormatUtils.format(executeTime, Constants.DATE_FORMAT)) + .append(",lastPushTime=") + .append(DateFormatUtils.format(lastPushTime, Constants.DATE_FORMAT)) + .append(",createTime=") + .append(DateFormatUtils.format(createTime, Constants.DATE_FORMAT)).append("}"); + return sb.toString(); + } + + boolean processResponseStatus(int httpStatus, HttpResponse httpResponse) { + if (httpStatus == HttpStatus.SC_OK || httpStatus == HttpStatus.SC_CREATED + || httpStatus == HttpStatus.SC_NO_CONTENT || httpStatus == HttpStatus.SC_ACCEPTED) { + // success http response + return true; + } else if (httpStatus == 429) { + // failed with customer retry interval + + // Response Status code is 429 Too Many Requests + // retry after the time specified by the header + Optional
optHeader = Arrays.stream(httpResponse.getHeaders("Retry-After")).findAny(); + if (optHeader.isPresent() && StringUtils.isNumeric(optHeader.get().getValue())) { + delayRetry(Long.parseLong(optHeader.get().getValue())); + } + return false; + } else if (httpStatus == HttpStatus.SC_GONE || httpStatus == HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE) { + // failed with no retry + return false; + } + + // failed with default retry + delayRetry(); + return false; + } + + ClientRetCode processResponseContent(String content) { + if (StringUtils.isBlank(content)) { + return ClientRetCode.FAIL; + } + + try { + Map ret = + JsonUtils.deserialize(content, new TypeReference>() { + }); + Integer retCode = (Integer) ret.get("retCode"); + if (retCode != null && ClientRetCode.contains(retCode)) { + return ClientRetCode.get(retCode); + } + + return ClientRetCode.FAIL; + } catch (NumberFormatException e) { + messageLogger.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", currPushUrl, + handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), content); + return ClientRetCode.FAIL; + } catch (JsonException e) { + messageLogger.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", currPushUrl, + handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), content); + return ClientRetCode.FAIL; + } catch (Throwable t) { + messageLogger.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", currPushUrl, + handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), content); + return ClientRetCode.FAIL; + } + } + + private void addToWaitingMap(AsyncHTTPPushRequest request) { + if (waitingRequests.containsKey(request.handleMsgContext.getConsumerGroup())) { + waitingRequests.get(request.handleMsgContext.getConsumerGroup()).add(request); + return; + } + waitingRequests + .put(request.handleMsgContext.getConsumerGroup(), Sets.newConcurrentHashSet()); + waitingRequests.get(request.handleMsgContext.getConsumerGroup()).add(request); + } + + private void removeWaitingMap(AsyncHTTPPushRequest request) { + if (waitingRequests.containsKey(request.handleMsgContext.getConsumerGroup())) { + waitingRequests.get(request.handleMsgContext.getConsumerGroup()).remove(request); + } + } + + @Override + public boolean retry() { + tryHTTPRequest(); + return true; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/HTTPClientPool.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/HTTPClientPool.java new file mode 100644 index 0000000000..b54ec70f77 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/HTTPClientPool.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.push; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.RandomUtils; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.DefaultConnectionReuseStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; +import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; + +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HTTPClientPool { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private List clients = Collections.synchronizedList(new ArrayList<>()); + + private int core = 1; + + public HTTPClientPool(int core) { + this.core = core; + } + + public CloseableHttpClient getClient() { + if (CollectionUtils.size(clients) < core) { + CloseableHttpClient client = getHttpClient(200, 30, null); + clients.add(client); + return client; + } + return clients.get(RandomUtils.nextInt(core, 2 * core) % core); + } + + public void shutdown() throws Exception { + Iterator itr = clients.iterator(); + while (itr.hasNext()) { + CloseableHttpClient client = itr.next(); + client.close(); + itr.remove(); + } + } + + @SuppressWarnings("deprecation") + public CloseableHttpClient getHttpClient(int maxTotal, int idleTimeInSeconds, SSLContext sslContext) { + try { + if (sslContext == null) { + sslContext = SSLContexts.custom().loadTrustMaterial(new TheTrustStrategy()).build(); + } + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { + logger.error("Get sslContext error: {}", e.getMessage()); + return HttpClients.createDefault(); + } + + HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; + + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); + Registry socketFactoryRegistry + = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", sslsf).build(); + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + + connectionManager.setDefaultMaxPerRoute(maxTotal); + connectionManager.setMaxTotal(maxTotal); + return HttpClients.custom() + .setConnectionManager(connectionManager) + .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) + .evictIdleConnections(idleTimeInSeconds, TimeUnit.SECONDS) + .setConnectionReuseStrategy(new DefaultConnectionReuseStrategy()) + .setRetryHandler(new DefaultHttpRequestRetryHandler()) + .build(); + } + + public static class TheTrustStrategy implements TrustStrategy { + @Override + public boolean isTrusted(X509Certificate[] arg0, String arg1) { + return true; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/HTTPMessageHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/HTTPMessageHandler.java new file mode 100644 index 0000000000..166ddca928 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/HTTPMessageHandler.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.push; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.EventMeshConsumer; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.HandleMsgContext; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.collections4.MapUtils; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.opentelemetry.api.trace.Span; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class HTTPMessageHandler implements MessageHandler { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private EventMeshConsumer eventMeshConsumer; + + private static final ScheduledExecutorService SCHEDULER = ThreadPoolFactory.createSingleScheduledExecutor("eventMesh-pushMsgTimeout-"); + + private ThreadPoolExecutor pushExecutor; + + private static final Integer CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD = 10000; + + private void checkTimeout() { + waitingRequests.entrySet().stream().forEach(entry -> { + for (AbstractHTTPPushRequest request : entry.getValue()) { + request.timeout(); + waitingRequests.get(request.handleMsgContext.getConsumerGroup()).remove(request); + } + }); + } + + public static Map> waitingRequests = Maps.newConcurrentMap(); + + public HTTPMessageHandler(EventMeshConsumer eventMeshConsumer) { + this.eventMeshConsumer = eventMeshConsumer; + this.pushExecutor = eventMeshConsumer.getEventMeshHTTPServer().pushMsgExecutor; + waitingRequests.put(this.eventMeshConsumer.getConsumerGroupConf().getConsumerGroup(), Sets.newConcurrentHashSet()); + SCHEDULER.scheduleAtFixedRate(this::checkTimeout, 0, 1000, TimeUnit.MILLISECONDS); + } + + @Override + public boolean handle(final HandleMsgContext handleMsgContext) { + Set waitingRequests4Group = MapUtils.getObject(waitingRequests, + handleMsgContext.getConsumerGroup(), Sets.newConcurrentHashSet()); + if (waitingRequests4Group.size() > CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD) { + logger.warn("waitingRequests is too many, so reject, this message will be send back to MQ, consumerGroup:{}, threshold:{}", + handleMsgContext.getConsumerGroup(), CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD); + return false; + } + + try { + pushExecutor.submit(() -> { + String protocolVersion = Objects.requireNonNull(handleMsgContext.getEvent().getSpecVersion()).toString(); + + Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, handleMsgContext.getEvent()), + EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_CLIENT_SPAN, false); + + try { + AsyncHTTPPushRequest asyncPushRequest = new AsyncHTTPPushRequest(handleMsgContext, waitingRequests); + asyncPushRequest.tryHTTPRequest(); + } finally { + TraceUtils.finishSpan(span, handleMsgContext.getEvent()); + } + + }); + return true; + } catch (RejectedExecutionException e) { + logger.warn("pushMsgThreadPoolQueue is full, so reject, current task size {}", + handleMsgContext.getEventMeshHTTPServer().getPushMsgExecutor().getQueue().size(), e); + return false; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/MessageHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/MessageHandler.java new file mode 100644 index 0000000000..bf29c0e5ed --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/push/MessageHandler.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.push; + +import org.apache.eventmesh.runtime.core.protocol.http.consumer.HandleMsgContext; + +/** + * MessageHandler + */ +public interface MessageHandler { + boolean handle(HandleMsgContext handleMsgContext); +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/DelayRetryable.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/DelayRetryable.java new file mode 100644 index 0000000000..f79a6c2005 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/DelayRetryable.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.retry; + +import java.util.concurrent.Delayed; + +/** + * DelayRetryable + */ +public interface DelayRetryable extends Delayed { + boolean retry() throws Exception; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/HttpRetryer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/HttpRetryer.java new file mode 100644 index 0000000000..6448db3fe4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/HttpRetryer.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.retry; + +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HttpRetryer { + + private Logger retryLogger = LoggerFactory.getLogger("retry"); + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private EventMeshHTTPServer eventMeshHTTPServer; + + public HttpRetryer(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + private DelayQueue failed = new DelayQueue<>(); + + private ThreadPoolExecutor pool; + + private Thread dispatcher; + + public void pushRetry(DelayRetryable delayRetryable) { + if (failed.size() >= eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerRetryBlockQSize) { + retryLogger.error("[RETRY-QUEUE] is full!"); + return; + } + failed.offer(delayRetryable); + } + + public void init() { + pool = new ThreadPoolExecutor(eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerRetryThreadNum, + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerRetryThreadNum, + 60000, + TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>( + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerRetryBlockQSize), + new ThreadFactory() { + private AtomicInteger count = new AtomicInteger(); + + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r, "http-retry-" + count.incrementAndGet()); + thread.setPriority(Thread.NORM_PRIORITY); + thread.setDaemon(true); + return thread; + } + }, + new ThreadPoolExecutor.AbortPolicy()); + + dispatcher = new Thread(() -> { + try { + DelayRetryable retryObj; + while (!Thread.currentThread().isInterrupted() && (retryObj = failed.take()) != null) { + final DelayRetryable delayRetryable = retryObj; + pool.execute(() -> { + try { + delayRetryable.retry(); + if (retryLogger.isDebugEnabled()) { + retryLogger.debug("retryObj : {}", delayRetryable); + } + } catch (Exception e) { + retryLogger.error("http-retry-dispatcher error!", e); + } + }); + } + } catch (Exception e) { + retryLogger.error("http-retry-dispatcher error!", e); + } + }, "http-retry-dispatcher"); + dispatcher.setDaemon(true); + logger.info("HttpRetryer inited......"); + } + + public int size() { + return failed.size(); + } + + /** + * Get failed queue, this method is just used for metrics. + */ + public DelayQueue getFailedQueue() { + return failed; + } + + public void shutdown() { + dispatcher.interrupt(); + pool.shutdown(); + logger.info("HttpRetryer shutdown......"); + } + + public void start() throws Exception { + dispatcher.start(); + logger.info("HttpRetryer started......"); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/RetryContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/RetryContext.java new file mode 100644 index 0000000000..7841cca1e4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/retry/RetryContext.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.http.retry; + +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +public abstract class RetryContext implements DelayRetryable { + + public int retryTimes = 0; + + public long executeTime = System.currentTimeMillis(); + + public RetryContext delay(long delay) { + this.executeTime = System.currentTimeMillis() + delay; + return this; + } + + @Override + public int compareTo(Delayed delayed) { + RetryContext obj = (RetryContext) delayed; + if (this.executeTime > obj.executeTime) { + return 1; + } else if (this.executeTime == obj.executeTime) { + return 0; + } else { + return -1; + } + } + + @Override + public long getDelay(TimeUnit unit) { + return unit.convert(this.executeTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcp2Client.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcp2Client.java new file mode 100644 index 0000000000..35f17aad10 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcp2Client.java @@ -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 org.apache.eventmesh.runtime.core.protocol.tcp.client; + +import static org.apache.eventmesh.common.protocol.tcp.Command.REDIRECT_TO_CLIENT; +import static org.apache.eventmesh.common.protocol.tcp.Command.SERVER_GOODBYE_REQUEST; + +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.RedirectInfo; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.SessionState; +import org.apache.eventmesh.runtime.metrics.tcp.EventMeshTcpMonitor; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; + +import java.net.InetSocketAddress; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; + +public class EventMeshTcp2Client { + + private static final Logger logger = LoggerFactory.getLogger(EventMeshTcp2Client.class); + + public static InetSocketAddress serverGoodby2Client(EventMeshTCPServer eventMeshTCPServer, Session session, + ClientSessionGroupMapping mapping) { + logger.info("serverGoodby2Client client[{}]", session.getClient()); + try { + long startTime = System.currentTimeMillis(); + Package msg = new Package(); + msg.setHeader( + new Header(SERVER_GOODBYE_REQUEST, OPStatus.SUCCESS.getCode(), "graceful normal quit from eventmesh", + null)); + + eventMeshTCPServer.getScheduler().submit(new Runnable() { + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + } + }); + InetSocketAddress address = (InetSocketAddress) session.getContext().channel().remoteAddress(); + + closeSessionIfTimeout(eventMeshTCPServer, session, mapping); + return address; + } catch (Exception e) { + logger.error("exception occur while serverGoodby2Client", e); + return null; + } + } + + public static InetSocketAddress goodBye2Client(EventMeshTCPServer eventMeshTCPServer, + Session session, + String errMsg, + int eventMeshStatus, + ClientSessionGroupMapping mapping) { + try { + long startTime = System.currentTimeMillis(); + Package msg = new Package(); + msg.setHeader(new Header(SERVER_GOODBYE_REQUEST, eventMeshStatus, errMsg, null)); + eventMeshTCPServer.getScheduler().schedule(new Runnable() { + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + } + }, 1 * 1000, TimeUnit.MILLISECONDS); + + closeSessionIfTimeout(eventMeshTCPServer, session, mapping); + + return session.getRemoteAddress(); + } catch (Exception e) { + logger.error("exception occur while goodbye2client", e); + return null; + } + } + + public static void goodBye2Client(ChannelHandlerContext ctx, + String errMsg, + ClientSessionGroupMapping mapping, + EventMeshTcpMonitor eventMeshTcpMonitor) { + long startTime = System.currentTimeMillis(); + Package pkg = new Package(new Header(SERVER_GOODBYE_REQUEST, OPStatus.FAIL.getCode(), errMsg, null)); + eventMeshTcpMonitor.getTcpSummaryMetrics().getEventMesh2clientMsgNum().incrementAndGet(); + logger.info("goodBye2Client client[{}]", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); + ctx.writeAndFlush(pkg).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + Utils.logSucceedMessageFlow(pkg, null, startTime, startTime); + try { + mapping.closeSession(ctx); + } catch (Exception e) { + logger.warn("close session failed!", e); + } + } + } + ); + } + + public static String redirectClient2NewEventMesh(EventMeshTCPServer eventMeshTCPServer, String newEventMeshIp, + int port, Session session, ClientSessionGroupMapping mapping) { + logger.info("begin to gracefully redirect Client {}, newIPPort[{}]", session.getClient(), + newEventMeshIp + ":" + port); + try { + long startTime = System.currentTimeMillis(); + + Package pkg = new Package(); + pkg.setHeader(new Header(REDIRECT_TO_CLIENT, OPStatus.SUCCESS.getCode(), null, null)); + pkg.setBody(new RedirectInfo(newEventMeshIp, port)); + eventMeshTCPServer.getScheduler().schedule(new Runnable() { + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Utils.writeAndFlush(pkg, startTime, taskExecuteTime, session.getContext(), session); + } + }, 5 * 1000, TimeUnit.MILLISECONDS); + closeSessionIfTimeout(eventMeshTCPServer, session, mapping); + return session.getRemoteAddress() + "--->" + newEventMeshIp + ":" + port; + } catch (Exception e) { + logger.error("exception occur while redirectClient2NewEventMesh", e); + return null; + } + } + + public static void closeSessionIfTimeout(EventMeshTCPServer eventMeshTCPServer, Session session, + ClientSessionGroupMapping mapping) { + eventMeshTCPServer.getScheduler().schedule(new Runnable() { + @Override + public void run() { + try { + if (!session.getSessionState().equals(SessionState.CLOSED)) { + mapping.closeSession(session.getContext()); + logger.info("closeSessionIfTimeout success, session[{}]", session.getClient()); + } + } catch (Exception e) { + logger.error("close session failed", e); + } + } + }, 30 * 1000, TimeUnit.MILLISECONDS); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpConnectionHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpConnectionHandler.java new file mode 100644 index 0000000000..685abc6a6b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpConnectionHandler.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; + +public class EventMeshTcpConnectionHandler extends ChannelDuplexHandler { + + public static AtomicInteger connections = new AtomicInteger(0); + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private EventMeshTCPServer eventMeshTCPServer; + + public EventMeshTcpConnectionHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + logger.info("client|tcp|channelRegistered|remoteAddress={}|msg={}", remoteAddress, ""); + super.channelRegistered(ctx); + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + logger.info("client|tcp|channelUnregistered|remoteAddress={}|msg={}", remoteAddress, ""); + super.channelUnregistered(ctx); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + logger.info("client|tcp|channelActive|remoteAddress={}|msg={}", remoteAddress, ""); + + int c = connections.incrementAndGet(); + if (c > eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpClientMaxNum) { + logger.warn("client|tcp|channelActive|remoteAddress={}|msg={}", remoteAddress, "too many client connect " + + + "this eventMesh server"); + ctx.close(); + return; + } + + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + connections.decrementAndGet(); + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + logger.info("client|tcp|channelInactive|remoteAddress={}|msg={}", remoteAddress, ""); + eventMeshTCPServer.getClientSessionGroupMapping().closeSession(ctx); + super.channelInactive(ctx); + } + + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) evt; + if (event.state().equals(IdleState.ALL_IDLE)) { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + logger.info("client|tcp|userEventTriggered|remoteAddress={}|msg={}", remoteAddress, evt.getClass().getName()); + eventMeshTCPServer.getClientSessionGroupMapping().closeSession(ctx); + } + } + + ctx.fireUserEventTriggered(evt); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpExceptionHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpExceptionHandler.java new file mode 100644 index 0000000000..d9aace846a --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpExceptionHandler.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client; + +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; + +public class EventMeshTcpExceptionHandler extends ChannelDuplexHandler { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private EventMeshTCPServer eventMeshTCPServer; + + public EventMeshTcpExceptionHandler(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + UserAgent client = session == null ? null : session.getClient(); + logger.error("exceptionCaught, push goodbye to client|user={},errMsg={}", client, cause.fillInStackTrace()); + String errMsg; + if (cause.toString().contains("value not one of declared Enum instance names")) { + errMsg = "Unknown Command type"; + } else { + errMsg = cause.toString(); + } + + if (session != null) { + EventMeshTcp2Client.goodBye2Client(eventMeshTCPServer, session, errMsg, OPStatus.FAIL.getCode(), + eventMeshTCPServer.getClientSessionGroupMapping()); + } else { + EventMeshTcp2Client.goodBye2Client(ctx, errMsg, eventMeshTCPServer.getClientSessionGroupMapping(), + eventMeshTCPServer.getEventMeshTcpMonitor()); + } + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpMessageDispatcher.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpMessageDispatcher.java new file mode 100644 index 0000000000..0623d282cf --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpMessageDispatcher.java @@ -0,0 +1,238 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client; + +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.SessionState; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.GoodbyeTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.HeartBeatTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.HelloTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.ListenTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.MessageAckTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.MessageTransferTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.RecommendTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.SubscribeTask; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.task.UnSubscribeTask; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.opentelemetry.api.trace.Span; + +public class EventMeshTcpMessageDispatcher extends SimpleChannelInboundHandler { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Logger messageLogger = LoggerFactory.getLogger("message"); + private EventMeshTCPServer eventMeshTCPServer; + + public EventMeshTcpMessageDispatcher(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Package pkg) throws Exception { + long startTime = System.currentTimeMillis(); + validateMsg(pkg); + + eventMeshTCPServer.getEventMeshTcpMonitor().getTcpSummaryMetrics() + .getClient2eventMeshMsgNum().incrementAndGet(); + + Command cmd = pkg.getHeader().getCmd(); + try { + Runnable task; + + if (isNeedTrace(cmd)) { + pkg.getHeader().getProperties() + .put(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, startTime); + pkg.getHeader().getProperties().put(EventMeshConstants.REQ_SEND_EVENTMESH_IP, + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerIp); + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + + pkg.getHeader().getProperties().put(EventMeshConstants.REQ_SYS, session.getClient().getSubsystem()); + pkg.getHeader().getProperties().put(EventMeshConstants.REQ_IP, session.getClient().getHost()); + pkg.getHeader().getProperties().put(EventMeshConstants.REQ_IDC, session.getClient().getIdc()); + pkg.getHeader().getProperties().put(EventMeshConstants.REQ_GROUP, session.getClient().getGroup()); + } + + if (cmd.equals(Command.RECOMMEND_REQUEST)) { + messageLogger.info("pkg|c2eventMesh|cmd={}|pkg={}", cmd, pkg); + task = new RecommendTask(pkg, ctx, startTime, eventMeshTCPServer); + eventMeshTCPServer.getTaskHandleExecutorService().submit(task); + return; + } + if (cmd.equals(Command.HELLO_REQUEST)) { + messageLogger.info("pkg|c2eventMesh|cmd={}|pkg={}", cmd, pkg); + task = new HelloTask(pkg, ctx, startTime, eventMeshTCPServer); + eventMeshTCPServer.getTaskHandleExecutorService().submit(task); + return; + } + + if (eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx) == null) { + messageLogger.info("pkg|c2eventMesh|cmd={}|pkg={},no session is found", cmd, pkg); + throw new Exception("no session is found"); + } + + logMessageFlow(ctx, pkg, cmd); + + if (eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx) + .getSessionState() == SessionState.CLOSED) { + throw new Exception( + "this eventMesh tcp session will be closed, may be reboot or version change!"); + } + + dispatch(ctx, pkg, startTime, cmd); + } catch (Exception e) { + logger.error("exception occurred while pkg|cmd={}|pkg={}", cmd, pkg, e); + + if (isNeedTrace(cmd)) { + Span span = TraceUtils.prepareServerSpan(pkg.getHeader().getProperties(), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, startTime, + TimeUnit.MILLISECONDS, false); + TraceUtils.finishSpanWithException(span, pkg.getHeader().getProperties(), + "exception occurred while dispatch pkg", e); + } + + writeToClient(cmd, pkg, ctx, e); + } + } + + private boolean isNeedTrace(Command cmd) { + if (eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerTraceEnable + && cmd != null && (Command.REQUEST_TO_SERVER == cmd + || Command.ASYNC_MESSAGE_TO_SERVER == cmd + || Command.BROADCAST_MESSAGE_TO_SERVER == cmd)) { + return true; + } + return false; + } + + private void writeToClient(Command cmd, Package pkg, ChannelHandlerContext ctx, Exception e) { + try { + Package res = new Package(); + res.setHeader(new Header(getReplyCommand(cmd), OPStatus.FAIL.getCode(), e.toString(), + pkg.getHeader().getSeq())); + ctx.writeAndFlush(res); + } catch (Exception ex) { + logger.warn("writeToClient failed", ex); + } + } + + private Command getReplyCommand(Command cmd) { + switch (cmd) { + case HELLO_REQUEST: + return Command.HELLO_RESPONSE; + case RECOMMEND_REQUEST: + return Command.RECOMMEND_RESPONSE; + case HEARTBEAT_REQUEST: + return Command.HEARTBEAT_RESPONSE; + case SUBSCRIBE_REQUEST: + return Command.SUBSCRIBE_RESPONSE; + case UNSUBSCRIBE_REQUEST: + return Command.UNSUBSCRIBE_RESPONSE; + case LISTEN_REQUEST: + return Command.LISTEN_RESPONSE; + case CLIENT_GOODBYE_REQUEST: + return Command.CLIENT_GOODBYE_RESPONSE; + case REQUEST_TO_SERVER: + return Command.RESPONSE_TO_CLIENT; + case ASYNC_MESSAGE_TO_SERVER: + return Command.ASYNC_MESSAGE_TO_SERVER_ACK; + case BROADCAST_MESSAGE_TO_SERVER: + return Command.BROADCAST_MESSAGE_TO_SERVER_ACK; + default: + return cmd; + } + } + + private void logMessageFlow(ChannelHandlerContext ctx, Package pkg, Command cmd) { + if (pkg.getBody() instanceof EventMeshMessage) { + messageLogger.info("pkg|c2eventMesh|cmd={}|Msg={}|user={}", cmd, + EventMeshUtil.printMqMessage((EventMeshMessage) pkg.getBody()), + eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx).getClient()); + } else { + messageLogger.info("pkg|c2eventMesh|cmd={}|pkg={}|user={}", cmd, pkg, + eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx).getClient()); + } + } + + private void validateMsg(Package pkg) throws Exception { + if (pkg == null) { + throw new Exception("the incoming message is empty."); + } + if (pkg.getHeader() == null) { + logger.error("the incoming message does not have a header|pkg={}", pkg); + throw new Exception("the incoming message does not have a header."); + } + if (pkg.getHeader().getCmd() == null) { + logger.error("the incoming message does not have a command type|pkg={}", pkg); + throw new Exception("the incoming message does not have a command type."); + } + } + + private void dispatch(ChannelHandlerContext ctx, Package pkg, long startTime, Command cmd) + throws Exception { + Runnable task; + switch (cmd) { + case HEARTBEAT_REQUEST: + task = new HeartBeatTask(pkg, ctx, startTime, eventMeshTCPServer); + break; + case CLIENT_GOODBYE_REQUEST: + case SERVER_GOODBYE_RESPONSE: + task = new GoodbyeTask(pkg, ctx, startTime, eventMeshTCPServer); + break; + case SUBSCRIBE_REQUEST: + task = new SubscribeTask(pkg, ctx, startTime, eventMeshTCPServer); + break; + case UNSUBSCRIBE_REQUEST: + task = new UnSubscribeTask(pkg, ctx, startTime, eventMeshTCPServer); + break; + case LISTEN_REQUEST: + task = new ListenTask(pkg, ctx, startTime, eventMeshTCPServer); + break; + case REQUEST_TO_SERVER: + case RESPONSE_TO_SERVER: + case ASYNC_MESSAGE_TO_SERVER: + case BROADCAST_MESSAGE_TO_SERVER: + task = new MessageTransferTask(pkg, ctx, startTime, eventMeshTCPServer); + break; + case RESPONSE_TO_CLIENT_ACK: + case ASYNC_MESSAGE_TO_CLIENT_ACK: + case BROADCAST_MESSAGE_TO_CLIENT_ACK: + case REQUEST_TO_CLIENT_ACK: + task = new MessageAckTask(pkg, ctx, startTime, eventMeshTCPServer); + break; + default: + throw new Exception("unknown cmd"); + } + eventMeshTCPServer.getTaskHandleExecutorService().submit(task); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/ClientGroupWrapper.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/ClientGroupWrapper.java new file mode 100644 index 0000000000..fc85da4d3f --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/ClientGroupWrapper.java @@ -0,0 +1,763 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.group; + +import org.apache.eventmesh.api.EventListener; +import org.apache.eventmesh.api.EventMeshAction; +import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.plugin.MQConsumerWrapper; +import org.apache.eventmesh.runtime.core.plugin.MQProducerWrapper; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.dispatch.DownstreamDispatchStrategy; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.DownStreamMsgContext; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry.EventMeshTcpRetryer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.UpStreamMsgContext; +import org.apache.eventmesh.runtime.metrics.tcp.EventMeshTcpMonitor; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.HttpTinyClient; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; + +import com.google.common.base.Preconditions; + +public class ClientGroupWrapper { + + public static Logger logger = LoggerFactory.getLogger(ClientGroupWrapper.class); + + private String sysId; + + private String group; + + private EventMeshTCPConfiguration eventMeshTCPConfiguration; + + private EventMeshTCPServer eventMeshTCPServer; + + private EventMeshTcpRetryer eventMeshTcpRetryer; + + private EventMeshTcpMonitor eventMeshTcpMonitor; + + private DownstreamDispatchStrategy downstreamDispatchStrategy; + + private final ReadWriteLock groupLock = new ReentrantReadWriteLock(); + + public Set groupConsumerSessions = new HashSet(); + + public Set groupProducerSessions = new HashSet(); + + public AtomicBoolean started4Persistent = new AtomicBoolean(Boolean.FALSE); + + public AtomicBoolean started4Broadcast = new AtomicBoolean(Boolean.FALSE); + + public AtomicBoolean inited4Persistent = new AtomicBoolean(Boolean.FALSE); + + public AtomicBoolean inited4Broadcast = new AtomicBoolean(Boolean.FALSE); + + private MQConsumerWrapper persistentMsgConsumer; + + private MQConsumerWrapper broadCastMsgConsumer; + + private ConcurrentHashMap> topic2sessionInGroupMapping = + new ConcurrentHashMap>(); + + private ConcurrentHashMap subscriptions = new ConcurrentHashMap<>(); + + public AtomicBoolean producerStarted = new AtomicBoolean(Boolean.FALSE); + + private MQProducerWrapper mqProducerWrapper; + + public ClientGroupWrapper(String sysId, String group, + EventMeshTCPServer eventMeshTCPServer, + DownstreamDispatchStrategy downstreamDispatchStrategy) { + this.sysId = sysId; + this.group = group; + this.eventMeshTCPServer = eventMeshTCPServer; + this.eventMeshTCPConfiguration = eventMeshTCPServer.getEventMeshTCPConfiguration(); + this.eventMeshTcpRetryer = eventMeshTCPServer.getEventMeshTcpRetryer(); + this.eventMeshTcpMonitor = + Preconditions.checkNotNull(eventMeshTCPServer.getEventMeshTcpMonitor()); + this.downstreamDispatchStrategy = downstreamDispatchStrategy; + this.persistentMsgConsumer = new MQConsumerWrapper( + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshConnectorPluginType); + this.broadCastMsgConsumer = new MQConsumerWrapper( + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshConnectorPluginType); + this.mqProducerWrapper = new MQProducerWrapper( + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshConnectorPluginType); + } + + public ConcurrentHashMap> getTopic2sessionInGroupMapping() { + return topic2sessionInGroupMapping; + } + + public boolean hasSubscription(String topic) { + boolean has = false; + try { + this.groupLock.readLock().lockInterruptibly(); + has = topic2sessionInGroupMapping.containsKey(topic); + } catch (Exception e) { + logger.error("hasSubscription error! topic[{}]", topic); + } finally { + this.groupLock.readLock().unlock(); + } + + return has; + } + + public boolean send(UpStreamMsgContext upStreamMsgContext, SendCallback sendCallback) + throws Exception { + mqProducerWrapper.send(upStreamMsgContext.getEvent(), sendCallback); + return true; + } + + public void request(UpStreamMsgContext upStreamMsgContext, RequestReplyCallback rrCallback, + long timeout) + throws Exception { + mqProducerWrapper.request(upStreamMsgContext.getEvent(), rrCallback, timeout); + } + + public boolean reply(UpStreamMsgContext upStreamMsgContext) throws Exception { + mqProducerWrapper.reply(upStreamMsgContext.getEvent(), new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + + } + + @Override + public void onException(OnExceptionContext context) { + String bizSeqNo = (String) upStreamMsgContext.getEvent() + .getExtension(EventMeshConstants.PROPERTY_MESSAGE_KEYS); + logger.error("reply err! topic:{}, bizSeqNo:{}, client:{}", + upStreamMsgContext.getEvent().getSubject(), bizSeqNo, + upStreamMsgContext.getSession().getClient(), context.getException()); + } + }); + return true; + } + + public MQProducerWrapper getMqProducerWrapper() { + return mqProducerWrapper; + } + + public boolean addSubscription(SubscriptionItem subscriptionItem, Session session) + throws Exception { + if (subscriptionItem == null) { + logger.error("addSubscription param error,subscriptionItem is null", session); + return false; + } + String topic = subscriptionItem.getTopic(); + if (session == null || !StringUtils.equalsIgnoreCase(group, + EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + logger.error("addSubscription param error,topic:{},session:{}", topic, session); + return false; + } + + boolean r = false; + try { + this.groupLock.writeLock().lockInterruptibly(); + if (!topic2sessionInGroupMapping.containsKey(topic)) { + Set sessions = new HashSet(); + topic2sessionInGroupMapping.put(topic, sessions); + } + r = topic2sessionInGroupMapping.get(topic).add(session); + if (r) { + logger.info("addSubscription success, group:{} topic:{} client:{}", group, + topic, session.getClient()); + } else { + logger + .warn("addSubscription fail, group:{} topic:{} client:{}", group, topic, + session.getClient()); + } + + subscriptions.putIfAbsent(topic, subscriptionItem); + } catch (Exception e) { + logger + .error("addSubscription error! topic:{} client:{}", topic, session.getClient(), e); + throw new Exception("addSubscription fail"); + } finally { + this.groupLock.writeLock().unlock(); + } + return r; + } + + public boolean removeSubscription(SubscriptionItem subscriptionItem, Session session) { + if (subscriptionItem == null) { + logger.error("addSubscription param error,subscriptionItem is null", session); + return false; + } + String topic = subscriptionItem.getTopic(); + if (session == null + || !StringUtils.equalsIgnoreCase(group, + EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + logger.error("removeSubscription param error,topic:{},session:{}", topic, session); + return false; + } + + boolean r = false; + try { + this.groupLock.writeLock().lockInterruptibly(); + if (topic2sessionInGroupMapping.containsKey(topic)) { + r = topic2sessionInGroupMapping.get(topic).remove(session); + if (r) { + logger.info( + "removeSubscription remove session success, group:{} topic:{} client:{}", + group, topic, session.getClient()); + } else { + logger.warn( + "removeSubscription remove session failed, group:{} topic:{} client:{}", + group, topic, session.getClient()); + } + } + if (CollectionUtils.size(topic2sessionInGroupMapping.get(topic)) == 0) { + topic2sessionInGroupMapping.remove(topic); + subscriptions.remove(topic); + logger.info("removeSubscription remove topic success, group:{} topic:{}", + group, topic); + } + } catch (Exception e) { + logger.error("removeSubscription error! topic:{} client:{}", topic, session.getClient(), + e); + } finally { + this.groupLock.writeLock().unlock(); + } + return r; + } + + public synchronized void startClientGroupProducer() throws Exception { + if (producerStarted.get()) { + return; + } + + Properties keyValue = new Properties(); + keyValue.put("producerGroup", group); + keyValue.put("instanceName", EventMeshUtil + .buildMeshTcpClientID(sysId, "PUB", eventMeshTCPConfiguration.eventMeshCluster)); + + //TODO for defibus + keyValue.put("eventMeshIDC", eventMeshTCPConfiguration.eventMeshIDC); + + mqProducerWrapper.init(keyValue); + mqProducerWrapper.start(); + producerStarted.compareAndSet(false, true); + logger.info("starting producer success, group:{}", group); + } + + public synchronized void shutdownProducer() throws Exception { + if (!producerStarted.get()) { + return; + } + mqProducerWrapper.shutdown(); + producerStarted.compareAndSet(true, false); + logger.info("shutdown producer success for group:{}", group); + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public boolean addGroupConsumerSession(Session session) { + if (session == null + || !StringUtils.equalsIgnoreCase(group, + EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + logger.error("addGroupConsumerSession param error,session:{}", session); + return false; + } + + boolean r = false; + try { + this.groupLock.writeLock().lockInterruptibly(); + r = groupConsumerSessions.add(session); + if (r) { + logger.info("addGroupConsumerSession success, group:{} client:{}", group, + session.getClient()); + } + } catch (Exception e) { + logger.error("addGroupConsumerSession error! group:{} client:{}", group, + session.getClient(), e); + } finally { + this.groupLock.writeLock().unlock(); + } + return r; + } + + public boolean addGroupProducerSession(Session session) { + if (session == null + || !StringUtils.equalsIgnoreCase(group, + EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + logger.error("addGroupProducerSession param error,session:{}", session); + return false; + } + + boolean r = false; + try { + this.groupLock.writeLock().lockInterruptibly(); + r = groupProducerSessions.add(session); + if (r) { + logger.info("addGroupProducerSession success, group:{} client:{}", group, + session.getClient()); + } + } catch (Exception e) { + logger.error("addGroupProducerSession error! group:{} client:{}", group, + session.getClient(), e); + } finally { + this.groupLock.writeLock().unlock(); + } + return r; + } + + public boolean removeGroupConsumerSession(Session session) { + if (session == null + || !StringUtils.equalsIgnoreCase(group, + EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + logger.error("removeGroupConsumerSession param error,session:{}", session); + return false; + } + + boolean r = false; + try { + this.groupLock.writeLock().lockInterruptibly(); + r = groupConsumerSessions.remove(session); + if (r) { + logger.info("removeGroupConsumerSession success, group:{} client:{}", group, + session.getClient()); + } + } catch (Exception e) { + logger.error("removeGroupConsumerSession error! group:{} client:{}", group, + session.getClient(), e); + } finally { + this.groupLock.writeLock().unlock(); + } + return r; + } + + public boolean removeGroupProducerSession(Session session) { + if (session == null + || !StringUtils.equalsIgnoreCase(group, + EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + logger.error("removeGroupProducerSession param error,session:{}", session); + return false; + } + + boolean r = false; + try { + this.groupLock.writeLock().lockInterruptibly(); + r = groupProducerSessions.remove(session); + if (r) { + logger.info("removeGroupProducerSession success, group:{} client:{}", group, + session.getClient()); + } + } catch (Exception e) { + logger.error("removeGroupProducerSession error! group:{} client:{}", group, + session.getClient(), e); + } finally { + this.groupLock.writeLock().unlock(); + } + + return r; + } + + public synchronized void initClientGroupPersistentConsumer() throws Exception { + if (inited4Persistent.get()) { + return; + } + + Properties keyValue = new Properties(); + keyValue.put("isBroadcast", "false"); + keyValue.put("consumerGroup", group); + keyValue.put("eventMeshIDC", eventMeshTCPConfiguration.eventMeshIDC); + keyValue.put("instanceName", EventMeshUtil + .buildMeshTcpClientID(sysId, "SUB", eventMeshTCPConfiguration.eventMeshCluster)); + + persistentMsgConsumer.init(keyValue); + + EventListener listener = (event, context) -> { + String protocolVersion = + Objects.requireNonNull(event.getSpecVersion()).toString(); + + Span span = TraceUtils.prepareServerSpan( + EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), + EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_SERVER_SPAN, false); + + try { + eventMeshTcpMonitor.getTcpSummaryMetrics().getMq2eventMeshMsgNum() + .incrementAndGet(); + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_RECEIVE_EVENTMESH_IP, + eventMeshTCPConfiguration.eventMeshServerIp).build(); + String topic = event.getSubject(); + + EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = + (EventMeshAsyncConsumeContext) context; + Session session = downstreamDispatchStrategy + .select(group, topic, groupConsumerSessions); + String bizSeqNo = EventMeshUtil.getMessageBizSeq(event); + if (session == null) { + try { + Integer sendBackTimes = 0; + String sendBackFromEventMeshIp = ""; + if (StringUtils.isNotBlank(Objects.requireNonNull(event.getExtension( + EventMeshConstants.EVENTMESH_SEND_BACK_TIMES)).toString())) { + sendBackTimes = (Integer) event.getExtension( + EventMeshConstants.EVENTMESH_SEND_BACK_TIMES); + } + if (StringUtils.isNotBlank(Objects.requireNonNull(event.getExtension( + EventMeshConstants.EVENTMESH_SEND_BACK_IP)).toString())) { + sendBackFromEventMeshIp = (String) event.getExtension( + EventMeshConstants.EVENTMESH_SEND_BACK_IP); + } + + logger.error( + "found no session to downstream msg,groupName:{}, topic:{}, " + + "bizSeqNo:{}, sendBackTimes:{}, sendBackFromEventMeshIp:{}", + group, topic, bizSeqNo, sendBackTimes, + sendBackFromEventMeshIp); + + if (sendBackTimes >= eventMeshTCPServer + .getEventMeshTCPConfiguration().eventMeshTcpSendBackMaxTimes) { + logger.error( + "sendBack to broker over max times:{}, groupName:{}, topic:{}, " + + "bizSeqNo:{}", eventMeshTCPServer + .getEventMeshTCPConfiguration() + .eventMeshTcpSendBackMaxTimes, + group, topic, bizSeqNo); + } else { + sendBackTimes++; + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.EVENTMESH_SEND_BACK_TIMES, + sendBackTimes.toString()) + .withExtension(EventMeshConstants.EVENTMESH_SEND_BACK_IP, + eventMeshTCPConfiguration.eventMeshServerIp).build(); + sendMsgBackToBroker(event, bizSeqNo); + } + } catch (Exception e) { + logger.warn("handle msg exception when no session found", e); + } + + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + return; + } + + SubscriptionItem subscriptionItem = subscriptions.get(topic); + DownStreamMsgContext downStreamMsgContext = + new DownStreamMsgContext(event, session, persistentMsgConsumer, + eventMeshAsyncConsumeContext.getAbstractContext(), false, + subscriptionItem); + //msg put in eventmesh,waiting client ack + session.getPusher().unAckMsg(downStreamMsgContext.seq, downStreamMsgContext); + session.downstreamMsg(downStreamMsgContext); + eventMeshAsyncConsumeContext.commit(EventMeshAction.ManualAck); + } finally { + TraceUtils.finishSpan(span, event); + } + }; + persistentMsgConsumer.registerEventListener(listener); + + inited4Persistent.compareAndSet(false, true); + logger.info("init persistentMsgConsumer success, group:{}", group); + } + + public synchronized void startClientGroupPersistentConsumer() throws Exception { + if (started4Persistent.get()) { + return; + } + persistentMsgConsumer.start(); + started4Persistent.compareAndSet(false, true); + logger.info("starting persistentMsgConsumer success, group:{}", group); + } + + public synchronized void initClientGroupBroadcastConsumer() throws Exception { + if (inited4Broadcast.get()) { + return; + } + + Properties keyValue = new Properties(); + keyValue.put("isBroadcast", "true"); + keyValue.put("consumerGroup", group); + keyValue.put("eventMeshIDC", eventMeshTCPConfiguration.eventMeshIDC); + keyValue.put("instanceName", EventMeshUtil + .buildMeshTcpClientID(sysId, "SUB", eventMeshTCPConfiguration.eventMeshCluster)); + broadCastMsgConsumer.init(keyValue); + + EventListener listener = (event, context) -> { + String protocolVersion = + Objects.requireNonNull(event.getSpecVersion()).toString(); + + Span span = TraceUtils.prepareServerSpan( + EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), + EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_SERVER_SPAN, false); + try { + eventMeshTcpMonitor.getTcpSummaryMetrics().getMq2eventMeshMsgNum() + .incrementAndGet(); + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, + String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.REQ_RECEIVE_EVENTMESH_IP, + eventMeshTCPConfiguration.eventMeshServerIp).build(); + String topic = event.getSubject(); + + EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = + (EventMeshAsyncConsumeContext) context; + if (CollectionUtils.isEmpty(groupConsumerSessions)) { + logger.warn("found no session to downstream broadcast msg"); + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + return; + } + + Iterator sessionsItr = groupConsumerSessions.iterator(); + + SubscriptionItem subscriptionItem = subscriptions.get(topic); + DownStreamMsgContext downStreamMsgContext = + new DownStreamMsgContext(event, null, broadCastMsgConsumer, + eventMeshAsyncConsumeContext.getAbstractContext(), false, + subscriptionItem); + + while (sessionsItr.hasNext()) { + Session session = sessionsItr.next(); + + if (!session.isAvailable(topic)) { + logger + .warn("downstream broadcast msg,session is not available,client:{}", + session.getClient()); + continue; + } + + downStreamMsgContext.session = session; + + //downstream broadcast msg asynchronously + eventMeshTCPServer.getBroadcastMsgDownstreamExecutorService() + .submit(new Runnable() { + @Override + public void run() { + //msg put in eventmesh,waiting client ack + session.getPusher() + .unAckMsg(downStreamMsgContext.seq, downStreamMsgContext); + session.downstreamMsg(downStreamMsgContext); + } + }); + } + + eventMeshAsyncConsumeContext.commit(EventMeshAction.ManualAck); + } finally { + TraceUtils.finishSpan(span, event); + } + }; + broadCastMsgConsumer.registerEventListener(listener); + + inited4Broadcast.compareAndSet(false, true); + logger.info("init broadCastMsgConsumer success, group:{}", group); + } + + public synchronized void startClientGroupBroadcastConsumer() throws Exception { + if (started4Broadcast.get()) { + return; + } + broadCastMsgConsumer.start(); + started4Broadcast.compareAndSet(false, true); + logger.info("starting broadCastMsgConsumer success, group:{}", group); + } + + public void subscribe(SubscriptionItem subscriptionItem) throws Exception { + if (SubscriptionMode.BROADCASTING.equals(subscriptionItem.getMode())) { + broadCastMsgConsumer.subscribe(subscriptionItem.getTopic()); + } else { + persistentMsgConsumer.subscribe(subscriptionItem.getTopic()); + } + } + + public void unsubscribe(SubscriptionItem subscriptionItem) throws Exception { + if (SubscriptionMode.BROADCASTING.equals(subscriptionItem.getMode())) { + broadCastMsgConsumer.unsubscribe(subscriptionItem.getTopic()); + } else { + persistentMsgConsumer.unsubscribe(subscriptionItem.getTopic()); + } + } + + public synchronized void shutdownBroadCastConsumer() throws Exception { + if (started4Broadcast.get()) { + broadCastMsgConsumer.shutdown(); + logger.info("broadcast consumer group:{} shutdown...", group); + } + started4Broadcast.compareAndSet(true, false); + inited4Broadcast.compareAndSet(true, false); + broadCastMsgConsumer = null; + } + + public synchronized void shutdownPersistentConsumer() throws Exception { + + if (started4Persistent.get()) { + persistentMsgConsumer.shutdown(); + logger.info("persistent consumer group:{} shutdown...", group); + } + started4Persistent.compareAndSet(true, false); + inited4Persistent.compareAndSet(true, false); + persistentMsgConsumer = null; + } + + public Set getGroupConsumerSessions() { + return groupConsumerSessions; + } + + public Set getGroupProducerSessions() { + return groupProducerSessions; + } + + public EventMeshTCPConfiguration getEventMeshTCPConfiguration() { + return eventMeshTCPConfiguration; + } + + public void setEventMeshTCPConfiguration(EventMeshTCPConfiguration eventMeshTCPConfiguration) { + this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; + } + + public EventMeshTcpRetryer getEventMeshTcpRetryer() { + return eventMeshTcpRetryer; + } + + public void setEventMeshTcpRetryer(EventMeshTcpRetryer eventMeshTcpRetryer) { + this.eventMeshTcpRetryer = eventMeshTcpRetryer; + } + + public EventMeshTcpMonitor getEventMeshTcpMonitor() { + return eventMeshTcpMonitor; + } + + public void setEventMeshTcpMonitor(EventMeshTcpMonitor eventMeshTcpMonitor) { + this.eventMeshTcpMonitor = eventMeshTcpMonitor; + } + + public DownstreamDispatchStrategy getDownstreamDispatchStrategy() { + return downstreamDispatchStrategy; + } + + public void setDownstreamDispatchStrategy( + DownstreamDispatchStrategy downstreamDispatchStrategy) { + this.downstreamDispatchStrategy = downstreamDispatchStrategy; + } + + public String getSysId() { + return sysId; + } + + private String pushMsgToEventMesh(CloudEvent msg, String ip, int port) throws Exception { + StringBuilder targetUrl = new StringBuilder(); + targetUrl.append("http://").append(ip).append(":").append(port) + .append("/eventMesh/msg/push"); + HttpTinyClient.HttpResult result = null; + + try { + logger.info("pushMsgToEventMesh,targetUrl:{},msg:{}", targetUrl, + msg); + List paramValues = new ArrayList(); + paramValues.add("msg"); + paramValues.add(JsonUtils.serialize(msg)); + paramValues.add("group"); + paramValues.add(group); + + result = HttpTinyClient.httpPost( + targetUrl.toString(), + null, + paramValues, + "UTF-8", + 3000); + } catch (Exception e) { + logger.error("httpPost " + targetUrl + " is fail,", e); + throw e; + } + + if (200 == result.getCode() && result.getContent() != null) { + return result.getContent(); + + } else { + throw new Exception("httpPost targetUrl[" + targetUrl + + "] is not OK when getContentThroughHttp, httpResult: " + result + "."); + } + } + + public MQConsumerWrapper getPersistentMsgConsumer() { + return persistentMsgConsumer; + } + + private void sendMsgBackToBroker(CloudEvent event, String bizSeqNo) throws Exception { + try { + String topic = event.getSubject(); + logger.warn("send msg back to broker, bizSeqno:{}, topic:{}", bizSeqNo, topic); + + long startTime = System.currentTimeMillis(); + long taskExcuteTime = startTime; + send(new UpStreamMsgContext(null, event, null, startTime, taskExcuteTime), + new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + logger.info( + "group:{} consume fail, sendMessageBack success, bizSeqno:{}, " + + "topic:{}", group, bizSeqNo, topic); + } + + @Override + public void onException(OnExceptionContext context) { + logger.warn( + "group:{} consume fail, sendMessageBack fail, bizSeqno:{}," + + " topic:{}", group, bizSeqNo, topic); + } + + }); + eventMeshTcpMonitor.getTcpSummaryMetrics().getEventMesh2mqMsgNum().incrementAndGet(); + } catch (Exception e) { + logger.warn("try send msg back to broker failed"); + throw e; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/ClientSessionGroupMapping.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/ClientSessionGroupMapping.java new file mode 100644 index 0000000000..8a184d5042 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/ClientSessionGroupMapping.java @@ -0,0 +1,504 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.group; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.dispatch.DownstreamDispatchStrategy; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.dispatch.FreePriorityDispatchStrategy; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.SessionState; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.DownStreamMsgContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.collections4.MapUtils; + +import java.lang.ref.WeakReference; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; + +public class ClientSessionGroupMapping { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Logger sessionLogger = LoggerFactory.getLogger("sessionLogger"); + + private ConcurrentHashMap sessionTable = new ConcurrentHashMap<>(); + + private ConcurrentHashMap clientGroupMap = + new ConcurrentHashMap(); + + private ConcurrentHashMap lockMap = + new ConcurrentHashMap(); + + private EventMeshTCPServer eventMeshTCPServer; + + public ClientSessionGroupMapping(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + public EventMeshTCPServer getEventMeshTCPServer() { + return eventMeshTCPServer; + } + + public void setEventMeshTCPServer(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + public ClientGroupWrapper getClientGroupWrapper(String sysId) { + return MapUtils.getObject(clientGroupMap, sysId, null); + } + + public Session getSession(ChannelHandlerContext ctx) { + Session session = getSession((InetSocketAddress) ctx.channel().remoteAddress()); + return session; + } + + public Session getSession(InetSocketAddress address) { + return sessionTable.get(address); + } + + public Session createSession(UserAgent user, ChannelHandlerContext ctx) throws Exception { + InetSocketAddress addr = (InetSocketAddress) ctx.channel().remoteAddress(); + user.setHost(addr.getHostString()); + user.setPort(addr.getPort()); + Session session = null; + if (!sessionTable.containsKey(addr)) { + logger.info("createSession client[{}]", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); + session = new Session(user, ctx, eventMeshTCPServer.getEventMeshTCPConfiguration()); + initClientGroupWrapper(user, session); + sessionTable.put(addr, session); + sessionLogger.info("session|open|succeed|user={}", user); + } else { + session = sessionTable.get(addr); + sessionLogger.error("session|open|failed|user={}|msg={}", user, "session has been created!"); + } + return session; + } + + public void readySession(Session session) throws Exception { + if (!EventMeshConstants.PURPOSE_SUB.equals(session.getClient().getPurpose())) { + throw new Exception("client purpose config is not sub"); + } + startClientGroupConsumer(session); + } + + public synchronized void closeSession(ChannelHandlerContext ctx) throws Exception { + + InetSocketAddress addr = (InetSocketAddress) ctx.channel().remoteAddress(); + Session session = MapUtils.getObject(sessionTable, addr, null); + if (session == null) { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + logger.info("begin to close channel to remote address[{}]", remoteAddress); + ctx.channel().close().addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + logger.info("close the connection to remote address[{}] result: {}", remoteAddress, + future.isSuccess()); + } + }); + sessionLogger.info("session|close|succeed|address={}|msg={}", addr, "no session was found"); + return; + } + + closeSession(session); + + //remove session from sessionTable + sessionTable.remove(addr); + + sessionLogger.info("session|close|succeed|user={}", session.getClient()); + } + + private void closeSession(Session session) throws Exception { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(session.getContext().channel()); + if (SessionState.CLOSED == session.getSessionState()) { + logger.info("session has been closed, addr:{}", remoteAddress); + return; + } + + //session must be synchronized to avoid SessionState be confound, for example adding subscribe when session closing + synchronized (session) { + + if (SessionState.CLOSED == session.getSessionState()) { + logger.info("session has been closed in sync, addr:{}", remoteAddress); + return; + } + + session.setSessionState(SessionState.CLOSED); + + if (EventMeshConstants.PURPOSE_SUB.equals(session.getClient().getPurpose())) { + cleanClientGroupWrapperByCloseSub(session); + } else if (EventMeshConstants.PURPOSE_PUB.equals(session.getClient().getPurpose())) { + cleanClientGroupWrapperByClosePub(session); + } else { + logger.error("client purpose config is error:{}", session.getClient().getPurpose()); + } + + if (session.getContext() != null) { + logger.info("begin to close channel to remote address[{}]", remoteAddress); + session.getContext().channel().close().addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + logger.info("close the connection to remote address[{}] result: {}", remoteAddress, + future.isSuccess()); + } + }); + } + } + } + + private ClientGroupWrapper constructClientGroupWrapper(String sysId, String group, + EventMeshTCPServer eventMeshTCPServer, + DownstreamDispatchStrategy downstreamDispatchStrategy) { + return new ClientGroupWrapper(sysId, group, eventMeshTCPServer, + downstreamDispatchStrategy); + } + + private void initClientGroupWrapper(UserAgent user, Session session) throws Exception { + if (!lockMap.containsKey(user.getGroup())) { + Object obj = lockMap.putIfAbsent(user.getGroup(), new Object()); + if (obj == null) { + logger.info("add lock to map for group:{}", user.getGroup()); + } + } + synchronized (lockMap.get(user.getGroup())) { + if (!clientGroupMap.containsKey(user.getGroup())) { + ClientGroupWrapper cgw = constructClientGroupWrapper(user.getSubsystem(), user.getGroup(), + eventMeshTCPServer, new FreePriorityDispatchStrategy()); + clientGroupMap.put(user.getGroup(), cgw); + logger.info("create new ClientGroupWrapper, group:{}", user.getGroup()); + } + + ClientGroupWrapper cgw = clientGroupMap.get(user.getGroup()); + + if (EventMeshConstants.PURPOSE_PUB.equals(user.getPurpose())) { + startClientGroupProducer(cgw, session); + } else if (EventMeshConstants.PURPOSE_SUB.equals(user.getPurpose())) { + initClientGroupConsumser(cgw); + } else { + logger.error("unknown client purpose:{}", user.getPurpose()); + throw new Exception("client purpose config is error"); + } + + session.setClientGroupWrapper(new WeakReference(cgw)); + } + } + + private void startClientGroupProducer(ClientGroupWrapper cgw, Session session) throws Exception { + if (!cgw.producerStarted.get()) { + cgw.startClientGroupProducer(); + } + boolean flag = cgw.addGroupProducerSession(session); + if (!flag) { + throw new Exception("addGroupProducerSession fail"); + } + session.setSessionState(SessionState.RUNNING); + } + + private void initClientGroupConsumser(ClientGroupWrapper cgw) throws Exception { + if (!cgw.producerStarted.get()) { + cgw.startClientGroupProducer(); + } + + if (!cgw.inited4Broadcast.get()) { + cgw.initClientGroupBroadcastConsumer(); + } + + if (!cgw.inited4Persistent.get()) { + cgw.initClientGroupPersistentConsumer(); + } + } + + private void startClientGroupConsumer(Session session) throws Exception { + if (!lockMap.containsKey(session.getClient().getSubsystem())) { + lockMap.putIfAbsent(session.getClient().getSubsystem(), new Object()); + } + synchronized (lockMap.get(session.getClient().getSubsystem())) { + logger.info("readySession session[{}]", session); + ClientGroupWrapper cgw = session.getClientGroupWrapper().get(); + + boolean flag = cgw.addGroupConsumerSession(session); + if (!flag) { + throw new Exception("addGroupConsumerSession fail"); + } + + if (cgw.inited4Persistent.get() && !cgw.started4Persistent.get()) { + cgw.startClientGroupPersistentConsumer(); + } + if (cgw.inited4Broadcast.get() && !cgw.started4Broadcast.get()) { + cgw.startClientGroupBroadcastConsumer(); + } + session.setSessionState(SessionState.RUNNING); + } + } + + private void cleanClientGroupWrapperByCloseSub(Session session) throws Exception { + cleanSubscriptionInSession(session); + session.getClientGroupWrapper().get().removeGroupConsumerSession(session); + handleUnackMsgsInSession(session); + cleanClientGroupWrapperCommon(session); + } + + private void cleanClientGroupWrapperByClosePub(Session session) throws Exception { + session.getClientGroupWrapper().get().removeGroupProducerSession(session); + cleanClientGroupWrapperCommon(session); + } + + /** + * clean subscription of the session + * + * @param session + */ + private void cleanSubscriptionInSession(Session session) throws Exception { + for (SubscriptionItem item : session.getSessionContext().subscribeTopics.values()) { + session.getClientGroupWrapper().get().removeSubscription(item, session); + if (!session.getClientGroupWrapper().get().hasSubscription(item.getTopic())) { + session.getClientGroupWrapper().get().unsubscribe(item); + } + } + } + + /** + * handle unAck msgs in this session + * + * @param session + */ + private void handleUnackMsgsInSession(Session session) { + ConcurrentHashMap unAckMsg = session.getPusher().getUnAckMsg(); + if (unAckMsg.size() > 0 && session.getClientGroupWrapper().get().getGroupConsumerSessions().size() > 0) { + for (Map.Entry entry : unAckMsg.entrySet()) { + DownStreamMsgContext downStreamMsgContext = entry.getValue(); + if (SubscriptionMode.BROADCASTING.equals(downStreamMsgContext.subscriptionItem.getMode())) { + logger.warn("exist broadcast msg unack when closeSession,seq:{},bizSeq:{},client:{}", + downStreamMsgContext.seq, EventMeshUtil.getMessageBizSeq(downStreamMsgContext.event), + session.getClient()); + continue; + } + Session reChooseSession = session.getClientGroupWrapper().get().getDownstreamDispatchStrategy() + .select(session.getClientGroupWrapper().get().getGroup(), + downStreamMsgContext.event.getSubject(), + Objects.requireNonNull(session.getClientGroupWrapper().get()).groupConsumerSessions); + if (reChooseSession != null) { + downStreamMsgContext.session = reChooseSession; + reChooseSession.getPusher().unAckMsg(downStreamMsgContext.seq, downStreamMsgContext); + reChooseSession.downstreamMsg(downStreamMsgContext); + logger.info("rePush msg form unAckMsgs,seq:{},rePushClient:{}", entry.getKey(), + downStreamMsgContext.session.getClient()); + } else { + logger.warn("select session fail in handleUnackMsgsInSession,seq:{},topic:{}", entry.getKey(), + downStreamMsgContext.event.getSubject()); + } + } + } + } + + private void cleanClientGroupWrapperCommon(Session session) throws Exception { + logger.info("GroupConsumerSessions size:{}", + session.getClientGroupWrapper().get().getGroupConsumerSessions().size()); + if (session.getClientGroupWrapper().get().getGroupConsumerSessions().size() == 0) { + shutdownClientGroupConsumer(session); + } + + logger.info("GroupProducerSessions size:{}", + session.getClientGroupWrapper().get().getGroupProducerSessions().size()); + if ((session.getClientGroupWrapper().get().getGroupConsumerSessions().size() == 0) + && (session.getClientGroupWrapper().get().getGroupProducerSessions().size() == 0)) { + shutdownClientGroupProducer(session); + + clientGroupMap.remove(session.getClientGroupWrapper().get().getGroup()); + lockMap.remove(session.getClientGroupWrapper().get().getGroup()); + logger.info("remove clientGroupWrapper group[{}]", session.getClientGroupWrapper().get().getGroup()); + } + } + + private void shutdownClientGroupConsumer(Session session) throws Exception { + if (session.getClientGroupWrapper().get().started4Broadcast.get() == Boolean.TRUE) { + session.getClientGroupWrapper().get().shutdownBroadCastConsumer(); + } + + if (session.getClientGroupWrapper().get().started4Persistent.get() == Boolean.TRUE) { + session.getClientGroupWrapper().get().shutdownPersistentConsumer(); + } + } + + + private void shutdownClientGroupProducer(Session session) throws Exception { + if (session.getClientGroupWrapper().get().producerStarted.get() == Boolean.TRUE) { + session.getClientGroupWrapper().get().shutdownProducer(); + } + } + + private void initSessionCleaner() { + eventMeshTCPServer.getScheduler().scheduleAtFixedRate( + new Runnable() { + @Override + public void run() { + Iterator sessionIterator = sessionTable.values().iterator(); + while (sessionIterator.hasNext()) { + Session tmp = sessionIterator.next(); + if (System.currentTimeMillis() - tmp.getLastHeartbeatTime() + > eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpSessionExpiredInMills) { + try { + logger.warn("clean expired session,client:{}", tmp.getClient()); + closeSession(tmp.getContext()); + } catch (Exception e) { + logger.error("say goodbye to session error! {}", tmp, e); + } + } + } + } + }, 1000, eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpSessionExpiredInMills, + TimeUnit.MILLISECONDS); + } + + private void initDownStreamMsgContextCleaner() { + eventMeshTCPServer.getScheduler().scheduleAtFixedRate( + new Runnable() { + @Override + public void run() { + + //scan non-broadcast msg + Iterator sessionIterator = sessionTable.values().iterator(); + while (sessionIterator.hasNext()) { + Session tmp = sessionIterator.next(); + for (Map.Entry entry : tmp.getPusher().getUnAckMsg().entrySet()) { + String seqKey = entry.getKey(); + DownStreamMsgContext downStreamMsgContext = entry.getValue(); + if (!downStreamMsgContext.isExpire()) { + continue; + } + downStreamMsgContext.ackMsg(); + tmp.getPusher().getUnAckMsg().remove(seqKey); + logger.warn("remove expire downStreamMsgContext, session:{}, topic:{}, seq:{}", tmp, + downStreamMsgContext.event.getSubject(), seqKey); + } + } + } + }, 1000, 5 * 1000, TimeUnit.MILLISECONDS); + } + + + public void init() throws Exception { + initSessionCleaner(); + initDownStreamMsgContextCleaner(); + logger.info("ClientSessionGroupMapping inited......"); + } + + public void start() throws Exception { + logger.info("ClientSessionGroupMapping started......"); + } + + public void shutdown() throws Exception { + logger.info("begin to close sessions gracefully"); + for (ClientGroupWrapper clientGroupWrapper : clientGroupMap.values()) { + for (Session subSession : clientGroupWrapper.getGroupConsumerSessions()) { + try { + EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, subSession, this); + } catch (Exception e) { + logger.error("say goodbye to subSession error! {}", subSession, e); + } + } + + for (Session pubSession : clientGroupWrapper.getGroupProducerSessions()) { + try { + EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, pubSession, this); + } catch (Exception e) { + logger.error("say goodbye to pubSession error! {}", pubSession, e); + } + } + try { + Thread.sleep(eventMeshTCPServer.getEventMeshTCPConfiguration().gracefulShutdownSleepIntervalInMills); + } catch (InterruptedException e) { + logger.warn("Thread.sleep occur InterruptedException", e); + } + } + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + logger.warn("Thread.sleep occur InterruptedException", e); + } + + sessionTable.values().parallelStream().forEach(itr -> { + try { + EventMeshTcp2Client.serverGoodby2Client(this.eventMeshTCPServer, itr, this); + } catch (Exception e) { + logger.error("say goodbye to session error! {}", itr, e); + } + }); + ThreadUtils.randomSleep(50); + logger.info("ClientSessionGroupMapping shutdown......"); + } + + public ConcurrentHashMap getSessionMap() { + return sessionTable; + } + + public ConcurrentHashMap getClientGroupMap() { + return clientGroupMap; + } + + public Map> prepareEventMeshClientDistributionData() { + Map> result = null; + + if (!clientGroupMap.isEmpty()) { + result = new HashMap<>(); + for (Map.Entry entry : clientGroupMap.entrySet()) { + Map map = new HashMap<>(); + map.put(EventMeshConstants.PURPOSE_SUB, entry.getValue().getGroupConsumerSessions().size()); + map.put(EventMeshConstants.PURPOSE_PUB, entry.getValue().getGroupProducerSessions().size()); + result.put(entry.getKey(), map); + } + } + + return result; + } + + public Map> prepareProxyClientDistributionData() { + Map> result = null; + + if (!clientGroupMap.isEmpty()) { + result = new HashMap<>(); + for (Map.Entry entry : clientGroupMap.entrySet()) { + Map map = new HashMap<>(); + map.put(EventMeshConstants.PURPOSE_SUB, entry.getValue().getGroupConsumerSessions().size()); + map.put(EventMeshConstants.PURPOSE_PUB, entry.getValue().getGroupProducerSessions().size()); + result.put(entry.getKey(), map); + } + } + + return result; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/dispatch/DownstreamDispatchStrategy.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/dispatch/DownstreamDispatchStrategy.java new file mode 100644 index 0000000000..9259c51de8 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/dispatch/DownstreamDispatchStrategy.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.group.dispatch; + + +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; + +import java.util.Set; + +/** + * DownstreamDispatchStrategy + */ +public interface DownstreamDispatchStrategy { + /** + * select a SESSION + * + * @param group + * @param consumeSessions + * @return + */ + Session select(String group, String topic, Set consumeSessions); +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/dispatch/FreePriorityDispatchStrategy.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/dispatch/FreePriorityDispatchStrategy.java new file mode 100644 index 0000000000..623dbb07d9 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/group/dispatch/FreePriorityDispatchStrategy.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.group.dispatch; + +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FreePriorityDispatchStrategy implements DownstreamDispatchStrategy { + + private static final Logger logger = LoggerFactory.getLogger(FreePriorityDispatchStrategy.class); + + @Override + public Session select(String group, String topic, Set groupConsumerSessions) { + if (CollectionUtils.isEmpty(groupConsumerSessions) + || StringUtils.isBlank(topic) + || StringUtils.isBlank(group)) { + return null; + } + + List filtered = new ArrayList(); + List isolatedSessions = new ArrayList<>(); + for (Session session : groupConsumerSessions) { + if (!session.isAvailable(topic)) { + continue; + } + if (session.isIsolated()) { + isolatedSessions.add(session); + logger.info("session is not available because session is isolated,isolateTime:{},client:{}", + session.getIsolateTime(), session.getClient()); + continue; + } + filtered.add(session); + } + + if (CollectionUtils.isEmpty(filtered)) { + if (CollectionUtils.isEmpty(isolatedSessions)) { + logger.warn("all sessions can't downstream msg"); + return null; + } else { + logger.warn("all sessions are isolated,group:{},topic:{}", group, topic); + filtered.addAll(isolatedSessions); + } + } + + Collections.shuffle(filtered); + Session session = filtered.get(0); + return session; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventMeshRebalanceService.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventMeshRebalanceService.java new file mode 100644 index 0000000000..560cf40e24 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventMeshRebalanceService.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.util.EventMeshThreadFactoryImpl; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventMeshRebalanceService { + protected final Logger logger = LoggerFactory.getLogger(EventMeshRebalanceService.class); + + private EventMeshTCPServer eventMeshTCPServer; + + private Integer rebalanceIntervalMills; + + private EventMeshRebalanceStrategy rebalanceStrategy; + + private ScheduledExecutorService serviceRebalanceScheduler; + + public EventMeshRebalanceService(EventMeshTCPServer eventMeshTCPServer, EventMeshRebalanceStrategy rebalanceStrategy) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.rebalanceStrategy = rebalanceStrategy; + this.rebalanceIntervalMills = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpRebalanceIntervalInMills; + } + + public void init() { + this.serviceRebalanceScheduler = ThreadPoolFactory.createScheduledExecutor(5, new EventMeshThreadFactoryImpl("proxy-rebalance-sch", true)); + logger.info("rebalance service inited......"); + } + + public void start() throws Exception { + rebalanceStrategy.doRebalance(); + serviceRebalanceScheduler.scheduleAtFixedRate(() -> { + try { + rebalanceStrategy.doRebalance(); + } catch (Exception ex) { + logger.error("RebalanceByService failed", ex); + } + }, rebalanceIntervalMills, rebalanceIntervalMills, TimeUnit.MILLISECONDS); + logger.info("rebalance service started......"); + } + + public void shutdown() { + this.serviceRebalanceScheduler.shutdown(); + logger.info("rebalance service shutdown......"); + } + + public void printRebalanceThreadPoolState() { + EventMeshUtil.printState((ThreadPoolExecutor) serviceRebalanceScheduler); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventMeshRebalanceStrategy.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventMeshRebalanceStrategy.java new file mode 100644 index 0000000000..b14e602a82 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventMeshRebalanceStrategy.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance; + +/** + * EventMeshRebalanceStrategy + */ +public interface EventMeshRebalanceStrategy { + void doRebalance() throws Exception; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventmeshRebalanceImpl.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventmeshRebalanceImpl.java new file mode 100644 index 0000000000..ad787f8e70 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventmeshRebalanceImpl.java @@ -0,0 +1,279 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance; + +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend.EventMeshRecommendImpl; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend.EventMeshRecommendStrategy; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventmeshRebalanceImpl implements EventMeshRebalanceStrategy { + + protected final Logger logger = LoggerFactory.getLogger(EventmeshRebalanceImpl.class); + + private EventMeshTCPServer eventMeshTCPServer; + + public EventmeshRebalanceImpl(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void doRebalance() throws Exception { + long startTime = System.currentTimeMillis(); + logger.info("doRebalance start===========startTime:{}", startTime); + + Set groupSet = eventMeshTCPServer.getClientSessionGroupMapping().getClientGroupMap().keySet(); + if (CollectionUtils.isEmpty(groupSet)) { + logger.warn("doRebalance failed,eventmesh has no group, please check eventmeshData"); + return; + } + + final String cluster = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshCluster; + //get eventmesh of local idc + Map localEventMeshMap = queryLocalEventMeshMap(cluster); + if (localEventMeshMap == null || localEventMeshMap.size() == 0) { + return; + } + + for (String group : groupSet) { + doRebalanceByGroup(cluster, group, EventMeshConstants.PURPOSE_SUB, localEventMeshMap); + doRebalanceByGroup(cluster, group, EventMeshConstants.PURPOSE_PUB, localEventMeshMap); + } + logger.info("doRebalance end===========startTime:{}, cost:{}", startTime, System.currentTimeMillis() - startTime); + } + + private Map queryLocalEventMeshMap(String cluster) { + Map localEventMeshMap = null; + List eventMeshDataInfoList = null; + try { + eventMeshDataInfoList = eventMeshTCPServer.getRegistry().findEventMeshInfoByCluster(cluster); + + if (eventMeshDataInfoList == null || CollectionUtils.isEmpty(eventMeshDataInfoList)) { + logger.warn("doRebalance failed,query eventmesh instances is null from registry,cluster:{}", cluster); + return null; + } + localEventMeshMap = new HashMap<>(); + String localIdc = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshIDC; + for (EventMeshDataInfo eventMeshDataInfo : eventMeshDataInfoList) { + String idc = eventMeshDataInfo.getEventMeshName().split("-")[0]; + if (StringUtils.isNotBlank(idc) && StringUtils.equals(idc, localIdc)) { + localEventMeshMap.put(eventMeshDataInfo.getEventMeshName(), eventMeshDataInfo.getEndpoint()); + } + } + + if (0 == localEventMeshMap.size()) { + logger.warn("doRebalance failed,query eventmesh instances of localIDC is null from registry,localIDC:{},cluster:{}", + localIdc, cluster); + return null; + } + } catch (Exception e) { + logger.warn("doRebalance failed,findEventMeshInfoByCluster failed,cluster:{},errMsg:{}", cluster, e); + return null; + } + + return localEventMeshMap; + } + + private void doRebalanceByGroup(String cluster, String group, String purpose, Map eventMeshMap) throws Exception { + logger.info("doRebalanceByGroup start, cluster:{}, group:{}, purpose:{}", cluster, group, purpose); + + //query distribute data of loacl idc + Map clientDistributionMap = queryLocalEventMeshDistributeData(cluster, group, purpose, + eventMeshMap); + if (clientDistributionMap == null || clientDistributionMap.size() == 0) { + return; + } + + doRebalanceRedirect(eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshName, group, purpose, + eventMeshMap, clientDistributionMap); + logger.info("doRebalanceByGroup end, cluster:{}, group:{}, purpose:{}", cluster, group, purpose); + + } + + private void doRebalanceRedirect(String currEventMeshName, String group, String purpose, Map eventMeshMap, + Map clientDistributionMap) throws Exception { + if (clientDistributionMap == null || clientDistributionMap.size() == 0) { + return; + } + + //caculate client num need to redirect in currEventMesh + int judge = caculateRedirectNum(currEventMeshName, group, purpose, clientDistributionMap); + + if (judge > 0) { + + //select redirect target eventmesh lisg + List eventMeshRecommendResult = selectRedirectEventMesh(group, eventMeshMap, clientDistributionMap, + judge, currEventMeshName); + if (eventMeshRecommendResult == null || eventMeshRecommendResult.size() != judge) { + logger.warn("doRebalance failed,recommendEventMeshNum is not consistent,recommendResult:{},judge:{}", + eventMeshRecommendResult, judge); + return; + } + + //do redirect + doRedirect(group, purpose, judge, eventMeshRecommendResult); + } else { + logger.info("rebalance condition not satisfy,group:{}, purpose:{},judge:{}", group, purpose, judge); + } + } + + private void doRedirect(String group, String purpose, int judge, List eventMeshRecommendResult) throws Exception { + logger.info("doRebalance redirect start---------------------group:{},judge:{}", group, judge); + Set sessionSet = null; + if (EventMeshConstants.PURPOSE_SUB.equals(purpose)) { + sessionSet = eventMeshTCPServer.getClientSessionGroupMapping().getClientGroupMap().get(group).getGroupConsumerSessions(); + } else if (EventMeshConstants.PURPOSE_PUB.equals(purpose)) { + sessionSet = eventMeshTCPServer.getClientSessionGroupMapping().getClientGroupMap().get(group).getGroupProducerSessions(); + } else { + logger.warn("doRebalance failed,param is illegal, group:{}, purpose:{}", group, purpose); + return; + } + List sessionList = new ArrayList<>(sessionSet); + Collections.shuffle(new ArrayList<>(sessionList)); + + for (int i = 0; i < judge; i++) { + String newProxyIp = eventMeshRecommendResult.get(i).split(":")[0]; + String newProxyPort = eventMeshRecommendResult.get(i).split(":")[1]; + String redirectSessionAddr = EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer, newProxyIp, + Integer.parseInt(newProxyPort), sessionList.get(i), eventMeshTCPServer.getClientSessionGroupMapping()); + logger.info("doRebalance,redirect sessionAddr:{}", redirectSessionAddr); + try { + Thread.sleep(eventMeshTCPServer.getEventMeshTCPConfiguration().sleepIntervalInRebalanceRedirectMills); + } catch (InterruptedException e) { + logger.warn("Thread.sleep occur InterruptedException", e); + } + } + logger.info("doRebalance redirect end---------------------group:{}", group); + } + + private List selectRedirectEventMesh(String group, Map eventMeshMap, + Map clientDistributionMap, int judge, + String evenMeshName) throws Exception { + EventMeshRecommendStrategy eventMeshRecommendStrategy = new EventMeshRecommendImpl(eventMeshTCPServer); + return eventMeshRecommendStrategy.calculateRedirectRecommendEventMesh(eventMeshMap, clientDistributionMap, + group, judge, evenMeshName); + } + + public int caculateRedirectNum(String eventMeshName, String group, String purpose, + Map clientDistributionMap) throws Exception { + int sum = 0; + for (Integer item : clientDistributionMap.values()) { + sum += item; + } + int currentNum = 0; + if (clientDistributionMap.get(eventMeshName) != null) { + currentNum = clientDistributionMap.get(eventMeshName); + } + int avgNum = sum / clientDistributionMap.size(); + int modNum = sum % clientDistributionMap.size(); + + List eventMeshList = new ArrayList<>(clientDistributionMap.keySet()); + Collections.sort(eventMeshList); + int index = -1; + for (int i = 0; i < Math.min(modNum, eventMeshList.size()); i++) { + if (StringUtils.equals(eventMeshName, eventMeshList.get(i))) { + index = i; + break; + } + } + int rebalanceResult = 0; + if (avgNum == 0) { + rebalanceResult = 1; + } else { + rebalanceResult = (modNum != 0 && index < modNum && index >= 0) ? avgNum + 1 : avgNum; + } + logger.info("rebalance caculateRedirectNum,group:{}, purpose:{},sum:{},avgNum:{}," + + + "modNum:{}, index:{}, currentNum:{}, rebalanceResult:{}", group, purpose, sum, + avgNum, modNum, index, currentNum, rebalanceResult); + return currentNum - rebalanceResult; + } + + private Map queryLocalEventMeshDistributeData(String cluster, String group, String purpose, + Map eventMeshMap) { + Map localEventMeshDistributeData = null; + Map> eventMeshClientDistributionDataMap = null; + try { + eventMeshClientDistributionDataMap = eventMeshTCPServer.getRegistry().findEventMeshClientDistributionData( + cluster, group, purpose); + + if (eventMeshClientDistributionDataMap == null || eventMeshClientDistributionDataMap.size() == 0) { + logger.warn("doRebalance failed,found no distribute data in regitry, cluster:{}, group:{}, purpose:{}", + cluster, group, purpose); + return null; + } + + localEventMeshDistributeData = new HashMap<>(); + String localIdc = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshIDC; + for (Map.Entry> entry : eventMeshClientDistributionDataMap.entrySet()) { + String idc = entry.getKey().split("-")[0]; + if (StringUtils.isNotBlank(idc) && StringUtils.equals(idc, localIdc)) { + localEventMeshDistributeData.put(entry.getKey(), entry.getValue().get(purpose)); + } + } + + if (0 == localEventMeshDistributeData.size()) { + logger.warn("doRebalance failed,found no distribute data of localIDC in regitry,cluster:{},group:{}, purpose:{},localIDC:{}", + cluster, group, purpose, localIdc); + return null; + } + + logger.info("before revert clientDistributionMap:{}, group:{}, purpose:{}", localEventMeshDistributeData, + group, purpose); + for (String eventMeshName : localEventMeshDistributeData.keySet()) { + if (!eventMeshMap.keySet().contains(eventMeshName)) { + logger.warn( + "doRebalance failed,exist eventMesh not register but exist in " + + "distributionMap,cluster:{},grpup:{},purpose:{},eventMeshName:{}", + cluster, group, purpose, eventMeshName); + return null; + } + } + for (String eventMesh : eventMeshMap.keySet()) { + if (!localEventMeshDistributeData.keySet().contains(eventMesh)) { + localEventMeshDistributeData.put(eventMesh, 0); + } + } + logger.info("after revert clientDistributionMap:{}, group:{}, purpose:{}", localEventMeshDistributeData, + group, purpose); + } catch (Exception e) { + logger.warn("doRebalance failed,cluster:{},group:{},purpose:{},findProxyClientDistributionData failed, errMsg:{}", + cluster, group, purpose, e); + return null; + } + + return localEventMeshDistributeData; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/recommend/EventMeshRecommendImpl.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/recommend/EventMeshRecommendImpl.java new file mode 100644 index 0000000000..290e3d4ffb --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/recommend/EventMeshRecommendImpl.java @@ -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 org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend; + +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.util.ValueComparator; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventMeshRecommendImpl implements EventMeshRecommendStrategy { + + protected final Logger logger = LoggerFactory.getLogger(EventMeshRecommendImpl.class); + + private EventMeshTCPServer eventMeshTCPServer; + + public EventMeshRecommendImpl(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public String calculateRecommendEventMesh(String group, String purpose) throws Exception { + List eventMeshDataInfoList = null; + if (StringUtils.isBlank(group) || StringUtils.isBlank(purpose)) { + logger.warn("EventMeshRecommend failed,params illegal,group:{},purpose:{}", group, purpose); + return null; + } + final String cluster = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshCluster; + try { + eventMeshDataInfoList = eventMeshTCPServer.getRegistry().findEventMeshInfoByCluster(cluster); + } catch (Exception e) { + logger.warn("EventMeshRecommend failed, findEventMeshInfoByCluster failed, cluster:{}, group:{}, purpose:{}, errMsg:{}", + cluster, group, purpose, e); + return null; + } + + if (eventMeshDataInfoList == null || CollectionUtils.isEmpty(eventMeshDataInfoList)) { + logger.warn("EventMeshRecommend failed,not find eventMesh instances from registry,cluster:{},group:{},purpose:{}", + cluster, group, purpose); + return null; + } + + Map localEventMeshMap = new HashMap<>(); + Map remoteEventMeshMap = new HashMap<>(); + String localIdc = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshIDC; + for (EventMeshDataInfo eventMeshDataInfo : eventMeshDataInfoList) { + String idc = eventMeshDataInfo.getEventMeshName().split("-")[0]; + if (StringUtils.isNotBlank(idc)) { + if (StringUtils.equals(idc, localIdc)) { + localEventMeshMap.put(eventMeshDataInfo.getEventMeshName(), eventMeshDataInfo.getEndpoint()); + } else { + remoteEventMeshMap.put(eventMeshDataInfo.getEventMeshName(), eventMeshDataInfo.getEndpoint()); + } + } else { + logger.error("EventMeshName may be illegal,idc is null,eventMeshName:{}", eventMeshDataInfo.getEventMeshName()); + } + } + + if (localEventMeshMap.size() == 0 && remoteEventMeshMap.size() == 0) { + logger.warn("EventMeshRecommend failed,find no legal eventMesh instances from registry,localIDC:{}", localIdc); + return null; + } + if (localEventMeshMap.size() > 0) { + //recommend eventmesh of local idc + return recommendProxyByDistributeData(cluster, group, purpose, localEventMeshMap, true); + } else if (remoteEventMeshMap.size() > 0) { + //recommend eventmesh of other idc + return recommendProxyByDistributeData(cluster, group, purpose, remoteEventMeshMap, false); + } else { + logger.error("localEventMeshMap or remoteEventMeshMap size error"); + return null; + } + } + + @Override + public List calculateRedirectRecommendEventMesh(Map eventMeshMap, + Map clientDistributeMap, String group, + int recommendProxyNum, String eventMeshName) throws Exception { + if (recommendProxyNum < 1) { + return null; + } + logger.info("eventMeshMap:{},clientDistributionMap:{},group:{},recommendNum:{},currEventMeshName:{}", + eventMeshMap, clientDistributeMap, group, recommendProxyNum, eventMeshName); + //find eventmesh with least client + List> list = new ArrayList<>(); + ValueComparator vc = new ValueComparator(); + for (Map.Entry entry : clientDistributeMap.entrySet()) { + list.add(entry); + } + Collections.sort(list, vc); + logger.info("clientDistributionMap after sort:{}", list); + + List recommendProxyList = new ArrayList<>(recommendProxyNum); + while (recommendProxyList.size() < recommendProxyNum) { + Map.Entry minProxyItem = list.get(0); + int currProxyNum = clientDistributeMap.get(eventMeshName); + recommendProxyList.add(eventMeshMap.get(minProxyItem.getKey())); + clientDistributeMap.put(minProxyItem.getKey(), minProxyItem.getValue() + 1); + clientDistributeMap.put(eventMeshName, currProxyNum - 1); + Collections.sort(list, vc); + logger.info("clientDistributionMap after sort:{}", list); + } + logger.info("choose proxys with min instance num, group:{}, recommendProxyNum:{}, recommendProxyList:{}", + group, recommendProxyNum, recommendProxyList); + return recommendProxyList; + } + + private String recommendProxyByDistributeData(String cluster, String group, String purpose, + Map eventMeshMap, boolean caculateLocal) { + logger.info("eventMeshMap:{},cluster:{},group:{},purpose:{},caculateLocal:{}", eventMeshMap, cluster, + group, purpose, caculateLocal); + + String recommendProxyAddr = null; + List tmpProxyAddrList = null; + Map> eventMeshClientDistributionDataMap = null; + try { + eventMeshClientDistributionDataMap = eventMeshTCPServer.getRegistry().findEventMeshClientDistributionData( + cluster, group, purpose); + } catch (Exception e) { + logger.warn("EventMeshRecommend failed,findEventMeshClientDistributionData failed," + + "cluster:{},group:{},purpose:{}, errMsg:{}", cluster, group, purpose, e); + } + + if (eventMeshClientDistributionDataMap == null || MapUtils.isEmpty(eventMeshClientDistributionDataMap)) { + tmpProxyAddrList = new ArrayList<>(eventMeshMap.values()); + Collections.shuffle(tmpProxyAddrList); + recommendProxyAddr = tmpProxyAddrList.get(0); + logger.info("No distribute data in registry,cluster:{}, group:{},purpose:{}, recommendProxyAddr:{}", + cluster, group, purpose, recommendProxyAddr); + return recommendProxyAddr; + } + + Map localClientDistributionMap = new HashMap<>(); + Map remoteClientDistributionMap = new HashMap<>(); + for (Map.Entry> entry : eventMeshClientDistributionDataMap.entrySet()) { + String idc = entry.getKey().split("-")[0]; + if (StringUtils.isNotBlank(idc)) { + if (StringUtils.equals(idc, eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshIDC)) { + localClientDistributionMap.put(entry.getKey(), entry.getValue().get(purpose)); + } else { + remoteClientDistributionMap.put(entry.getKey(), entry.getValue().get(purpose)); + } + } else { + logger.error("eventMeshName may be illegal,idc is null,eventMeshName:{}", entry.getKey()); + } + } + recommendProxyAddr = recommendProxy(eventMeshMap, (caculateLocal == true) ? localClientDistributionMap + : remoteClientDistributionMap, group); + + logger.info("eventMeshMap:{},group:{},purpose:{},caculateLocal:{},recommendProxyAddr:{}", eventMeshMap, + group, purpose, caculateLocal, recommendProxyAddr); + return recommendProxyAddr; + } + + private String recommendProxy(Map eventMeshMap, Map clientDistributionMap, String group) { + logger.info("eventMeshMap:{},clientDistributionMap:{},group:{}", eventMeshMap, clientDistributionMap, group); + String recommendProxy = null; + + for (String proxyName : clientDistributionMap.keySet()) { + if (!eventMeshMap.keySet().contains(proxyName)) { + logger.warn("exist proxy not register but exist in distributionMap,proxy:{}", proxyName); + return null; + } + } + for (String proxy : eventMeshMap.keySet()) { + if (!clientDistributionMap.keySet().contains(proxy)) { + clientDistributionMap.put(proxy, 0); + } + } + + //select the eventmesh with least instances + List> list = new ArrayList<>(); + ValueComparator vc = new ValueComparator(); + for (Map.Entry entry : clientDistributionMap.entrySet()) { + list.add(entry); + } + if (list.size() == 0) { + logger.error("no legal distribute data,check eventMeshMap and distributeData, group:{}", group); + return null; + } else { + Collections.sort(list, vc); + logger.info("clientDistributionMap after sort:{}", list); + recommendProxy = eventMeshMap.get(list.get(0).getKey()); + return recommendProxy; + } + } + + private List calculate(Map proxyMap, Map clientDistributionMap, + String group, int recommendProxyNum) { + return null; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/recommend/EventMeshRecommendStrategy.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/recommend/EventMeshRecommendStrategy.java new file mode 100644 index 0000000000..515cf3bc83 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/recommend/EventMeshRecommendStrategy.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend; + +import java.util.List; +import java.util.Map; + +/** + * EventMeshRecommendStrategy + */ +public interface EventMeshRecommendStrategy { + String calculateRecommendEventMesh(String group, String purpose) throws Exception; + + List calculateRedirectRecommendEventMesh(Map eventMeshMap, + Map clientDistributeMap, String group, + int recommendNum, String eventMeshName) throws Exception; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/Session.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/Session.java new file mode 100644 index 0000000000..5c7234e02f --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/Session.java @@ -0,0 +1,349 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session; + +import static org.apache.eventmesh.common.protocol.tcp.Command.LISTEN_RESPONSE; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientGroupWrapper; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.DownStreamMsgContext; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.SessionPusher; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.EventMeshTcpSendResult; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.SessionSender; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.ref.WeakReference; +import java.net.InetSocketAddress; +import java.util.List; +import java.util.concurrent.locks.ReentrantLock; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; + +public class Session { + + protected final Logger messageLogger = LoggerFactory.getLogger("message"); + + private final Logger subscribeLogger = LoggerFactory.getLogger("subscribeLogger"); + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private UserAgent client; + + private InetSocketAddress remoteAddress; + + protected ChannelHandlerContext context; + + private WeakReference clientGroupWrapper; + + private EventMeshTCPConfiguration eventMeshTCPConfiguration; + + private SessionPusher pusher; + + private SessionSender sender; + + private long createTime = System.currentTimeMillis(); + + private long lastHeartbeatTime = System.currentTimeMillis(); + + private long isolateTime = 0; + + private SessionContext sessionContext = new SessionContext(this); + + private boolean listenRspSend = false; + + private ReentrantLock listenRspLock = new ReentrantLock(); + + private String listenRequestSeq = null; + + protected SessionState sessionState = SessionState.CREATED; + + public InetSocketAddress getRemoteAddress() { + return remoteAddress; + } + + public void setRemoteAddress(InetSocketAddress remoteAddress) { + this.remoteAddress = remoteAddress; + } + + public long getLastHeartbeatTime() { + return lastHeartbeatTime; + } + + public void notifyHeartbeat(long heartbeatTime) throws Exception { + this.lastHeartbeatTime = heartbeatTime; + } + + public SessionState getSessionState() { + return sessionState; + } + + public void setSessionState(SessionState sessionState) { + this.sessionState = sessionState; + } + + public void setClient(UserAgent client) { + this.client = client; + } + + public SessionPusher getPusher() { + return pusher; + } + + public void setPusher(SessionPusher pusher) { + this.pusher = pusher; + } + + public SessionSender getSender() { + return sender; + } + + public void setSender(SessionSender sender) { + this.sender = sender; + } + + public void setLastHeartbeatTime(long lastHeartbeatTime) { + this.lastHeartbeatTime = lastHeartbeatTime; + } + + public SessionContext getSessionContext() { + return sessionContext; + } + + public void setSessionContext(SessionContext sessionContext) { + this.sessionContext = sessionContext; + } + + public ChannelHandlerContext getContext() { + return context; + } + + public void setContext(ChannelHandlerContext context) { + this.context = context; + } + + public UserAgent getClient() { + return client; + } + + public String getListenRequestSeq() { + return listenRequestSeq; + } + + public void setListenRequestSeq(String listenRequestSeq) { + this.listenRequestSeq = listenRequestSeq; + } + + public void subscribe(List items) throws Exception { + for (SubscriptionItem item : items) { + sessionContext.subscribeTopics.putIfAbsent(item.getTopic(), item); + clientGroupWrapper.get().subscribe(item); + + clientGroupWrapper.get().getMqProducerWrapper().getMeshMQProducer().checkTopicExist(item.getTopic()); + + clientGroupWrapper.get().addSubscription(item, this); + subscribeLogger.info("subscribe|succeed|topic={}|user={}", item.getTopic(), client); + } + } + + public void unsubscribe(List items) throws Exception { + for (SubscriptionItem item : items) { + sessionContext.subscribeTopics.remove(item.getTopic()); + clientGroupWrapper.get().removeSubscription(item, this); + + if (!clientGroupWrapper.get().hasSubscription(item.getTopic())) { + clientGroupWrapper.get().unsubscribe(item); + subscribeLogger.info("unSubscribe|succeed|topic={}|lastUser={}", item.getTopic(), client); + } + } + } + + public EventMeshTcpSendResult upstreamMsg(Header header, CloudEvent event, SendCallback sendCallback, long startTime, long taskExecuteTime) { + String topic = event.getSubject(); + sessionContext.sendTopics.putIfAbsent(topic, topic); + return sender.send(header, event, sendCallback, startTime, taskExecuteTime); + } + + public void downstreamMsg(DownStreamMsgContext downStreamMsgContext) { + long currTime = System.currentTimeMillis(); + trySendListenResponse(new Header(LISTEN_RESPONSE, OPStatus.SUCCESS.getCode(), "succeed", getListenRequestSeq()), currTime, currTime); + + pusher.push(downStreamMsgContext); + } + + public boolean isIsolated() { + return System.currentTimeMillis() < isolateTime; + } + + public void write2Client(final Package pkg) { + + try { + if (SessionState.CLOSED.equals(sessionState)) { + return; + } + context.writeAndFlush(pkg).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + messageLogger.error("write2Client fail, pkg[{}] session[{}]", pkg, this); + } else { + clientGroupWrapper.get().getEventMeshTcpMonitor().getTcpSummaryMetrics().getEventMesh2clientMsgNum() + .incrementAndGet(); + } + } + } + ); + } catch (Exception e) { + logger.error("exception while write2Client", e); + } + } + + @Override + public String toString() { + return "Session{" + + + "sysId=" + clientGroupWrapper.get().getSysId() + + + ",remoteAddr=" + RemotingHelper.parseSocketAddressAddr(remoteAddress) + + + ",client=" + client + + + ",sessionState=" + sessionState + + + ",sessionContext=" + sessionContext + + + ",pusher=" + pusher + + + ",sender=" + sender + + + ",createTime=" + DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT) + + + ",lastHeartbeatTime=" + DateFormatUtils.format(lastHeartbeatTime, EventMeshConstants.DATE_FORMAT) + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Session session = (Session) o; + if (client != null ? !client.equals(session.client) : session.client != null) { + return false; + } + if (context != null ? !context.equals(session.context) : session.context != null) { + return false; + } + if (sessionState != null ? !sessionState.equals(session.sessionState) : session.sessionState != null) { + return false; + } + return true; + } + + public WeakReference getClientGroupWrapper() { + return clientGroupWrapper; + } + + public void setClientGroupWrapper(WeakReference clientGroupWrapper) { + this.clientGroupWrapper = clientGroupWrapper; + } + + public Session(UserAgent client, ChannelHandlerContext context, EventMeshTCPConfiguration eventMeshTCPConfiguration) { + this.client = client; + this.context = context; + this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; + this.remoteAddress = (InetSocketAddress) context.channel().remoteAddress(); + this.sender = new SessionSender(this); + this.pusher = new SessionPusher(this); + } + + public EventMeshTCPConfiguration getEventMeshTCPConfiguration() { + return eventMeshTCPConfiguration; + } + + public void setEventMeshTCPConfiguration(EventMeshTCPConfiguration eventMeshTCPConfiguration) { + this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; + } + + public void trySendListenResponse(Header header, long startTime, long taskExecuteTime) { + if (!listenRspSend) { + if (listenRspLock.tryLock()) { + if (!listenRspSend) { + if (header == null) { + header = new Header(LISTEN_RESPONSE, OPStatus.SUCCESS.getCode(), "succeed", null); + } + Package msg = new Package(); + msg.setHeader(header); + + // TODO: if startTime is modified + Utils.writeAndFlush(msg, startTime, taskExecuteTime, context, this); + listenRspSend = true; + } + listenRspLock.unlock(); + } + } + } + + public long getIsolateTime() { + return isolateTime; + } + + public void setIsolateTime(long isolateTime) { + this.isolateTime = isolateTime; + } + + public boolean isAvailable(String topic) { + if (SessionState.CLOSED == sessionState) { + logger.warn("session is not available because session has been closed,topic:{},client:{}", topic, client); + return false; + } + + if (!sessionContext.subscribeTopics.containsKey(topic)) { + logger.warn("session is not available because session has not subscribe topic:{},client:{}", topic, client); + return false; + } + + return true; + } + + public boolean isRunning() { + if (SessionState.RUNNING != sessionState) { + logger.warn("session is not running, state:{} client:{}", sessionState, client); + return false; + } + return true; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/SessionContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/SessionContext.java new file mode 100644 index 0000000000..802b6e1c0e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/SessionContext.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.concurrent.ConcurrentHashMap; + +public class SessionContext { + + private Session session; + + public ConcurrentHashMap sendTopics = new ConcurrentHashMap(); + + public ConcurrentHashMap subscribeTopics = new ConcurrentHashMap(); + + public long createTime = System.currentTimeMillis(); + + public SessionContext(Session session) { + this.session = session; + } + + @Override + public String toString() { + return "SessionContext{subscribeTopics=" + subscribeTopics + + ",sendTopics=" + sendTopics.keySet() + + ",createTime=" + DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT) + "}"; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/SessionState.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/SessionState.java new file mode 100644 index 0000000000..2093a8e4e0 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/SessionState.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session; + +public enum SessionState { + CREATED, + RUNNING, + CLOSED +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/ClientAckContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/ClientAckContext.java new file mode 100644 index 0000000000..ffcf936838 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/ClientAckContext.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.plugin.MQConsumerWrapper; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class ClientAckContext { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private String seq; + + private AbstractContext context; + + private long createTime; + + private long expireTime; + + private List events; + + private MQConsumerWrapper consumer; + + public ClientAckContext(String seq, AbstractContext context, List events, MQConsumerWrapper consumer) { + this.seq = seq; + this.context = context; + this.events = events; + this.consumer = consumer; + this.createTime = System.currentTimeMillis(); + String ttlStr = events.get(0).getExtension(EventMeshConstants.PROPERTY_MESSAGE_TTL).toString(); + long ttl = StringUtils.isNumeric(ttlStr) ? Long.parseLong(ttlStr) : EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS; + this.expireTime = System.currentTimeMillis() + ttl; + } + + public boolean isExpire() { + return System.currentTimeMillis() >= expireTime; + } + + public String getSeq() { + return seq; + } + + public void setSeq(String seq) { + this.seq = seq; + } + + public AbstractContext getContext() { + return context; + } + + public void setContext(AbstractContext context) { + this.context = context; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public List getEvents() { + return events; + } + + public void setEvents(List events) { + this.events = events; + } + + public long getExpireTime() { + return expireTime; + } + + public void setExpireTime(long expireTime) { + this.expireTime = expireTime; + } + + public MQConsumerWrapper getConsumer() { + return consumer; + } + + public void ackMsg() { + if (consumer != null && context != null && events != null) { + consumer.updateOffset(events, context); + logger.info("ackMsg topic:{}, bizSeq:{}", events.get(0).getSubject(), EventMeshUtil.getMessageBizSeq(events.get(0))); + } else { + logger.warn("ackMsg failed,consumer is null:{}, context is null:{} , msgs is null:{}", + consumer == null, context == null, events == null); + } + } + + @Override + public String toString() { + return "ClientAckContext{" + + + ",seq=" + seq + + + //TODO ",consumer=" + consumer.getDefaultMQPushConsumer().getMessageModel() + + // ",consumerGroup=" + consumer.getDefaultMQPushConsumer().getConsumerGroup() + + ",topic=" + (CollectionUtils.size(events) > 0 ? events.get(0).getSubject() : null) + + + ",createTime=" + DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT) + + + ",expireTime=" + DateFormatUtils.format(expireTime, EventMeshConstants.DATE_FORMAT) + '}'; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/DownStreamMsgContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/DownStreamMsgContext.java new file mode 100644 index 0000000000..d01469c7d6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/DownStreamMsgContext.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push; + +import org.apache.eventmesh.api.AbstractContext; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.plugin.MQConsumerWrapper; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry.RetryContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.ServerGlobal; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class DownStreamMsgContext extends RetryContext { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public Session session; + + public AbstractContext consumeConcurrentlyContext; + + public MQConsumerWrapper consumer; + + public SubscriptionItem subscriptionItem; + + public long lastPushTime; + + private long createTime; + + private long expireTime; + + public boolean msgFromOtherEventMesh; + + public DownStreamMsgContext(CloudEvent event, Session session, MQConsumerWrapper consumer, + AbstractContext consumeConcurrentlyContext, boolean msgFromOtherEventMesh, + SubscriptionItem subscriptionItem) { + this.seq = String.valueOf(ServerGlobal.getInstance().getMsgCounter().incrementAndGet()); + this.event = event; + this.session = session; + this.consumer = consumer; + this.consumeConcurrentlyContext = consumeConcurrentlyContext; + this.lastPushTime = System.currentTimeMillis(); + this.createTime = System.currentTimeMillis(); + this.subscriptionItem = subscriptionItem; + String ttlStr = (String) event.getExtension("TTL"); + long ttl = StringUtils.isNumeric(ttlStr) ? Long.parseLong(ttlStr) : + EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS; + this.expireTime = System.currentTimeMillis() + ttl; + this.msgFromOtherEventMesh = msgFromOtherEventMesh; + } + + public boolean isExpire() { + return System.currentTimeMillis() >= expireTime; + } + + public void ackMsg() { + if (consumer != null && consumeConcurrentlyContext != null && event != null) { + List events = new ArrayList(); + events.add(event); + consumer.updateOffset(events, consumeConcurrentlyContext); + logger.info("ackMsg seq:{}, topic:{}, bizSeq:{}", seq, events.get(0).getSubject(), + events.get(0).getExtension(EventMeshConstants.PROPERTY_MESSAGE_KEYS)); + } else { + logger.warn("ackMsg seq:{} failed,consumer is null:{}, context is null:{} , msgs is null:{}", seq, + consumer == null, consumeConcurrentlyContext == null, event == null); + } + } + + @Override + public String toString() { + return "DownStreamMsgContext{" + + + ",seq=" + seq + + + ",client=" + (session == null ? null : session.getClient()) + + + ",retryTimes=" + retryTimes + + + ",consumer=" + consumer + + + // todo ",consumerGroup=" + consumer.getClass().getConsumerGroup() + + ",topic=" + event.getSubject() + + + ",subscriptionItem=" + subscriptionItem + + + ",createTime=" + DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT) + + + ",executeTime=" + DateFormatUtils.format(executeTime, EventMeshConstants.DATE_FORMAT) + + + ",lastPushTime=" + DateFormatUtils.format(lastPushTime, EventMeshConstants.DATE_FORMAT) + + '}'; + } + + @Override + public void retry() { + try { + logger.info("retry downStream msg start,seq:{},retryTimes:{},bizSeq:{}", this.seq, this.retryTimes, + EventMeshUtil.getMessageBizSeq(this.event)); + + if (isRetryMsgTimeout(this)) { + return; + } + this.retryTimes++; + this.lastPushTime = System.currentTimeMillis(); + + Session rechoosen = null; + String topic = this.event.getSubject(); + if (!SubscriptionMode.BROADCASTING.equals(this.subscriptionItem.getMode())) { + rechoosen = this.session.getClientGroupWrapper() + .get().getDownstreamDispatchStrategy().select(this.session.getClientGroupWrapper().get().getSysId(), + topic, this.session.getClientGroupWrapper().get().getGroupConsumerSessions()); + } else { + rechoosen = this.session; + } + + if (rechoosen == null) { + logger.warn("retry, found no session to downstream msg,seq:{}, retryTimes:{}, bizSeq:{}", this.seq, + this.retryTimes, EventMeshUtil.getMessageBizSeq(this.event)); + } else { + this.session = rechoosen; + rechoosen.downstreamMsg(this); + logger.info("retry downStream msg end,seq:{},retryTimes:{},bizSeq:{}", this.seq, this.retryTimes, + EventMeshUtil.getMessageBizSeq(this.event)); + } + } catch (Exception e) { + logger.error("retry-dispatcher error!", e); + } + } + + private boolean isRetryMsgTimeout(DownStreamMsgContext downStreamMsgContext) { + boolean flag = false; + String ttlStr = (String) downStreamMsgContext.event.getExtension(EventMeshConstants.PROPERTY_MESSAGE_TTL); + long ttl = StringUtils.isNumeric(ttlStr) ? Long.parseLong(ttlStr) : EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS; + ; + + String storeTimeStr = (String) downStreamMsgContext.event.getExtension(EventMeshConstants.STORE_TIME); + long storeTimestamp = StringUtils.isNumeric(storeTimeStr) ? Long.parseLong(storeTimeStr) : 0; + String leaveTimeStr = (String) downStreamMsgContext.event.getExtension(EventMeshConstants.LEAVE_TIME); + long brokerCost = StringUtils.isNumeric(leaveTimeStr) ? Long.parseLong(leaveTimeStr) - storeTimestamp : 0; + + String arriveTimeStr = (String) downStreamMsgContext.event.getExtension(EventMeshConstants.ARRIVE_TIME); + long accessCost = StringUtils.isNumeric(arriveTimeStr) ? System.currentTimeMillis() - Long.parseLong(arriveTimeStr) + : 0; + + double elapseTime = brokerCost + accessCost; + if (elapseTime >= ttl) { + logger.warn("discard the retry because timeout, seq:{}, retryTimes:{}, bizSeq:{}", downStreamMsgContext.seq, + downStreamMsgContext.retryTimes, EventMeshUtil.getMessageBizSeq(downStreamMsgContext.event)); + flag = true; + eventMeshAckMsg(downStreamMsgContext); + } + return flag; + } + + /** + * eventMesh ack msg + * + * @param downStreamMsgContext + */ + private void eventMeshAckMsg(DownStreamMsgContext downStreamMsgContext) { + List msgExts = new ArrayList(); + msgExts.add(downStreamMsgContext.event); + logger.warn("eventMeshAckMsg topic:{}, seq:{}, bizSeq:{}", downStreamMsgContext.event.getSubject(), + downStreamMsgContext.seq, downStreamMsgContext.event.getExtension(EventMeshConstants.PROPERTY_MESSAGE_KEYS)); + downStreamMsgContext.consumer.updateOffset(msgExts, downStreamMsgContext.consumeConcurrentlyContext); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/PushContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/PushContext.java new file mode 100644 index 0000000000..7b721467f3 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/PushContext.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push; + +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PushContext { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private SessionPusher sessionPusher; + + public AtomicLong deliveredMsgsCount = new AtomicLong(0); + + public AtomicLong deliverFailMsgsCount = new AtomicLong(0); + + private ConcurrentHashMap unAckMsg = new ConcurrentHashMap(); + + private long createTime = System.currentTimeMillis(); + + public PushContext(SessionPusher sessionPusher) { + this.sessionPusher = sessionPusher; + } + + public void deliveredMsgCount() { + deliveredMsgsCount.incrementAndGet(); + } + + public void deliverFailMsgCount() { + deliverFailMsgsCount.incrementAndGet(); + } + + public void unAckMsg(String seq, DownStreamMsgContext downStreamMsgContext) { + unAckMsg.put(seq, downStreamMsgContext); + logger.info("put msg in unAckMsg,seq:{},unAckMsgSize:{}", seq, getTotalUnackMsgs()); + } + + public int getTotalUnackMsgs() { + return unAckMsg.size(); + } + + + public ConcurrentHashMap getUnAckMsg() { + return unAckMsg; + } + + @Override + public String toString() { + return "PushContext{" + + + "deliveredMsgsCount=" + deliveredMsgsCount.longValue() + + + ",deliverFailCount=" + deliverFailMsgsCount.longValue() + + + ",unAckMsg=" + CollectionUtils.size(unAckMsg) + + + ",createTime=" + DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT) + '}'; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/SessionPusher.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/SessionPusher.java new file mode 100644 index 0000000000..f368063889 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/push/SessionPusher.java @@ -0,0 +1,185 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.opentelemetry.api.trace.Span; + +public class SessionPusher { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private AtomicLong deliveredMsgsCount = new AtomicLong(0); + + private AtomicLong deliverFailMsgsCount = new AtomicLong(0); + + private ConcurrentHashMap downStreamMap = new ConcurrentHashMap(); + + private Session session; + + public SessionPusher(Session session) { + this.session = session; + } + + @Override + public String toString() { + return "SessionPusher{" + + + "deliveredMsgsCount=" + deliveredMsgsCount.longValue() + + + ",deliverFailCount=" + deliverFailMsgsCount.longValue() + + + ",unAckMsg=" + CollectionUtils.size(downStreamMap) + '}'; + } + + public void push(final DownStreamMsgContext downStreamMsgContext) { + Command cmd; + if (SubscriptionMode.BROADCASTING.equals(downStreamMsgContext.subscriptionItem.getMode())) { + cmd = Command.BROADCAST_MESSAGE_TO_CLIENT; + } else if (SubscriptionType.SYNC.equals(downStreamMsgContext.subscriptionItem.getType())) { + cmd = Command.REQUEST_TO_CLIENT; + } else { + cmd = Command.ASYNC_MESSAGE_TO_CLIENT; + } + + String protocolType = Objects.requireNonNull(downStreamMsgContext.event.getExtension(Constants.PROTOCOL_TYPE)).toString(); + + ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + + Package pkg = new Package(); + + downStreamMsgContext.event = CloudEventBuilder.from(downStreamMsgContext.event) + .withExtension(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.RSP_SYS, session.getClient().getSubsystem()) + .withExtension(EventMeshConstants.RSP_GROUP, session.getClient().getGroup()) + .withExtension(EventMeshConstants.RSP_IDC, session.getClient().getIdc()) + .withExtension(EventMeshConstants.RSP_IP, session.getClient().getHost()) + .build(); + EventMeshMessage body = null; + int retCode = 0; + String retMsg = null; + try { + pkg = (Package) protocolAdaptor.fromCloudEvent(downStreamMsgContext.event); + pkg.setHeader(new Header(cmd, OPStatus.SUCCESS.getCode(), null, downStreamMsgContext.seq)); + pkg.getHeader().putProperty(Constants.PROTOCOL_TYPE, protocolType); + messageLogger.info("pkg|mq2eventMesh|cmd={}|mqMsg={}|user={}", cmd, pkg, session.getClient()); + } catch (Exception e) { + pkg.setHeader(new Header(cmd, OPStatus.FAIL.getCode(), e.getStackTrace().toString(), downStreamMsgContext.seq)); + retCode = -1; + retMsg = e.toString(); + } finally { + session.getClientGroupWrapper().get().getEventMeshTcpMonitor().getTcpSummaryMetrics().getEventMesh2clientMsgNum().incrementAndGet(); + + //TODO uploadTrace + String protocolVersion = Objects.requireNonNull(downStreamMsgContext.event.getSpecVersion()).toString(); + + Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, downStreamMsgContext.event), + EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_CLIENT_SPAN, false); + + try { + session.getContext().writeAndFlush(pkg).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + logger.error("downstreamMsg fail,seq:{}, retryTimes:{}, event:{}", downStreamMsgContext.seq, + downStreamMsgContext.retryTimes, downStreamMsgContext.event); + deliverFailMsgsCount.incrementAndGet(); + + //how long to isolate client when push fail + long isolateTime = System.currentTimeMillis() + + session.getEventMeshTCPConfiguration().eventMeshTcpPushFailIsolateTimeInMills; + session.setIsolateTime(isolateTime); + logger.warn("isolate client:{},isolateTime:{}", session.getClient(), isolateTime); + + //retry + long delayTime = SubscriptionType.SYNC.equals(downStreamMsgContext.subscriptionItem.getType()) + ? session.getEventMeshTCPConfiguration().eventMeshTcpMsgRetrySyncDelayInMills + : session.getEventMeshTCPConfiguration().eventMeshTcpMsgRetryAsyncDelayInMills; + downStreamMsgContext.delay(delayTime); + session.getClientGroupWrapper().get().getEventMeshTcpRetryer().pushRetry(downStreamMsgContext); + } else { + deliveredMsgsCount.incrementAndGet(); + logger.info("downstreamMsg success,seq:{}, retryTimes:{}, bizSeq:{}", downStreamMsgContext.seq, + downStreamMsgContext.retryTimes, EventMeshUtil.getMessageBizSeq(downStreamMsgContext.event)); + + if (session.isIsolated()) { + logger.info("cancel isolated,client:{}", session.getClient()); + session.setIsolateTime(System.currentTimeMillis()); + } + } + } + } + ); + } finally { + TraceUtils.finishSpan(span, downStreamMsgContext.event); + } + + } + } + + public void unAckMsg(String seq, DownStreamMsgContext downStreamMsgContext) { + downStreamMap.put(seq, downStreamMsgContext); + logger.info("put msg in unAckMsg,seq:{},unAckMsgSize:{}", seq, getTotalUnackMsgs()); + } + + public int getTotalUnackMsgs() { + return downStreamMap.size(); + } + + public ConcurrentHashMap getUnAckMsg() { + return downStreamMap; + } + + public AtomicLong getDeliveredMsgsCount() { + return deliveredMsgsCount; + } + + public AtomicLong getDeliverFailMsgsCount() { + return deliverFailMsgsCount; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/EventMeshTcpRetryer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/EventMeshTcpRetryer.java new file mode 100644 index 0000000000..55641ae97a --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/EventMeshTcpRetryer.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry; + +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.DownStreamMsgContext; +import org.apache.eventmesh.runtime.util.EventMeshThreadFactoryImpl; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventMeshTcpRetryer { + + public static Logger logger = LoggerFactory.getLogger(EventMeshTcpRetryer.class); + + private EventMeshTCPServer eventMeshTCPServer; + + private DelayQueue retrys = new DelayQueue(); + + private ThreadPoolExecutor pool = new ThreadPoolExecutor(3, + 3, + 60000, + TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1000), + new EventMeshThreadFactoryImpl("eventMesh-tcp-retry", true), + new ThreadPoolExecutor.AbortPolicy()); + + private Thread dispatcher; + + public EventMeshTcpRetryer(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + public EventMeshTCPServer getEventMeshTCPServer() { + return eventMeshTCPServer; + } + + public void setEventMeshTCPServer(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + public void pushRetry(RetryContext retryContext) { + if (retrys.size() >= eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpMsgRetryQueueSize) { + logger.error("pushRetry fail,retrys is too much,allow max retryQueueSize:{}, retryTimes:{}, seq:{}, bizSeq:{}", + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpMsgRetryQueueSize, retryContext.retryTimes, + retryContext.seq, EventMeshUtil.getMessageBizSeq(retryContext.event)); + return; + } + + int maxRetryTimes = eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpMsgAsyncRetryTimes; + if (retryContext instanceof DownStreamMsgContext) { + DownStreamMsgContext downStreamMsgContext = (DownStreamMsgContext) retryContext; + maxRetryTimes = SubscriptionType.SYNC.equals(downStreamMsgContext.subscriptionItem.getType()) + ? eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpMsgSyncRetryTimes : + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshTcpMsgAsyncRetryTimes; + } + + if (retryContext.retryTimes >= maxRetryTimes) { + logger.warn("pushRetry fail,retry over maxRetryTimes:{}, retryTimes:{}, seq:{}, bizSeq:{}", maxRetryTimes, + retryContext.retryTimes, retryContext.seq, EventMeshUtil.getMessageBizSeq(retryContext.event)); + return; + } + + retrys.offer(retryContext); + logger.info("pushRetry success,seq:{}, retryTimes:{}, bizSeq:{}", retryContext.seq, retryContext.retryTimes, + EventMeshUtil.getMessageBizSeq(retryContext.event)); + } + + public void init() { + dispatcher = new Thread(() -> { + try { + RetryContext retryContext; + while ((retryContext = retrys.take()) != null) { + pool.execute(retryContext::retry); + } + } catch (Exception e) { + logger.error("retry-dispatcher error!", e); + } + }, "retry-dispatcher"); + dispatcher.setDaemon(true); + logger.info("EventMeshTcpRetryer inited......"); + } + + public void start() throws Exception { + dispatcher.start(); + logger.info("EventMeshTcpRetryer started......"); + } + + public void shutdown() { + pool.shutdown(); + logger.info("EventMeshTcpRetryer shutdown......"); + } + + public int getRetrySize() { + return retrys.size(); + } + + public void printRetryThreadPoolState() { + //ThreadPoolHelper.printState(pool); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/RetryContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/RetryContext.java new file mode 100644 index 0000000000..9a5359ee01 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/RetryContext.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry; + +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +import io.cloudevents.CloudEvent; + +public abstract class RetryContext implements Delayed { + + public CloudEvent event; + + public String seq; + + public int retryTimes = 0; + + public long executeTime = System.currentTimeMillis(); + + public RetryContext delay(long delay) { + this.executeTime = System.currentTimeMillis() + (retryTimes + 1) * delay; + return this; + } + + @Override + public int compareTo(Delayed delayed) { + RetryContext obj = (RetryContext) delayed; + if (this.executeTime > obj.executeTime) { + return 1; + } else if (this.executeTime == obj.executeTime) { + return 0; + } else { + return -1; + } + } + + @Override + public long getDelay(TimeUnit unit) { + return unit.convert(this.executeTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + + public abstract void retry(); +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/EventMeshTcpSendResult.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/EventMeshTcpSendResult.java new file mode 100644 index 0000000000..61c4d041e4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/EventMeshTcpSendResult.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send; + +public class EventMeshTcpSendResult { + + private String seq; + + private EventMeshTcpSendStatus sendStatus; + + private String detail; + + public EventMeshTcpSendResult(String seq, EventMeshTcpSendStatus sendStatus, String detail) { + this.seq = seq; + this.sendStatus = sendStatus; + this.detail = detail; + } + + public String getSeq() { + return seq; + } + + public EventMeshTcpSendStatus getSendStatus() { + return sendStatus; + } + + public String getDetail() { + return detail; + } + + @Override + public String toString() { + return "EventMeshTcpSendResult{seq=" + seq + + ",sendStatus=" + sendStatus + + ",detail=" + detail + "}"; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/EventMeshTcpSendStatus.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/EventMeshTcpSendStatus.java new file mode 100644 index 0000000000..75d0823630 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/EventMeshTcpSendStatus.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send; + +public enum EventMeshTcpSendStatus { + SUCCESS, + SEND_TOO_FAST, + OTHER_EXCEPTION; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/SessionSender.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/SessionSender.java new file mode 100644 index 0000000000..b9e4e81758 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/SessionSender.java @@ -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 org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.Utils; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.util.Objects; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.opentelemetry.api.trace.Span; + +public class SessionSender { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + private final Logger logger = LoggerFactory.getLogger(SessionSender.class); + + private Session session; + + public long createTime = System.currentTimeMillis(); + + public AtomicLong upMsgs = new AtomicLong(0); + + public AtomicLong failMsgCount = new AtomicLong(0); + + private static final int TRY_PERMIT_TIME_OUT = 5; + + @Override + public String toString() { + return "SessionSender{upstreamBuff=" + upstreamBuff.availablePermits() + + + ",upMsgs=" + upMsgs.longValue() + + + ",failMsgCount=" + failMsgCount.longValue() + + + ",createTime=" + DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT) + '}'; + } + + public Semaphore getUpstreamBuff() { + return upstreamBuff; + } + + private Semaphore upstreamBuff; + + public SessionSender(Session session) { + this.session = session; + this.upstreamBuff = new Semaphore(session.getEventMeshTCPConfiguration().eventMeshTcpSessionUpstreamBufferSize); + } + + public EventMeshTcpSendResult send(Header header, CloudEvent event, SendCallback sendCallback, long startTime, long taskExecuteTime) { + try { + if (upstreamBuff.tryAcquire(TRY_PERMIT_TIME_OUT, TimeUnit.MILLISECONDS)) { + upMsgs.incrementAndGet(); + UpStreamMsgContext upStreamMsgContext = null; + Command cmd = header.getCmd(); + + String protocolVersion = header.getProperty(Constants.PROTOCOL_VERSION).toString(); + + long ttl = EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS; + if (Command.REQUEST_TO_SERVER == cmd) { + if (event.getExtension(EventMeshConstants.PROPERTY_MESSAGE_TTL) != null) { + ttl = Long.parseLong((String) Objects.requireNonNull( + event.getExtension(EventMeshConstants.PROPERTY_MESSAGE_TTL))); + } + upStreamMsgContext = new UpStreamMsgContext(session, event, header, startTime, taskExecuteTime); + + Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN, false); + try { + session.getClientGroupWrapper().get() + .request(upStreamMsgContext, initSyncRRCallback(header, + startTime, taskExecuteTime, event), ttl); + upstreamBuff.release(); + } finally { + TraceUtils.finishSpan(span, event); + } + } else if (Command.RESPONSE_TO_SERVER == cmd) { + String cluster = (String) event.getExtension(EventMeshConstants.PROPERTY_MESSAGE_CLUSTER); + if (!StringUtils.isEmpty(cluster)) { + String replyTopic = EventMeshConstants.RR_REPLY_TOPIC; + replyTopic = cluster + "-" + replyTopic; + event = CloudEventBuilder.from(event).withSubject(replyTopic).build(); + } + + upStreamMsgContext = new UpStreamMsgContext(session, event, header, startTime, taskExecuteTime); + session.getClientGroupWrapper().get().reply(upStreamMsgContext); + upstreamBuff.release(); + } else { + upStreamMsgContext = new UpStreamMsgContext(session, event, header, startTime, taskExecuteTime); + + Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN, false); + try { + session.getClientGroupWrapper().get() + .send(upStreamMsgContext, sendCallback); + } finally { + TraceUtils.finishSpan(span, event); + } + } + + session.getClientGroupWrapper().get().getEventMeshTcpMonitor().getTcpSummaryMetrics().getEventMesh2mqMsgNum().incrementAndGet(); + } else { + logger.warn("send too fast,session flow control,session:{}", session.getClient()); + return new EventMeshTcpSendResult(header.getSeq(), EventMeshTcpSendStatus.SEND_TOO_FAST, EventMeshTcpSendStatus.SEND_TOO_FAST.name()); + } + } catch (Exception e) { + logger.warn("SessionSender send failed", e); + if (!(e instanceof InterruptedException)) { + upstreamBuff.release(); + } + failMsgCount.incrementAndGet(); + return new EventMeshTcpSendResult(header.getSeq(), EventMeshTcpSendStatus.OTHER_EXCEPTION, e.getCause().toString()); + } + return new EventMeshTcpSendResult(header.getSeq(), EventMeshTcpSendStatus.SUCCESS, EventMeshTcpSendStatus.SUCCESS.name()); + } + + private RequestReplyCallback initSyncRRCallback(Header header, long startTime, long taskExecuteTime, CloudEvent cloudEvent) { + return new RequestReplyCallback() { + @Override + public void onSuccess(CloudEvent event) { + String seq = header.getSeq(); + // TODO: How to assign values here + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.RSP_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .withExtension(EventMeshConstants.RSP_RECEIVE_EVENTMESH_IP, session.getEventMeshTCPConfiguration().eventMeshServerIp) + .build(); + session.getClientGroupWrapper().get().getEventMeshTcpMonitor().getTcpSummaryMetrics().getMq2eventMeshMsgNum().incrementAndGet(); + + Command cmd; + if (header.getCmd().equals(Command.REQUEST_TO_SERVER)) { + cmd = Command.RESPONSE_TO_CLIENT; + } else { + messageLogger.error("invalid message|messageHeader={}|event={}", header, event); + return; + } + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.RSP_EVENTMESH2C_TIMESTAMP, String.valueOf(System.currentTimeMillis())) + .build(); + String protocolType = Objects.requireNonNull(event.getExtension(Constants.PROTOCOL_TYPE)).toString(); + + ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + + Package pkg = new Package(); + + try { + pkg = (Package) protocolAdaptor.fromCloudEvent(event); + pkg.setHeader(new Header(cmd, OPStatus.SUCCESS.getCode(), null, seq)); + pkg.getHeader().putProperty(Constants.PROTOCOL_TYPE, protocolType); + } catch (Exception e) { + pkg.setHeader(new Header(cmd, OPStatus.FAIL.getCode(), null, seq)); + } finally { + Utils.writeAndFlush(pkg, startTime, taskExecuteTime, session.getContext(), session); + + TraceUtils.finishSpan(session.getContext(), event); + } + } + + @Override + public void onException(Throwable e) { + messageLogger.error("exception occur while sending RR message|user={}", session.getClient(), new Exception(e)); + + TraceUtils.finishSpanWithException(session.getContext(), cloudEvent, "exception occur while sending RR message", e); + } + }; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/UpStreamMsgContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/UpStreamMsgContext.java new file mode 100644 index 0000000000..74b140a64e --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/send/UpStreamMsgContext.java @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry.RetryContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.Utils; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class UpStreamMsgContext extends RetryContext { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Session session; + + private long createTime = System.currentTimeMillis(); + + private Header header; + + private long startTime; + + private long taskExecuteTime; + + public UpStreamMsgContext(Session session, CloudEvent event, Header header, long startTime, long taskExecuteTime) { + this.seq = header.getSeq(); + this.session = session; + this.event = event; + this.header = header; + this.startTime = startTime; + this.taskExecuteTime = taskExecuteTime; + } + + public Session getSession() { + return session; + } + + public CloudEvent getEvent() { + return event; + } + + public long getCreateTime() { + return createTime; + } + + @Override + public String toString() { + return "UpStreamMsgContext{seq=" + seq + + ",topic=" + event.getSubject() + + ",client=" + session.getClient() + + ",retryTimes=" + retryTimes + + ",createTime=" + DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT) + "}" + + ",executeTime=" + DateFormatUtils.format(executeTime, EventMeshConstants.DATE_FORMAT); + } + + @Override + public void retry() { + logger.info("retry upStream msg start,seq:{},retryTimes:{},bizSeq:{}", this.seq, this.retryTimes, + EventMeshUtil.getMessageBizSeq(this.event)); + + try { + Command replyCmd = getReplyCmd(header.getCmd()); + long sendTime = System.currentTimeMillis(); + + retryTimes++; + + // check session availability + if (session.isRunning()) { + EventMeshTcpSendResult sendStatus = session.upstreamMsg(header, event, + createSendCallback(replyCmd, taskExecuteTime, event, this), startTime, taskExecuteTime); + + if (StringUtils.equals(EventMeshTcpSendStatus.SUCCESS.name(), sendStatus.getSendStatus().name())) { + logger.info("pkg|eventMesh2mq|cmd={}|event={}|user={}|wait={}ms|cost={}ms", header.getCmd(), event, + session.getClient(), taskExecuteTime - startTime, sendTime - startTime); + } else { + throw new Exception(sendStatus.getDetail()); + } + } + } catch (Exception e) { + logger.error("TCP UpstreamMsg Retry error", e); + } + } + + protected SendCallback createSendCallback(Command replyCmd, long taskExecuteTime, CloudEvent event, UpStreamMsgContext retryContext) { + final long createTime = System.currentTimeMillis(); + Package msg = new Package(); + + return new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + session.getSender().getUpstreamBuff().release(); + logger.info("upstreamMsg message success|user={}|callback cost={}", session.getClient(), + System.currentTimeMillis() - createTime); + if (replyCmd.equals(Command.BROADCAST_MESSAGE_TO_SERVER_ACK) || replyCmd.equals(Command + .ASYNC_MESSAGE_TO_SERVER_ACK)) { + msg.setHeader(new Header(replyCmd, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), seq)); + msg.setBody(event); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + } + } + + @Override + public void onException(OnExceptionContext context) { + session.getSender().getUpstreamBuff().release(); + + // retry + // reset delay time + retryContext.delay(10000); + session.getClientGroupWrapper().get().getEventMeshTcpRetryer().pushRetry(retryContext); + + session.getSender().failMsgCount.incrementAndGet(); + logger.error("upstreamMsg mq message error|user={}|callback cost={}, errMsg={}", session.getClient(), + System.currentTimeMillis() - createTime, new Exception(context.getException())); + msg.setHeader(new Header(replyCmd, OPStatus.FAIL.getCode(), context.getException().toString(), seq)); + msg.setBody(event); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + } + + }; + } + + private Command getReplyCmd(Command cmd) { + switch (cmd) { + case REQUEST_TO_SERVER: + return Command.RESPONSE_TO_CLIENT; + case ASYNC_MESSAGE_TO_SERVER: + return Command.ASYNC_MESSAGE_TO_SERVER_ACK; + case BROADCAST_MESSAGE_TO_SERVER: + return Command.BROADCAST_MESSAGE_TO_SERVER_ACK; + default: + return cmd; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/AbstractTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/AbstractTask.java new file mode 100644 index 0000000000..560ccf4be6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/AbstractTask.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public abstract class AbstractTask implements Runnable { + + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected Package pkg; + protected ChannelHandlerContext ctx; + protected Session session; + protected long startTime; + protected EventMeshTCPServer eventMeshTCPServer; + + public AbstractTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.pkg = pkg; + this.ctx = ctx; + this.session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + this.startTime = startTime; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/GoodbyeTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/GoodbyeTask.java new file mode 100644 index 0000000000..0eeabf2dcd --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/GoodbyeTask.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import static org.apache.eventmesh.common.protocol.tcp.Command.CLIENT_GOODBYE_RESPONSE; + +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.util.Utils; + +import io.netty.channel.ChannelHandlerContext; + +public class GoodbyeTask extends AbstractTask { + + public GoodbyeTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Package msg = new Package(); + try { + if (pkg.getHeader().getCmd() == Command.SERVER_GOODBYE_RESPONSE) { + logger.info("client|address={}| has reject ", session.getContext().channel().remoteAddress()); + } else { + msg.setHeader( + new Header(CLIENT_GOODBYE_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), + pkg.getHeader().getSeq())); + } + } catch (Exception e) { + logger.error("GoodbyeTask failed|user={}|errMsg={}", session.getClient(), e); + msg.setHeader(new Header(CLIENT_GOODBYE_RESPONSE, OPStatus.FAIL.getCode(), e.getStackTrace().toString(), pkg + .getHeader().getSeq())); + } finally { + this.eventMeshTCPServer.getScheduler().submit(new Runnable() { + @Override + public void run() { + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + } + }); + //session.write2Client(msg); + } + EventMeshTcp2Client + .closeSessionIfTimeout(this.eventMeshTCPServer, session, eventMeshTCPServer.getClientSessionGroupMapping()); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HeartBeatTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HeartBeatTask.java new file mode 100644 index 0000000000..099b34638b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HeartBeatTask.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import static org.apache.eventmesh.common.protocol.tcp.Command.HEARTBEAT_REQUEST; +import static org.apache.eventmesh.common.protocol.tcp.Command.HEARTBEAT_RESPONSE; + +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; + +import io.netty.channel.ChannelHandlerContext; + +public class HeartBeatTask extends AbstractTask { + + public HeartBeatTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Package res = new Package(); + try { + //do acl check in heartbeat + if (eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + Acl.doAclCheckInTcpHeartbeat(remoteAddr, session.getClient(), HEARTBEAT_REQUEST.value()); + } + + if (session != null) { + session.notifyHeartbeat(startTime); + } + res.setHeader(new Header(HEARTBEAT_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), pkg.getHeader().getSeq())); + } catch (Exception e) { + logger.error("HeartBeatTask failed|user={}|errMsg={}", session.getClient(), e); + res.setHeader(new Header(HEARTBEAT_RESPONSE, OPStatus.FAIL.getCode(), "exception while " + + "heartbeating", pkg.getHeader().getSeq())); + } finally { + Utils.writeAndFlush(res, startTime, taskExecuteTime, session.getContext(), session); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HelloTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HelloTask.java new file mode 100644 index 0000000000..bde0659064 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HelloTask.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import static org.apache.eventmesh.common.protocol.tcp.Command.HELLO_REQUEST; +import static org.apache.eventmesh.common.protocol.tcp.Command.HELLO_RESPONSE; + +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; + +import org.apache.commons.lang3.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; + +public class HelloTask extends AbstractTask { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + public HelloTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Package res = new Package(); + Session session = null; + UserAgent user = (UserAgent) pkg.getBody(); + try { + //do acl check in connect + if (eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + Acl.doAclCheckInTcpConnect(remoteAddr, user, HELLO_REQUEST.value()); + } + + if (eventMeshTCPServer.getEventMeshServer().getServiceState() != ServiceState.RUNNING) { + logger.error("server state is not running:{}", eventMeshTCPServer.getEventMeshServer().getServiceState()); + throw new Exception("server state is not running, maybe deploying..."); + } + + validateUserAgent(user); + session = eventMeshTCPServer.getClientSessionGroupMapping().createSession(user, ctx); + res.setHeader(new Header(HELLO_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), pkg.getHeader().getSeq())); + Utils.writeAndFlush(res, startTime, taskExecuteTime, session.getContext(), session); + } catch (Throwable e) { + messageLogger.error("HelloTask failed|address={},errMsg={}", ctx.channel().remoteAddress(), e); + res.setHeader(new Header(HELLO_RESPONSE, OPStatus.FAIL.getCode(), e.getStackTrace().toString(), pkg + .getHeader().getSeq())); + ctx.writeAndFlush(res).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + Utils.logFailedMessageFlow(future, res, user, startTime, taskExecuteTime); + } else { + Utils.logSucceedMessageFlow(res, user, startTime, taskExecuteTime); + } + logger.warn("HelloTask failed,close session,addr:{}", ctx.channel().remoteAddress()); + eventMeshTCPServer.getClientSessionGroupMapping().closeSession(ctx); + } + } + ); + } + } + + private void validateUserAgent(UserAgent user) throws Exception { + if (user == null) { + throw new Exception("client info cannot be null"); + } + + if (user.getVersion() == null) { + throw new Exception("client version cannot be null"); + } + + if (!(StringUtils.equals(EventMeshConstants.PURPOSE_PUB, user.getPurpose()) || StringUtils.equals( + EventMeshConstants.PURPOSE_SUB, user.getPurpose()))) { + + throw new Exception("client purpose config is error"); + } + + if (StringUtils.isBlank(user.getGroup())) { + throw new Exception("client group cannot be null"); + } + + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/ListenTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/ListenTask.java new file mode 100644 index 0000000000..8c606154ab --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/ListenTask.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import static org.apache.eventmesh.common.protocol.tcp.Command.LISTEN_RESPONSE; + +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; + +import io.netty.channel.ChannelHandlerContext; + +public class ListenTask extends AbstractTask { + + public ListenTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Header header = new Header(LISTEN_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), pkg.getHeader().getSeq()); + session.setListenRequestSeq(pkg.getHeader().getSeq()); + try { + synchronized (session) { + eventMeshTCPServer.getClientSessionGroupMapping().readySession(session); + } + } catch (Exception e) { + logger.error("ListenTask failed|user={}|errMsg={}", session.getClient(), e); + Integer status = OPStatus.FAIL.getCode(); + header = new Header(LISTEN_RESPONSE, status, e.toString(), pkg.getHeader().getSeq()); + } finally { + //check to avoid send repeatedly + session.trySendListenResponse(header, startTime, taskExecuteTime); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageAckTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageAckTask.java new file mode 100644 index 0000000000..a01615babc --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageAckTask.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.DownStreamMsgContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class MessageAckTask extends AbstractTask { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + public MessageAckTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + String seq = pkg.getHeader().getSeq(); + Command cmd = pkg.getHeader().getCmd(); + + if (seq == null) { + logger.error("MessageAckTask failed, seq cannot be null|user={}", session.getClient()); + return; + } + DownStreamMsgContext downStreamMsgContext = session.getPusher().getUnAckMsg().get(seq); + // ack non-broadcast msg + if (downStreamMsgContext != null) { + downStreamMsgContext.ackMsg(); + session.getPusher().getUnAckMsg().remove(seq); + } else { + if (!cmd.equals(Command.RESPONSE_TO_CLIENT_ACK)) { + logger.warn("MessageAckTask, seq:{}, downStreamMsgContext not in downStreamMap,client:{}", + seq, session.getClient()); + } + } + messageLogger.info("pkg|c2eventMesh|cmd={}|seq=[{}]|user={}|wait={}ms|cost={}ms", cmd, seq, session.getClient(), + taskExecuteTime - startTime, System.currentTimeMillis() - startTime); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageTransferTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageTransferTask.java new file mode 100644 index 0000000000..cb249a0cfa --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageTransferTask.java @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import static org.apache.eventmesh.common.protocol.tcp.Command.RESPONSE_TO_SERVER; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.EventMeshTcpSendResult; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.EventMeshTcpSendStatus; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.UpStreamMsgContext; +import org.apache.eventmesh.runtime.trace.AttributeKeys; +import org.apache.eventmesh.runtime.trace.SpanKey; +import org.apache.eventmesh.runtime.trace.TraceUtils; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Context; + +public class MessageTransferTask extends AbstractTask { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + private static final int TRY_PERMIT_TIME_OUT = 5; + + public MessageTransferTask(Package pkg, ChannelHandlerContext ctx, long startTime, + EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Command cmd = pkg.getHeader().getCmd(); + + try { + if (eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerTraceEnable && !RESPONSE_TO_SERVER.equals(cmd)) { + //attach the span to the server context + Span span = TraceUtils.prepareServerSpan(pkg.getHeader().getProperties(), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, + startTime, TimeUnit.MILLISECONDS, true); + Context context = Context.current().with(SpanKey.SERVER_KEY, span); + //put the context in channel + ctx.channel().attr(AttributeKeys.SERVER_CONTEXT).set(context); + } + } catch (Throwable ex) { + logger.warn("upload trace fail in MessageTransferTask[server-span-start]", ex); + } + + + Command replyCmd = getReplyCmd(cmd); + Package msg = new Package(); + + int retCode = 0; + EventMeshTcpSendResult sendStatus; + CloudEvent event = null; + + try { + String protocolType = "eventmeshmessage"; + if (pkg.getHeader().getProperties() != null + && pkg.getHeader().getProperty(Constants.PROTOCOL_TYPE) != null) { + protocolType = (String) pkg.getHeader().getProperty(Constants.PROTOCOL_TYPE); + } + ProtocolAdaptor protocolAdaptor = + ProtocolPluginFactory.getProtocolAdaptor(protocolType); + event = protocolAdaptor.toCloudEvent(pkg); + + if (event == null) { + throw new Exception("event is null"); + } + + String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); + if (content.length() > eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshEventSize) { + throw new Exception("event size exceeds the limit: " + + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshEventSize); + } + + //do acl check in sending msg + if (eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + Acl.doAclCheckInTcpSend(remoteAddr, session.getClient(), event.getSubject(), + cmd.value()); + } + + if (!eventMeshTCPServer.getRateLimiter() + .tryAcquire(TRY_PERMIT_TIME_OUT, TimeUnit.MILLISECONDS)) { + + msg.setHeader(new Header(replyCmd, OPStatus.FAIL.getCode(), + "Tps overload, global flow control", + pkg.getHeader().getSeq())); + ctx.writeAndFlush(msg).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + Utils.logSucceedMessageFlow(msg, session.getClient(), startTime, + taskExecuteTime); + } + } + ); + + TraceUtils.finishSpanWithException(ctx, event, "Tps overload, global flow control", + null); + + logger.warn( + "======Tps overload, global flow control, rate:{}! PLEASE CHECK!========", + eventMeshTCPServer.getRateLimiter().getRate()); + return; + } + + synchronized (session) { + long sendTime = System.currentTimeMillis(); + event = addTimestamp(event, cmd, sendTime); + + sendStatus = session + .upstreamMsg(pkg.getHeader(), event, + createSendCallback(replyCmd, taskExecuteTime, event), + startTime, taskExecuteTime); + + if (StringUtils.equals(EventMeshTcpSendStatus.SUCCESS.name(), + sendStatus.getSendStatus().name())) { + messageLogger.info("pkg|eventMesh2mq|cmd={}|Msg={}|user={}|wait={}ms|cost={}ms", + cmd, event, + session.getClient(), taskExecuteTime - startTime, sendTime - startTime); + } else { + throw new Exception(sendStatus.getDetail()); + } + } + } catch (Exception e) { + logger.error("MessageTransferTask failed|cmd={}|event={}|user={}", cmd, event, + session.getClient(), + e); + + if (!cmd.equals(RESPONSE_TO_SERVER)) { + msg.setHeader( + new Header(replyCmd, OPStatus.FAIL.getCode(), e.toString(), + pkg.getHeader() + .getSeq())); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + + if (event != null) { + TraceUtils.finishSpanWithException(ctx, event, "MessageTransferTask failed", e); + } + } + } + } + + private CloudEvent addTimestamp(CloudEvent event, Command cmd, long sendTime) { + if (cmd.equals(RESPONSE_TO_SERVER)) { + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.RSP_C2EVENTMESH_TIMESTAMP, + String.valueOf(startTime)) + .withExtension(EventMeshConstants.RSP_EVENTMESH2MQ_TIMESTAMP, + String.valueOf(sendTime)) + .withExtension(EventMeshConstants.RSP_SEND_EVENTMESH_IP, + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerIp) + .build(); + } else { + event = CloudEventBuilder.from(event) + .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, + String.valueOf(startTime)) + .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, + String.valueOf(sendTime)) + .withExtension(EventMeshConstants.REQ_SEND_EVENTMESH_IP, + eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerIp) + .build(); + } + return event; + } + + private Command getReplyCmd(Command cmd) { + switch (cmd) { + case REQUEST_TO_SERVER: + return Command.RESPONSE_TO_CLIENT; + case ASYNC_MESSAGE_TO_SERVER: + return Command.ASYNC_MESSAGE_TO_SERVER_ACK; + case BROADCAST_MESSAGE_TO_SERVER: + return Command.BROADCAST_MESSAGE_TO_SERVER_ACK; + default: + return cmd; + } + } + + protected SendCallback createSendCallback(Command replyCmd, long taskExecuteTime, + CloudEvent event) { + final long createTime = System.currentTimeMillis(); + Package msg = new Package(); + + return new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + session.getSender().getUpstreamBuff().release(); + messageLogger.info("upstreamMsg message success|user={}|callback cost={}", + session.getClient(), + System.currentTimeMillis() - createTime); + if (replyCmd.equals(Command.BROADCAST_MESSAGE_TO_SERVER_ACK) + || replyCmd.equals(Command.ASYNC_MESSAGE_TO_SERVER_ACK)) { + msg.setHeader( + new Header(replyCmd, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), + pkg.getHeader().getSeq())); + msg.setBody(event); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), + session); + + //async request need finish span when callback, rr request will finish span when rrCallback + TraceUtils.finishSpan(ctx, event); + } + } + + @Override + public void onException(OnExceptionContext context) { + session.getSender().getUpstreamBuff().release(); + + // retry + UpStreamMsgContext upStreamMsgContext = new UpStreamMsgContext( + session, event, pkg.getHeader(), startTime, taskExecuteTime); + upStreamMsgContext.delay(10000); + session.getClientGroupWrapper().get().getEventMeshTcpRetryer() + .pushRetry(upStreamMsgContext); + + session.getSender().failMsgCount.incrementAndGet(); + messageLogger + .error("upstreamMsg mq message error|user={}|callback cost={}, errMsg={}", + session.getClient(), + (System.currentTimeMillis() - createTime), + new Exception(context.getException())); + msg.setHeader( + new Header(replyCmd, OPStatus.FAIL.getCode(), context.getException().toString(), + pkg.getHeader().getSeq())); + msg.setBody(event); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + + //both rr request and async request need finish span when reqeust fail + if (!replyCmd.equals(RESPONSE_TO_SERVER)) { + //upload trace + TraceUtils.finishSpanWithException(ctx, event, + "upload trace fail in MessageTransferTask.createSendCallback.onException", + context.getException()); + } + } + }; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/RecommendTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/RecommendTask.java new file mode 100644 index 0000000000..6499e8e948 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/RecommendTask.java @@ -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 org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import static org.apache.eventmesh.common.protocol.tcp.Command.RECOMMEND_RESPONSE; +import static org.apache.eventmesh.runtime.util.Utils.writeAndFlush; + +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend.EventMeshRecommendImpl; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend.EventMeshRecommendStrategy; + +import org.apache.commons.lang3.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class RecommendTask extends AbstractTask { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + public RecommendTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Package res = new Package(); + try { + if (!eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerRegistryEnable) { + throw new Exception("registry enable config is false, not support"); + } + UserAgent user = (UserAgent) pkg.getBody(); + validateUserAgent(user); + String group = getGroupOfClient(user); + EventMeshRecommendStrategy eventMeshRecommendStrategy = new EventMeshRecommendImpl(eventMeshTCPServer); + String eventMeshRecommendResult = eventMeshRecommendStrategy.calculateRecommendEventMesh(group, user.getPurpose()); + res.setHeader(new Header(RECOMMEND_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), pkg.getHeader().getSeq())); + res.setBody(eventMeshRecommendResult); + } catch (Exception e) { + messageLogger.error("RecommendTask failed|address={}|errMsg={}", ctx.channel().remoteAddress(), e); + res.setHeader(new Header(RECOMMEND_RESPONSE, OPStatus.FAIL.getCode(), e.toString(), pkg + .getHeader().getSeq())); + + } finally { + writeAndFlush(res, startTime, taskExecuteTime, session.getContext(), session); + //session.write2Client(res); + } + } + + private void validateUserAgent(UserAgent user) throws Exception { + if (user == null) { + throw new Exception("client info cannot be null"); + } + + if (user.getVersion() == null) { + throw new Exception("client version cannot be null"); + } + + if (user.getUsername() == null) { + throw new Exception("client wemqUser cannot be null"); + } + + if (user.getPassword() == null) { + throw new Exception("client wemqPasswd cannot be null"); + } + + if (!(StringUtils.equals(EventMeshConstants.PURPOSE_PUB, user.getPurpose()) || StringUtils.equals( + EventMeshConstants.PURPOSE_SUB, user.getPurpose()))) { + throw new Exception("client purpose config is error"); + } + } + + private String getGroupOfClient(UserAgent userAgent) { + if (userAgent == null) { + return null; + } + return userAgent.getGroup(); + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/SubscribeTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/SubscribeTask.java new file mode 100644 index 0000000000..852636c37d --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/SubscribeTask.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.Subscription; +import org.apache.eventmesh.runtime.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class SubscribeTask extends AbstractTask { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + public SubscribeTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Package msg = new Package(); + try { + Subscription subscriptionInfo = (Subscription) pkg.getBody(); + if (subscriptionInfo == null) { + throw new Exception("subscriptionInfo is null"); + } + + List subscriptionItems = new ArrayList<>(); + for (int i = 0; i < subscriptionInfo.getTopicList().size(); i++) { + SubscriptionItem item = subscriptionInfo.getTopicList().get(i); + + //do acl check for receive msg + if (eventMeshTCPServer.getEventMeshTCPConfiguration().eventMeshServerSecurityEnable) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + Acl.doAclCheckInTcpReceive(remoteAddr, session.getClient(), item.getTopic(), Command.SUBSCRIBE_REQUEST.value()); + } + + subscriptionItems.add(item); + } + synchronized (session) { + session.subscribe(subscriptionItems); + messageLogger.info("SubscribeTask succeed|user={}|topics={}", session.getClient(), subscriptionItems); + } + msg.setHeader(new Header(Command.SUBSCRIBE_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), pkg.getHeader() + .getSeq())); + } catch (Exception e) { + messageLogger.error("SubscribeTask failed|user={}|errMsg={}", session.getClient(), e); + msg.setHeader(new Header(Command.SUBSCRIBE_RESPONSE, OPStatus.FAIL.getCode(), e.toString(), pkg.getHeader() + .getSeq())); + } finally { + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + } + } + + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/UnSubscribeTask.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/UnSubscribeTask.java new file mode 100644 index 0000000000..15e3f70326 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/UnSubscribeTask.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.util.Utils; + +import org.apache.commons.collections4.MapUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class UnSubscribeTask extends AbstractTask { + + private final Logger messageLogger = LoggerFactory.getLogger("message"); + + public UnSubscribeTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { + super(pkg, ctx, startTime, eventMeshTCPServer); + } + + @Override + public void run() { + long taskExecuteTime = System.currentTimeMillis(); + Package msg = new Package(); + try { + synchronized (session) { + List topics = new ArrayList(); + if (MapUtils.isNotEmpty(session.getSessionContext().subscribeTopics)) { + for (Map.Entry entry : session.getSessionContext().subscribeTopics.entrySet()) { + topics.add(entry.getValue()); + } + session.unsubscribe(topics); + messageLogger.info("UnSubscriberTask succeed|user={}|topics={}", session.getClient(), topics); + } + } + msg.setHeader(new Header(Command.UNSUBSCRIBE_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), pkg.getHeader() + .getSeq())); + } catch (Exception e) { + messageLogger.error("UnSubscribeTask failed|user={}|errMsg={}", session.getClient(), e); + msg.setHeader(new Header(Command.UNSUBSCRIBE_RESPONSE, OPStatus.FAIL.getCode(), "exception while " + + + "unSubscribing", pkg.getHeader().getSeq())); + } finally { + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); + } + } + + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/MonitorMetricConstants.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/MonitorMetricConstants.java new file mode 100644 index 0000000000..60a2360ca1 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/MonitorMetricConstants.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.metrics; + +public class MonitorMetricConstants { + public static final String EVENTMESH_MONITOR_FORMAT_COMMON = "{\"protocol\":\"%s\",\"s\":\"%s\",\"t\":\"%s\"}"; + + public static final String EVENTMESH_TCP_MONITOR_FORMAT_THREADPOOL = "{\"threadPoolName\":\"%s\",\"s\":\"%s\",\"t\":\"%s\"}"; + + public static final String CLIENT_2_EVENTMESH_TPS = "client2eventMeshTPS"; + public static final String EVENTMESH_2_MQ_TPS = "eventMesh2mqTPS"; + public static final String MQ_2_EVENTMESH_TPS = "mq2eventMeshTPS"; + public static final String EVENTMESH_2_CLIENT_TPS = "eventMesh2clientTPS"; + public static final String ALL_TPS = "allTPS"; + public static final String CONNECTION = "connection"; + public static final String SUB_TOPIC_NUM = "subTopicNum"; + + public static final String RETRY_QUEUE_SIZE = "retryQueueSize"; + + + public static final String QUEUE_SIZE = "queueSize"; + public static final String POOL_SIZE = "poolSize"; + public static final String ACTIVE_COUNT = "activeCount"; + public static final String COMPLETED_TASK = "completedTask"; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/http/HTTPMetricsServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/http/HTTPMetricsServer.java new file mode 100644 index 0000000000..80fdc4d497 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/http/HTTPMetricsServer.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.metrics.http; + +import org.apache.eventmesh.metrics.api.MetricsRegistry; +import org.apache.eventmesh.metrics.api.model.HttpSummaryMetrics; +import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; + +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HTTPMetricsServer { + + private EventMeshHTTPServer eventMeshHTTPServer; + + private Logger httpLogger = LoggerFactory.getLogger("httpMonitor"); + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private List metricsRegistries; + + private final HttpSummaryMetrics summaryMetrics; + + public HTTPMetricsServer(EventMeshHTTPServer eventMeshHTTPServer, List metricsRegistries) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + this.metricsRegistries = metricsRegistries; + this.summaryMetrics = new HttpSummaryMetrics( + eventMeshHTTPServer.batchMsgExecutor, + eventMeshHTTPServer.sendMsgExecutor, + eventMeshHTTPServer.pushMsgExecutor, + eventMeshHTTPServer.getHttpRetryer().getFailedQueue()); + } + + public void init() throws Exception { + metricsRegistries.forEach(MetricsRegistry::start); + logger.info("HTTPMetricsServer initialized......"); + } + + public void start() throws Exception { + metricsRegistries.forEach(metricsRegistry -> { + metricsRegistry.register(summaryMetrics); + logger.info("Register httpMetrics to " + metricsRegistry.getClass().getName()); + }); + metricsSchedule.scheduleAtFixedRate(() -> { + try { + summaryMetrics.snapshotHTTPTPS(); + summaryMetrics.snapshotSendBatchMsgTPS(); + summaryMetrics.snapshotSendMsgTPS(); + summaryMetrics.snapshotPushMsgTPS(); + } catch (Exception ex) { + logger.warn("eventMesh snapshot tps metrics err", ex); + } + }, 0, 1000, TimeUnit.MILLISECONDS); + + metricsSchedule.scheduleAtFixedRate(() -> { + try { + logPrintServerMetrics(); + } catch (Exception ex) { + logger.warn("eventMesh print metrics err", ex); + } + }, 1000, 30 * 1000, TimeUnit.MILLISECONDS); + + logger.info("HTTPMetricsServer started......"); + } + + public void shutdown() throws Exception { + metricsSchedule.shutdown(); + metricsRegistries.forEach(MetricsRegistry::showdown); + logger.info("HTTPMetricsServer shutdown......"); + } + + protected static ScheduledExecutorService metricsSchedule = Executors.newScheduledThreadPool(2, new ThreadFactory() { + private AtomicInteger seq = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + seq.incrementAndGet(); + Thread t = new Thread(r, "eventMesh-metrics-" + seq.get()); + t.setDaemon(true); + return t; + } + }); + + // todo: move this into standalone metrics plugin + private void logPrintServerMetrics() { + httpLogger.info("===========================================SERVER METRICS=================================================="); + + httpLogger.info(String.format(HttpSummaryMetrics.EVENTMESH_MONITOR_FORMAT_HTTP, + summaryMetrics.maxHTTPTPS(), + summaryMetrics.avgHTTPTPS(), + summaryMetrics.maxHTTPCost(), + summaryMetrics.avgHTTPCost(), + summaryMetrics.avgHTTPBodyDecodeCost(), + summaryMetrics.getHttpDiscard())); + summaryMetrics.httpStatInfoClear(); + + httpLogger.info(String.format(HttpSummaryMetrics.EVENTMESH_MONITOR_FORMAT_BATCHSENDMSG, + summaryMetrics.maxSendBatchMsgTPS(), + summaryMetrics.avgSendBatchMsgTPS(), + summaryMetrics.getSendBatchMsgNumSum(), + summaryMetrics.getSendBatchMsgFailNumSum(), + summaryMetrics.getSendBatchMsgFailRate(), + summaryMetrics.getSendBatchMsgDiscardNumSum() + )); + summaryMetrics.cleanSendBatchStat(); + + httpLogger.info(String.format(HttpSummaryMetrics.EVENTMESH_MONITOR_FORMAT_SENDMSG, + summaryMetrics.maxSendMsgTPS(), + summaryMetrics.avgSendMsgTPS(), + summaryMetrics.getSendMsgNumSum(), + summaryMetrics.getSendMsgFailNumSum(), + summaryMetrics.getSendMsgFailRate(), + summaryMetrics.getReplyMsgNumSum(), + summaryMetrics.getReplyMsgFailNumSum() + )); + summaryMetrics.cleanSendMsgStat(); + + httpLogger.info(String.format(HttpSummaryMetrics.EVENTMESH_MONITOR_FORMAT_PUSHMSG, + summaryMetrics.maxPushMsgTPS(), + summaryMetrics.avgPushMsgTPS(), + summaryMetrics.getHttpPushMsgNumSum(), + summaryMetrics.getHttpPushFailNumSum(), + summaryMetrics.getHttpPushMsgFailRate(), + summaryMetrics.maxHTTPPushLatency(), + summaryMetrics.avgHTTPPushLatency() + )); + summaryMetrics.cleanHttpPushMsgStat(); + + httpLogger.info(String.format(HttpSummaryMetrics.EVENTMESH_MONITOR_FORMAT_BLOCKQ, + eventMeshHTTPServer.getBatchMsgExecutor().getQueue().size(), + eventMeshHTTPServer.getSendMsgExecutor().getQueue().size(), + eventMeshHTTPServer.getPushMsgExecutor().getQueue().size(), + eventMeshHTTPServer.getHttpRetryer().size())); + + httpLogger.info(String.format(HttpSummaryMetrics.EVENTMESH_MONITOR_FORMAT_MQ_CLIENT, + summaryMetrics.avgBatchSendMsgCost(), + summaryMetrics.avgSendMsgCost(), + summaryMetrics.avgReplyMsgCost())); + summaryMetrics.send2MQStatInfoClear(); + } + + public HttpSummaryMetrics getSummaryMetrics() { + return summaryMetrics; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/tcp/EventMeshTcpMonitor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/tcp/EventMeshTcpMonitor.java new file mode 100644 index 0000000000..63039a7220 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/tcp/EventMeshTcpMonitor.java @@ -0,0 +1,192 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.metrics.tcp; + +import org.apache.eventmesh.metrics.api.MetricsRegistry; +import org.apache.eventmesh.metrics.api.model.TcpSummaryMetrics; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcpConnectionHandler; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.metrics.MonitorMetricConstants; + +import java.net.InetSocketAddress; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; + +public class EventMeshTcpMonitor { + + private final EventMeshTCPServer eventMeshTCPServer; + + public EventMeshTCPServer getEventMeshTCPServer() { + return eventMeshTCPServer; + } + + private final Logger tcpLogger = LoggerFactory.getLogger("tcpMonitor"); + + private final Logger appLogger = LoggerFactory.getLogger("appMonitor"); + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static int delay = 60 * 1000; + + private static int period = 60 * 1000; + + private static int PRINT_THREADPOOLSTATE_INTERVAL = 1; + + public ScheduledFuture monitorTpsTask; + + public ScheduledFuture monitorThreadPoolTask; + + private final TcpSummaryMetrics tcpSummaryMetrics; + + private final List metricsRegistries; + + public EventMeshTcpMonitor(EventMeshTCPServer eventMeshTCPServer, List metricsRegistries) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.tcpSummaryMetrics = new TcpSummaryMetrics(); + this.metricsRegistries = Preconditions.checkNotNull(metricsRegistries); + } + + public void init() throws Exception { + metricsRegistries.forEach(MetricsRegistry::start); + logger.info("EventMeshTcpMonitor initialized......"); + } + + public void start() throws Exception { + metricsRegistries.forEach(metricsRegistry -> { + metricsRegistry.register(tcpSummaryMetrics); + logger.info("Register tcpMetrics to " + metricsRegistry.getClass().getName()); + }); + + monitorTpsTask = eventMeshTCPServer.getScheduler().scheduleAtFixedRate((() -> { + int msgNum = tcpSummaryMetrics.client2eventMeshMsgNum(); + tcpSummaryMetrics.setClient2eventMeshTPS(1000 * msgNum / period); + + msgNum = tcpSummaryMetrics.eventMesh2clientMsgNum(); + tcpSummaryMetrics.setEventMesh2clientTPS(1000 * msgNum / period); + + msgNum = tcpSummaryMetrics.eventMesh2mqMsgNum(); + tcpSummaryMetrics.setEventMesh2mqTPS(1000 * msgNum / period); + + msgNum = tcpSummaryMetrics.mq2eventMeshMsgNum(); + tcpSummaryMetrics.setMq2eventMeshTPS(1000 * msgNum / period); + + //count topics subscribed by client in this eventMesh + ConcurrentHashMap sessionMap = + eventMeshTCPServer.getClientSessionGroupMapping().getSessionMap(); + Iterator sessionIterator = sessionMap.values().iterator(); + Set topicSet = new HashSet<>(); + while (sessionIterator.hasNext()) { + Session session = sessionIterator.next(); + AtomicLong deliveredMsgsCount = session.getPusher().getDeliveredMsgsCount(); + AtomicLong deliveredFailCount = session.getPusher().getDeliverFailMsgsCount(); + int unAckMsgsCount = session.getPusher().getTotalUnackMsgs(); + int sendTopics = session.getSessionContext().sendTopics.size(); + int subscribeTopics = session.getSessionContext().subscribeTopics.size(); + + tcpLogger.info("session|deliveredFailCount={}|deliveredMsgsCount={}|unAckMsgsCount={}|sendTopics={}|subscribeTopics={}|user={}", + deliveredFailCount.longValue(), deliveredMsgsCount.longValue(), + unAckMsgsCount, sendTopics, subscribeTopics, session.getClient()); + + topicSet.addAll(session.getSessionContext().subscribeTopics.keySet()); + } + tcpSummaryMetrics.setSubTopicNum(topicSet.size()); + tcpSummaryMetrics.setAllConnections(EventMeshTcpConnectionHandler.connections.get()); + + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.CLIENT_2_EVENTMESH_TPS, + tcpSummaryMetrics.getClient2eventMeshTPS())); + + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.EVENTMESH_2_MQ_TPS, + tcpSummaryMetrics.getEventMesh2mqTPS())); + + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.MQ_2_EVENTMESH_TPS, + tcpSummaryMetrics.getMq2eventMeshTPS())); + + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.EVENTMESH_2_CLIENT_TPS, + tcpSummaryMetrics.getEventMesh2clientTPS())); + + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.ALL_TPS, + tcpSummaryMetrics.getAllTPS())); + + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.CONNECTION, + tcpSummaryMetrics.getAllConnections())); + + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.SUB_TOPIC_NUM, + tcpSummaryMetrics.getSubTopicNum())); + }), delay, period, TimeUnit.MILLISECONDS); + + monitorThreadPoolTask = eventMeshTCPServer.getScheduler().scheduleAtFixedRate(() -> { + eventMeshTCPServer.getEventMeshRebalanceService().printRebalanceThreadPoolState(); + eventMeshTCPServer.getEventMeshTcpRetryer().printRetryThreadPoolState(); + + //monitor retry queue size + tcpSummaryMetrics.setRetrySize(eventMeshTCPServer.getEventMeshTcpRetryer().getRetrySize()); + appLogger.info(String.format( + MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, + EventMeshConstants.PROTOCOL_TCP, + MonitorMetricConstants.RETRY_QUEUE_SIZE, + tcpSummaryMetrics.getRetrySize())); + + }, 10, PRINT_THREADPOOLSTATE_INTERVAL, TimeUnit.SECONDS); + logger.info("EventMeshTcpMonitor started......"); + } + + public TcpSummaryMetrics getTcpSummaryMetrics() { + return tcpSummaryMetrics; + } + + public void shutdown() throws Exception { + monitorTpsTask.cancel(true); + monitorThreadPoolTask.cancel(true); + metricsRegistries.forEach(MetricsRegistry::showdown); + logger.info("EventMeshTcpMonitor shutdown......"); + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/patch/EventMeshConsumeConcurrentlyStatus.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/patch/EventMeshConsumeConcurrentlyStatus.java new file mode 100644 index 0000000000..008f459f18 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/patch/EventMeshConsumeConcurrentlyStatus.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.patch; + +public enum EventMeshConsumeConcurrentlyStatus { + /** + * Success consumption + */ + CONSUME_SUCCESS, + /** + * Failure consumption,later try to consume + */ + RECONSUME_LATER, + /** + * Success consumption but ack later manually + */ + CONSUME_FINISH; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/registry/Registry.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/registry/Registry.java new file mode 100644 index 0000000000..6deaa5f8ff --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/registry/Registry.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.registry; + +import org.apache.eventmesh.api.registry.RegistryService; +import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Registry { + private static final Logger logger = LoggerFactory.getLogger(Registry.class); + + private volatile boolean inited = false; + + private volatile boolean started = false; + + private RegistryService registryService; + + public synchronized void init(String registryPluginType) throws Exception { + if (!inited) { + registryService = EventMeshExtensionFactory.getExtension(RegistryService.class, registryPluginType); + if (registryService == null) { + logger.error("can't load the registryService plugin, please check."); + throw new RuntimeException("doesn't load the registryService plugin, please check."); + } + registryService.init(); + inited = true; + } + } + + public synchronized void start() throws Exception { + if (!started) { + registryService.start(); + started = true; + } + } + + public synchronized void shutdown() throws Exception { + if (started) { + registryService.shutdown(); + started = false; + inited = false; + } + } + + public List findEventMeshInfoByCluster(String clusterName) throws Exception { + return registryService.findEventMeshInfoByCluster(clusterName); + } + + public List findAllEventMeshInfo() throws Exception { + return registryService.findAllEventMeshInfo(); + } + + public Map> findEventMeshClientDistributionData(String clusterName, String group, String purpose) throws Exception { + return registryService.findEventMeshClientDistributionData(clusterName, group, purpose); + } + + public void registerMetadata(Map metadata) { + registryService.registerMetadata(metadata); + } + + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws Exception { + return registryService.register(eventMeshRegisterInfo); + } + + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws Exception { + return registryService.unRegister(eventMeshUnRegisterInfo); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/AttributeKeys.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/AttributeKeys.java new file mode 100644 index 0000000000..ac151fda89 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/AttributeKeys.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.trace; + +import io.netty.util.AttributeKey; +import io.opentelemetry.context.Context; + +/** + * keys. + */ +public final class AttributeKeys { + public static final AttributeKey WRITE_CONTEXT = + AttributeKey.valueOf(AttributeKeys.class, "passed-context"); + + // this is the context that has the server span + // + // note: this attribute key is also used by ratpack instrumentation + public static final AttributeKey SERVER_CONTEXT = + AttributeKey.valueOf(AttributeKeys.class, "server-span"); + + public static final AttributeKey CLIENT_CONTEXT = + AttributeKey.valueOf(AttributeKeys.class, "client-context"); + + public static final AttributeKey CLIENT_PARENT_CONTEXT = + AttributeKey.valueOf(AttributeKeys.class, "client-parent-context"); + + private AttributeKeys() { + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/LogExporter.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/LogExporter.java new file mode 100644 index 0000000000..9bad687353 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/LogExporter.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.trace; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +/** + * Because the class 'LoggingSpanExporter' in openTelemetry exported garbled code in eventMesh's startUp, + * I override the 'LoggingSpanExporter'. + */ +public class LogExporter implements SpanExporter { + private static final Logger logger = LoggerFactory.getLogger(LogExporter.class); + + @Override + public CompletableResultCode export(Collection spans) { + // We always have 32 + 16 + name + several whitespace, 60 seems like an OK initial guess. + StringBuilder sb = new StringBuilder(60); + for (SpanData span : spans) { + sb.setLength(0); + InstrumentationLibraryInfo instrumentationLibraryInfo = span.getInstrumentationLibraryInfo(); + sb.append("'") + .append(span.getName()) + .append("' : ") + .append(span.getTraceId()) + .append(" ") + .append(span.getSpanId()) + .append(" ") + .append(span.getKind()) + .append(" [tracer: ") + .append(instrumentationLibraryInfo.getName()) + .append(":") + .append( + instrumentationLibraryInfo.getVersion() == null + ? "" + : instrumentationLibraryInfo.getVersion()) + .append("] ") + .append(span.getAttributes()); + logger.info(sb.toString()); + } + return CompletableResultCode.ofSuccess(); + } + + /** + * Flushes the data. + * (i guess it is not necessary for slf4j's log) + * + * @return the result of the operation + */ + @Override + public CompletableResultCode flush() { + CompletableResultCode resultCode = new CompletableResultCode(); + return resultCode.succeed(); + } + + @Override + public CompletableResultCode shutdown() { + return flush(); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/SpanKey.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/SpanKey.java new file mode 100644 index 0000000000..3fb285d14d --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/SpanKey.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.trace; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.ContextKey; + +/** + * Makes span keys for specific instrumentation accessible to enrich and suppress spans. + */ +public final class SpanKey { + // server span key + public static final ContextKey SERVER_KEY = + ContextKey.named("opentelemetry-traces-span-key-server"); + + // client span keys + public static final ContextKey HTTP_CLIENT_KEY = + ContextKey.named("opentelemetry-traces-span-key-http"); + public static final ContextKey RPC_CLIENT_KEY = + ContextKey.named("opentelemetry-traces-span-key-rpc"); + public static final ContextKey DB_CLIENT_KEY = + ContextKey.named("opentelemetry-traces-span-key-db"); + + // this is used instead of above, depending on the configuration value for + // otel.instrumentation.experimental.outgoing-span-suppression-by-type + public static final ContextKey CLIENT_KEY = + ContextKey.named("opentelemetry-traces-span-key-client"); + + // producer & consumer (messaging) span keys + public static final ContextKey PRODUCER_KEY = + ContextKey.named("opentelemetry-traces-span-key-producer"); + public static final ContextKey CONSUMER_RECEIVE_KEY = + ContextKey.named("opentelemetry-traces-span-key-consumer-receive"); + public static final ContextKey CONSUMER_PROCESS_KEY = + ContextKey.named("opentelemetry-traces-span-key-consumer-process"); +} + diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/Trace.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/Trace.java new file mode 100644 index 0000000000..716577f859 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/Trace.java @@ -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 org.apache.eventmesh.runtime.trace; + +import org.apache.eventmesh.trace.api.EventMeshTraceService; +import org.apache.eventmesh.trace.api.TracePluginFactory; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.netty.channel.ChannelHandlerContext; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.context.Context; + +public class Trace { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final boolean useTrace; + private EventMeshTraceService eventMeshTraceService; + + public Trace(boolean useTrace) { + this.useTrace = useTrace; + } + + public void init(String tracePluginType) throws Exception { + if (useTrace) { + eventMeshTraceService = TracePluginFactory.getEventMeshTraceService(tracePluginType); + eventMeshTraceService.init(); + } + } + + public Span createSpan(String spanName, SpanKind spanKind, long startTime, TimeUnit timeUnit, + Context context, boolean isSpanFinishInOtherThread) { + if (!useTrace) { + return Span.getInvalid(); + } + return eventMeshTraceService.createSpan(spanName, spanKind, startTime, timeUnit, context, + isSpanFinishInOtherThread); + } + + public Span createSpan(String spanName, SpanKind spanKind, Context context, + boolean isSpanFinishInOtherThread) { + if (!useTrace) { + return Span.getInvalid(); + } + return eventMeshTraceService.createSpan(spanName, spanKind, context, + isSpanFinishInOtherThread); + } + + public Context extractFrom(Context context, Map map) { + if (!useTrace) { + return null; + } + if (map == null) { + return context; + } + return eventMeshTraceService.extractFrom(context, map); + } + + public void inject(Context context, Map map) { + if (!useTrace) { + return; + } + if (context == null || map == null) { + return; + } + eventMeshTraceService.inject(context, map); + } + + public Span addTraceInfoToSpan(ChannelHandlerContext ctx, CloudEvent cloudEvent) { + if (!useTrace) { + return null; + } + Context context = ctx.channel().attr(AttributeKeys.SERVER_CONTEXT).get(); + Span span = context != null ? context.get(SpanKey.SERVER_KEY) : null; + + if (span == null) { + logger.warn("span is null when finishSpan"); + return null; + } + + //add trace info + for (String entry : cloudEvent.getExtensionNames()) { + span.setAttribute(entry, cloudEvent.getExtension(entry).toString()); + } + return span; + } + + public Span addTraceInfoToSpan(Span span, CloudEvent cloudEvent) { + if (!useTrace) { + return null; + } + + if (span == null) { + logger.warn("span is null when finishSpan"); + return null; + } + + if (cloudEvent == null) { + return span; + } + + for (String entry : cloudEvent.getExtensionNames()) { + span.setAttribute(entry, cloudEvent.getExtension(entry).toString()); + } + return span; + } + + public Span addTraceInfoToSpan(Span span, Map map) { + if (!useTrace) { + return null; + } + + if (span == null) { + logger.warn("span is null when finishSpan"); + return null; + } + + if (map == null || map.size() < 1) { + return span; + } + + for (Map.Entry entry : map.entrySet()) { + span.setAttribute(entry.getKey(), entry.getValue().toString()); + } + return span; + } + + public void finishSpan(ChannelHandlerContext ctx, StatusCode statusCode) { + try { + if (useTrace) { + Context context = ctx.channel().attr(AttributeKeys.SERVER_CONTEXT).get(); + Span span = context != null ? context.get(SpanKey.SERVER_KEY) : null; + + if (span == null) { + logger.warn("span is null when finishSpan"); + return; + } + if (statusCode != null) { + span.setStatus(statusCode); + } + span.end(); + } + } catch (Exception e) { + logger.warn("finishSpan occur exception,", e); + } + } + + public void finishSpan(Span span, StatusCode statusCode) { + try { + if (useTrace) { + if (span == null) { + logger.warn("span is null when finishSpan"); + return; + } + if (statusCode != null) { + span.setStatus(statusCode); + } + span.end(); + } + } catch (Exception e) { + logger.warn("finishSpan occur exception,", e); + } + } + + public void finishSpan(Span span, StatusCode statusCode, String errMsg, Throwable throwable) { + try { + if (useTrace) { + if (span == null) { + logger.warn("span is null when finishSpan"); + return; + } + if (statusCode != null) { + span.setStatus(statusCode, errMsg); + } + if (throwable != null) { + span.recordException(throwable); + } + span.end(); + } + } catch (Exception e) { + logger.warn("finishSpan occur exception,", e); + } + } + + public void finishSpan(ChannelHandlerContext ctx, StatusCode statusCode, String errMsg, + Throwable throwable) { + try { + if (useTrace) { + Context context = ctx.channel().attr(AttributeKeys.SERVER_CONTEXT).get(); + Span span = context != null ? context.get(SpanKey.SERVER_KEY) : null; + + if (span == null) { + logger.warn("span is null when finishSpan"); + return; + } + if (statusCode != null) { + span.setStatus(statusCode, errMsg); + } + if (throwable != null) { + span.recordException(throwable); + } + span.end(); + } + } catch (Exception e) { + logger.warn("finishSpan occur exception,", e); + } + } + + public void shutdown() throws Exception { + if (useTrace) { + eventMeshTraceService.shutdown(); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/TraceUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/TraceUtils.java new file mode 100644 index 0000000000..b8133c3a19 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/trace/TraceUtils.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.trace; + +import org.apache.eventmesh.runtime.boot.EventMeshServer; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.netty.channel.ChannelHandlerContext; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.context.Context; + +public class TraceUtils { + private static Logger logger = LoggerFactory.getLogger(TraceUtils.class); + + public static Span prepareClientSpan(Map map, String spanName, + boolean isSpanFinishInOtherThread) { + Span span = null; + try { + span = EventMeshServer.getTrace().createSpan( + spanName, SpanKind.CLIENT, Context.current(), isSpanFinishInOtherThread); + EventMeshServer.getTrace().inject(Context.current(), map); + } catch (Throwable ex) { + logger.warn("upload trace fail when prepareSpan", ex); + } + return span; + } + + public static Span prepareServerSpan(Map map, String spanName, + boolean isSpanFinishInOtherThread) { + Span span = null; + try { + Context traceContext = EventMeshServer.getTrace().extractFrom(Context.current(), map); + span = EventMeshServer.getTrace() + .createSpan(spanName, SpanKind.SERVER, traceContext, isSpanFinishInOtherThread); + } catch (Throwable ex) { + logger.warn("upload trace fail when prepareSpan", ex); + } + return span; + } + + public static Span prepareServerSpan(Map map, String spanName, long startTime, + TimeUnit timeUnit, boolean isSpanFinishInOtherThread) { + Span span = null; + try { + Context traceContext = EventMeshServer.getTrace().extractFrom(Context.current(), map); + if (startTime > 0) { + span = EventMeshServer.getTrace() + .createSpan(spanName, SpanKind.SERVER, startTime, timeUnit, traceContext, + isSpanFinishInOtherThread); + } else { + span = EventMeshServer.getTrace() + .createSpan(spanName, SpanKind.SERVER, traceContext, isSpanFinishInOtherThread); + } + } catch (Throwable ex) { + logger.warn("upload trace fail when prepareSpan", ex); + } + return span; + } + + + public static void finishSpan(Span span, CloudEvent event) { + try { + logger.debug("finishSpan with event:{}", event); + EventMeshServer.getTrace().addTraceInfoToSpan(span, event); + EventMeshServer.getTrace().finishSpan(span, StatusCode.OK); + } catch (Throwable ex) { + logger.warn("upload trace fail when finishSpan", ex); + } + + } + + public static void finishSpan(ChannelHandlerContext ctx, CloudEvent event) { + try { + logger.debug("finishSpan with event:{}", event); + EventMeshServer.getTrace().addTraceInfoToSpan(ctx, event); + EventMeshServer.getTrace().finishSpan(ctx, StatusCode.OK); + } catch (Throwable ex) { + logger.warn("upload trace fail when finishSpan", ex); + } + + } + + public static void finishSpanWithException(ChannelHandlerContext ctx, CloudEvent event, + String errMsg, Throwable e) { + try { + logger.debug("finishSpanWithException with event:{}", event); + EventMeshServer.getTrace().addTraceInfoToSpan(ctx, event); + EventMeshServer.getTrace().finishSpan(ctx, StatusCode.ERROR, errMsg, e); + } catch (Throwable ex) { + logger.warn("upload trace fail when finishSpanWithException", ex); + } + } + + public static void finishSpanWithException(Span span, Map map, String errMsg, + Throwable e) { + try { + logger.debug("finishSpanWithException with map:{}", map); + EventMeshServer.getTrace().addTraceInfoToSpan(span, map); + EventMeshServer.getTrace().finishSpan(span, StatusCode.ERROR, errMsg, e); + } catch (Throwable ex) { + logger.warn("upload trace fail when finishSpanWithException", ex); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshCloudEventWriter.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshCloudEventWriter.java new file mode 100644 index 0000000000..e939ac25e5 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshCloudEventWriter.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import java.util.HashMap; +import java.util.Map; + +import io.cloudevents.rw.CloudEventContextWriter; +import io.cloudevents.rw.CloudEventRWException; + +public class EventMeshCloudEventWriter implements CloudEventContextWriter { + private Map extensionMap = null; + + public EventMeshCloudEventWriter() { + extensionMap = new HashMap(); + } + + @Override + public CloudEventContextWriter withContextAttribute(String key, String value) + throws CloudEventRWException { + extensionMap.put(key, value); + return this; + } + + public Map getExtensionMap() { + return extensionMap; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshThreadFactoryImpl.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshThreadFactoryImpl.java new file mode 100644 index 0000000000..cf83904115 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshThreadFactoryImpl.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicLong; + +public class EventMeshThreadFactoryImpl implements ThreadFactory { + private final AtomicLong threadIndex = new AtomicLong(0); + private final String threadNamePrefix; + private Boolean isDaemonSpecified = null; + + public EventMeshThreadFactoryImpl(final String threadNamePrefix) { + this.threadNamePrefix = threadNamePrefix; + } + + public EventMeshThreadFactoryImpl(final String threadNamePrefix, final boolean isDaemonSpecified) { + this.threadNamePrefix = threadNamePrefix; + this.isDaemonSpecified = isDaemonSpecified; + } + + public String getThreadNamePrefix() { + return threadNamePrefix; + } + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, threadNamePrefix + '-' + this.threadIndex.incrementAndGet()); + if (isDaemonSpecified != null) { + t.setDaemon(isDaemonSpecified); + } + return t; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshUtil.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshUtil.java new file mode 100644 index 0000000000..7dff967378 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/EventMeshUtil.java @@ -0,0 +1,309 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.constants.EventMeshVersion; + +import org.apache.commons.lang3.StringUtils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; +import java.util.concurrent.ThreadPoolExecutor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.v03.CloudEventV03; +import io.cloudevents.core.v1.CloudEventV1; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +public class EventMeshUtil { + + private static final Logger logger = LoggerFactory.getLogger(EventMeshUtil.class); + + private static final Logger tcpLogger = LoggerFactory.getLogger("tcpMonitor"); + + public static String buildPushMsgSeqNo() { + return StringUtils.rightPad(String.valueOf(System.currentTimeMillis()), 6) + RandomStringUtils.generateNum(4); + } + + public static String buildMeshClientID(String clientGroup, String meshCluster) { + return StringUtils.trim(clientGroup) + + "(" + StringUtils.trim(meshCluster) + ")" + + "-" + EventMeshVersion.getCurrentVersionDesc() + + "-" + ThreadUtils.getPID(); + } + + public static String buildMeshTcpClientID(String clientSysId, String purpose, String meshCluster) { + return StringUtils.trim(clientSysId) + + "-" + StringUtils.trim(purpose) + + "-" + StringUtils.trim(meshCluster) + + "-" + EventMeshVersion.getCurrentVersionDesc() + + "-" + ThreadUtils.getPID(); + } + + public static String buildClientGroup(String systemId) { + return systemId; + } + + /** + * custom fetch stack + * + * @param e + * @return + */ + public static String stackTrace(Throwable e) { + return stackTrace(e, 0); + } + + public static String stackTrace(Throwable e, int level) { + if (e == null) { + return null; + } + + StackTraceElement[] eles = e.getStackTrace(); + level = (level == 0) ? eles.length : level; + StringBuilder sb = new StringBuilder(); + sb.append(e.getMessage()).append(System.lineSeparator()); + int innerLevel = 0; + for (StackTraceElement ele : eles) { + sb.append(ele.toString()).append(System.lineSeparator()); + if (++innerLevel >= level) { + break; + } + } + return sb.toString(); + } + + public static ObjectMapper createJsoner() { + ObjectMapper jsonMapper = new ObjectMapper(); + jsonMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + jsonMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + jsonMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + jsonMapper.setTimeZone(TimeZone.getDefault()); + return jsonMapper; + } + + + /** + * print part of the mq message + * + * @param eventMeshMessage + * @return + */ + public static String printMqMessage(EventMeshMessage eventMeshMessage) { + Map properties = eventMeshMessage.getProperties(); + + String keys = properties.get(EventMeshConstants.KEYS_UPPERCASE); + if (!StringUtils.isNotBlank(keys)) { + keys = properties.get(EventMeshConstants.KEYS_LOWERCASE); + } + + String result = String.format("Message [topic=%s,TTL=%s,uniqueId=%s,bizSeq=%s]", eventMeshMessage.getTopic(), + properties.get(EventMeshConstants.TTL), properties.get(EventMeshConstants.RR_REQUEST_UNIQ_ID), keys); + return result; + } + + public static String getMessageBizSeq(CloudEvent event) { + + String keys = (String) event.getExtension(EventMeshConstants.KEYS_UPPERCASE); + if (!StringUtils.isNotBlank(keys)) { + keys = (String) event.getExtension(EventMeshConstants.KEYS_LOWERCASE); + } + return keys; + } + + public static Map getEventProp(CloudEvent event) { + Set extensionSet = event.getExtensionNames(); + Map prop = new HashMap<>(); + for (String extensionKey : extensionSet) { + prop.put(extensionKey, event.getExtension(extensionKey).toString()); + } + return prop; + } + + public static String getLocalAddr() { + //priority of networkInterface when generating client ip + String priority = System.getProperty("networkInterface.priority", "bond1 preferList = new ArrayList(); + for (String eth : priority.split("<")) { + preferList.add(eth); + } + NetworkInterface preferNetworkInterface = null; + + try { + Enumeration enumeration1 = NetworkInterface.getNetworkInterfaces(); + while (enumeration1.hasMoreElements()) { + final NetworkInterface networkInterface = enumeration1.nextElement(); + if (!preferList.contains(networkInterface.getName())) { + continue; + } else if (preferNetworkInterface == null) { + preferNetworkInterface = networkInterface; + } else if (preferList.indexOf(networkInterface.getName()) + > preferList.indexOf(preferNetworkInterface.getName())) { + //get the networkInterface that has higher priority + preferNetworkInterface = networkInterface; + } + } + + // Traversal Network interface to get the first non-loopback and non-private address + ArrayList ipv4Result = new ArrayList(); + ArrayList ipv6Result = new ArrayList(); + + if (preferNetworkInterface != null) { + logger.debug("use preferNetworkInterface:{}", preferNetworkInterface); + final Enumeration en = preferNetworkInterface.getInetAddresses(); + getIpResult(ipv4Result, ipv6Result, en); + } else { + logger.debug("no preferNetworkInterface"); + Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); + while (enumeration.hasMoreElements()) { + final NetworkInterface networkInterface = enumeration.nextElement(); + final Enumeration en = networkInterface.getInetAddresses(); + getIpResult(ipv4Result, ipv6Result, en); + } + } + + // prefer ipv4 + if (!ipv4Result.isEmpty()) { + for (String ip : ipv4Result) { + if (ip.startsWith("127.0") || ip.startsWith("192.168")) { + continue; + } + + return ip; + } + + return ipv4Result.get(ipv4Result.size() - 1); + } else if (!ipv6Result.isEmpty()) { + return ipv6Result.get(0); + } + //If failed to find,fall back to localhost + final InetAddress localHost = InetAddress.getLocalHost(); + return normalizeHostAddress(localHost); + } catch (SocketException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + return null; + } + + public static String normalizeHostAddress(final InetAddress localHost) { + if (localHost instanceof Inet6Address) { + return "[" + localHost.getHostAddress() + "]"; + } else { + return localHost.getHostAddress(); + } + } + + private static void getIpResult(ArrayList ipv4Result, ArrayList ipv6Result, + Enumeration en) { + while (en.hasMoreElements()) { + final InetAddress address = en.nextElement(); + if (!address.isLoopbackAddress()) { + if (address instanceof Inet6Address) { + ipv6Result.add(normalizeHostAddress(address)); + } else { + ipv4Result.add(normalizeHostAddress(address)); + } + } + } + } + + public static String buildUserAgentClientId(UserAgent client) { + if (client == null) { + return null; + } + StringBuilder sb = new StringBuilder(); + sb.append(client.getSubsystem()).append("-") + .append("-") + .append(client.getPid()).append("-") + .append(client.getHost()).append(":").append(client.getPort()); + return sb.toString(); + } + + public static void printState(ThreadPoolExecutor scheduledExecutorService) { + tcpLogger.info("{} [{} {} {} {}]", ((EventMeshThreadFactoryImpl) scheduledExecutorService.getThreadFactory()) + .getThreadNamePrefix(), scheduledExecutorService.getQueue().size(), scheduledExecutorService + .getPoolSize(), scheduledExecutorService.getActiveCount(), scheduledExecutorService + .getCompletedTaskCount()); + } + + /** + * Perform deep clone of the given object using serialization + * + * @param object + * @return cloned object + * @throws IOException + * @throws ClassNotFoundException + */ + @SuppressWarnings("unchecked") + public static T cloneObject(T object) throws IOException, ClassNotFoundException { + ByteArrayOutputStream byOut = new ByteArrayOutputStream(); + ObjectOutputStream outputStream = new ObjectOutputStream(byOut); + outputStream.writeObject(object); + + ByteArrayInputStream byIn = new ByteArrayInputStream(byOut.toByteArray()); + ObjectInputStream inputStream = new ObjectInputStream(byIn); + return (T) inputStream.readObject(); + } + + public static Map getCloudEventExtensionMap(String protocolVersion, + CloudEvent cloudEvent) { + try { + EventMeshCloudEventWriter eventMeshCloudEventWriter = new EventMeshCloudEventWriter(); + if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion)) { + ((CloudEventV1) cloudEvent).readContext(eventMeshCloudEventWriter); + } else if (StringUtils.equals(SpecVersion.V03.toString(), protocolVersion)) { + ((CloudEventV03) cloudEvent).readContext(eventMeshCloudEventWriter); + } + return eventMeshCloudEventWriter.getExtensionMap(); + } catch (Throwable e) { + logger.warn("getCloudEventExtensionMap fail", e); + return null; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpResponseUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpResponseUtils.java new file mode 100644 index 0000000000..6c49c672a6 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpResponseUtils.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.DefaultHttpHeaders; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +public class HttpResponseUtils { + + public static final HttpResponse createSuccess() { + return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); + } + + public static final HttpResponse createNotFound() { + return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND); + } + + public static final HttpResponse createInternalServerError() { + return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); + } + + private static final ByteBuf crateByteBuf(ChannelHandlerContext ctx, String body) { + byte[] bytes = body.getBytes(); + ByteBuf byteBuf = ctx.alloc().buffer(bytes.length); + byteBuf.writeBytes(bytes); + return byteBuf; + } + + public static final HttpResponse setResponseJsonBody(String body, ChannelHandlerContext ctx) { + HttpHeaders responseHeaders = new DefaultHttpHeaders(); + responseHeaders.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON); + return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, crateByteBuf(ctx, body), + responseHeaders, responseHeaders); + + } + + public static final HttpResponse setResponseTextBody(String body, ChannelHandlerContext ctx) { + HttpHeaders responseHeaders = new DefaultHttpHeaders(); + responseHeaders.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_HTML); + return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, crateByteBuf(ctx, body), + responseHeaders, responseHeaders); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpTinyClient.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpTinyClient.java new file mode 100644 index 0000000000..e9d904a2c7 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/HttpTinyClient.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Iterator; +import java.util.List; + +public class HttpTinyClient { + + public static HttpResult httpGet(String url, List headers, List paramValues, + String encoding, long readTimeoutMs) throws IOException { + String encodedContent = encodingParams(paramValues, encoding); + url += (null == encodedContent) ? "" : ("?" + encodedContent); + + HttpURLConnection conn = null; + try { + conn = (HttpURLConnection) new URL(url).openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout((int) readTimeoutMs); + conn.setReadTimeout((int) readTimeoutMs); + setHeaders(conn, headers, encoding); + + conn.connect(); + int respCode = conn.getResponseCode(); + String resp = null; + + if (HttpURLConnection.HTTP_OK == respCode) { + resp = IOTinyUtils.toString(conn.getInputStream(), encoding); + } else { + resp = IOTinyUtils.toString(conn.getErrorStream(), encoding); + } + return new HttpResult(respCode, resp); + } finally { + if (conn != null) { + conn.disconnect(); + } + } + } + + private static String encodingParams(List paramValues, String encoding) + throws UnsupportedEncodingException { + StringBuilder sb = new StringBuilder(); + if (null == paramValues) { + return null; + } + + for (Iterator iter = paramValues.iterator(); iter.hasNext(); ) { + sb.append(iter.next()).append("="); + sb.append(URLEncoder.encode(iter.next(), encoding)); + if (iter.hasNext()) { + sb.append("&"); + } + } + return sb.toString(); + } + + private static void setHeaders(HttpURLConnection conn, List headers, String encoding) { + if (null != headers) { + for (Iterator iter = headers.iterator(); iter.hasNext(); ) { + conn.addRequestProperty(iter.next(), iter.next()); + } + } + conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding); + + String ts = String.valueOf(System.currentTimeMillis()); + conn.addRequestProperty("Metaq-Client-RequestTS", ts); + } + + /** + * @return the http response of given http post request + */ + public static HttpResult httpPost(String url, List headers, List paramValues, + String encoding, long readTimeoutMs) throws IOException { + String encodedContent = encodingParams(paramValues, encoding); + + HttpURLConnection conn = null; + try { + conn = (HttpURLConnection) new URL(url).openConnection(); + conn.setRequestMethod("POST"); + conn.setConnectTimeout(3000); + conn.setReadTimeout((int) readTimeoutMs); + conn.setDoOutput(true); + conn.setDoInput(true); + setHeaders(conn, headers, encoding); + + conn.getOutputStream().write(encodedContent.getBytes(EventMeshConstants.DEFAULT_CHARSET)); + + int respCode = conn.getResponseCode(); + String resp = null; + + if (HttpURLConnection.HTTP_OK == respCode) { + resp = IOTinyUtils.toString(conn.getInputStream(), encoding); + } else { + resp = IOTinyUtils.toString(conn.getErrorStream(), encoding); + } + return new HttpResult(respCode, resp); + } finally { + if (null != conn) { + conn.disconnect(); + } + } + } + + public static class HttpResult { + private final int code; + private final String content; + + public HttpResult(int code, String content) { + this.code = code; + this.content = content; + } + + public int getCode() { + return code; + } + + public String getContent() { + return content; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/IOTinyUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/IOTinyUtils.java new file mode 100644 index 0000000000..5aa3153747 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/IOTinyUtils.java @@ -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 org.apache.eventmesh.runtime.util; + +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import java.io.BufferedReader; +import java.io.CharArrayWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.List; + +public class IOTinyUtils { + + public static String toString(InputStream input, String encoding) throws IOException { + return (null == encoding) ? toString(new InputStreamReader(input, EventMeshConstants.DEFAULT_CHARSET)) + : toString(new InputStreamReader(input, encoding)); + } + + public static String toString(Reader reader) throws IOException { + CharArrayWriter sw = new CharArrayWriter(); + copy(reader, sw); + return sw.toString(); + } + + public static long copy(Reader input, Writer output) throws IOException { + char[] buffer = new char[1 << 12]; + long count = 0; + for (int n = 0; (n = input.read(buffer)) >= 0; ) { + output.write(buffer, 0, n); + count += n; + } + return count; + } + + public static List readLines(Reader input) throws IOException { + BufferedReader reader = toBufferedReader(input); + List list = new ArrayList(); + String line; + for (; ; ) { + line = reader.readLine(); + if (null != line) { + list.add(line); + } else { + break; + } + } + return list; + } + + private static BufferedReader toBufferedReader(Reader reader) { + return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); + } + + public static void copyFile(String source, String target) throws IOException { + File sf = new File(source); + if (!sf.exists()) { + throw new IllegalArgumentException("source file does not exist."); + } + File tf = new File(target); + tf.getParentFile().mkdirs(); + if (!tf.exists() && !tf.createNewFile()) { + throw new RuntimeException("failed to create target file."); + } + + FileChannel sc = null; + FileChannel tc = null; + try { + tc = new FileOutputStream(tf).getChannel(); + sc = new FileInputStream(sf).getChannel(); + sc.transferTo(0, sc.size(), tc); + } finally { + if (null != sc) { + sc.close(); + } + if (null != tc) { + tc.close(); + } + } + } + + public static void delete(File fileOrDir) throws IOException { + if (fileOrDir == null) { + return; + } + + if (fileOrDir.isDirectory()) { + cleanDirectory(fileOrDir); + } + + fileOrDir.delete(); + } + + public static void cleanDirectory(File directory) throws IOException { + if (!directory.exists()) { + String message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (!directory.isDirectory()) { + String message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } + + File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + directory); + } + + IOException exception = null; + for (File file : files) { + try { + delete(file); + } catch (IOException ioe) { + exception = ioe; + } + } + + if (null != exception) { + throw exception; + } + } + + public static void writeStringToFile(File file, String data, String encoding) throws IOException { + OutputStream os = null; + try { + os = new FileOutputStream(file); + os.write(data.getBytes(encoding)); + } finally { + if (null != os) { + os.close(); + } + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/NetUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/NetUtils.java new file mode 100644 index 0000000000..3a1cc8787b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/NetUtils.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import java.io.UnsupportedEncodingException; +import java.net.InetSocketAddress; +import java.net.URLDecoder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NetUtils { + + private static final Logger logger = LoggerFactory.getLogger(NetUtils.class); + + /** + * Transform the url form string to Map + * + * @param formData + * @return + */ + public static Map formData2Dic(String formData) { + Map result = new HashMap<>(); + if (formData == null || formData.trim().length() == 0) { + return result; + } + final String[] items = formData.split("&"); + Arrays.stream(items).forEach(item -> { + final String[] keyAndVal = item.split("="); + if (keyAndVal.length == 2) { + try { + final String key = URLDecoder.decode(keyAndVal[0], "utf8"); + final String val = URLDecoder.decode(keyAndVal[1], "utf8"); + result.put(key, val); + } catch (UnsupportedEncodingException e) { + logger.warn("formData2Dic:param decode failed...", e); + } + } + }); + return result; + } + + public static String addressToString(List clients) { + if (clients.isEmpty()) { + return "no session had been closed"; + } + StringBuilder sb = new StringBuilder(); + for (InetSocketAddress addr : clients) { + sb.append(addr).append("|"); + } + return sb.toString(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/RemotingHelper.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/RemotingHelper.java new file mode 100644 index 0000000000..a2c88dbc71 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/RemotingHelper.java @@ -0,0 +1,90 @@ +/* + * Licensed to Apache Software Foundation (ASF) under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Apache Software Foundation (ASF) licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.Channel; + +public class RemotingHelper { + public static final String DEFAULT_CHARSET = "UTF-8"; + + public static Logger logger = LoggerFactory.getLogger(RemotingHelper.class); + + public static String exceptionSimpleDesc(final Throwable e) { + StringBuilder sb = new StringBuilder(); + if (e != null) { + sb.append(e); + + StackTraceElement[] stackTrace = e.getStackTrace(); + if (stackTrace != null && stackTrace.length > 0) { + StackTraceElement elment = stackTrace[0]; + sb.append(", "); + sb.append(elment.toString()); + } + } + + return sb.toString(); + } + + public static SocketAddress string2SocketAddress(final String addr) { + int split = addr.lastIndexOf(":"); + String host = addr.substring(0, split); + String port = addr.substring(split + 1); + InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port)); + return isa; + } + + public static String parseChannelRemoteAddr(final Channel channel) { + if (null == channel) { + return ""; + } + SocketAddress remote = channel.remoteAddress(); + final String addr = remote != null ? remote.toString() : ""; + + if (addr.length() > 0) { + int index = addr.lastIndexOf("/"); + if (index >= 0) { + return addr.substring(index + 1); + } + + return addr; + } + + return ""; + } + + public static String parseSocketAddressAddr(SocketAddress socketAddress) { + if (socketAddress != null) { + final String addr = socketAddress.toString(); + + if (addr.length() > 0) { + return addr.substring(1); + } + } + return ""; + } + +} + diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ServerGlobal.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ServerGlobal.java new file mode 100644 index 0000000000..9ef4422946 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ServerGlobal.java @@ -0,0 +1,42 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import java.util.concurrent.atomic.AtomicLong; + +public class ServerGlobal { + + private static class SerGlobalHolder { + private static ServerGlobal singleton = new ServerGlobal(); + } + + public static ServerGlobal getInstance() { + return SerGlobalHolder.singleton; + } + + private AtomicLong msgCounter = new AtomicLong(); + + public AtomicLong getMsgCounter() { + return msgCounter; + } + + public void setMsgCounter(AtomicLong msgCounter) { + this.msgCounter = msgCounter; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/Utils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/Utils.java new file mode 100644 index 0000000000..0265dc3c3b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/Utils.java @@ -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 org.apache.eventmesh.runtime.util; + +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.SessionState; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; + +public class Utils { + private static final Logger logger = LoggerFactory.getLogger(Utils.class); + private static final Logger messageLogger = LoggerFactory.getLogger("message"); + + /** + * used to send messages to the client + * + * @param pkg + * @param startTime + * @param ctx + * @param session + */ + public static void writeAndFlush(final Package pkg, long startTime, long taskExecuteTime, ChannelHandlerContext ctx, + Session + session) { + try { + UserAgent user = session == null ? null : session.getClient(); + if (session != null && session.getSessionState().equals(SessionState.CLOSED)) { + logFailedMessageFlow(pkg, user, startTime, taskExecuteTime, + new Exception("the session has been closed")); + return; + } + ctx.writeAndFlush(pkg).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + logFailedMessageFlow(future, pkg, user, startTime, taskExecuteTime); + } else { + logSucceedMessageFlow(pkg, user, startTime, taskExecuteTime); + + if (session != null) { + session.getClientGroupWrapper().get() + .getEventMeshTcpMonitor().getTcpSummaryMetrics().getEventMesh2clientMsgNum().incrementAndGet(); + } + } + } + } + ); + } catch (Exception e) { + logger.error("exception while sending message to client", e); + } + } + + /** + * print the message flow of failed sending + * + * @param future + * @param pkg + * @param user + * @param startTime + */ + public static void logFailedMessageFlow(ChannelFuture future, Package pkg, UserAgent user, long startTime, + long taskExecuteTime) { + logFailedMessageFlow(pkg, user, startTime, taskExecuteTime, future.cause()); + } + + private static void logFailedMessageFlow(Package pkg, UserAgent user, long startTime, long taskExecuteTime, + Throwable e) { + if (pkg.getBody() instanceof EventMeshMessage) { + messageLogger.error("pkg|eventMesh2c|failed|cmd={}|mqMsg={}|user={}|wait={}ms|cost={}ms|errMsg={}", + pkg.getHeader().getCmd(), + printMqMessage((EventMeshMessage) pkg.getBody()), user, taskExecuteTime - startTime, + System.currentTimeMillis() - startTime, e); + } else { + messageLogger.error("pkg|eventMesh2c|failed|cmd={}|pkg={}|user={}|wait={}ms|cost={}ms|errMsg={}", + pkg.getHeader().getCmd(), + pkg, user, taskExecuteTime - startTime, System.currentTimeMillis() - startTime, e); + } + } + + /** + * print the message flow of successful sending. + * + * @param pkg + * @param user + * @param startTime + */ + public static void logSucceedMessageFlow(Package pkg, UserAgent user, long startTime, long taskExecuteTime) { + if (pkg.getBody() instanceof EventMeshMessage) { + messageLogger.info("pkg|eventMesh2c|cmd={}|mqMsg={}|user={}|wait={}ms|cost={}ms", pkg.getHeader().getCmd(), + printMqMessage((EventMeshMessage) pkg.getBody()), user, taskExecuteTime - startTime, + System.currentTimeMillis() - startTime); + } else { + messageLogger + .info("pkg|eventMesh2c|cmd={}|pkg={}|user={}|wait={}ms|cost={}ms", pkg.getHeader().getCmd(), pkg, + user, taskExecuteTime - startTime, System.currentTimeMillis() - startTime); + } + } + + /** + * print part of the mq message + * + * @param eventMeshMessage + * @return + */ + public static String printMqMessage(EventMeshMessage eventMeshMessage) { + Map properties = eventMeshMessage.getProperties(); + + String bizSeqNo = properties.get(EventMeshConstants.KEYS_UPPERCASE); + if (!StringUtils.isNotBlank(bizSeqNo)) { + bizSeqNo = properties.get(EventMeshConstants.KEYS_LOWERCASE); + } + + String result = String.format("Message [topic=%s,TTL=%s,uniqueId=%s,bizSeq=%s]", eventMeshMessage + .getTopic(), properties.get(EventMeshConstants.TTL), properties.get(EventMeshConstants.RR_REQUEST_UNIQ_ID), + bizSeqNo); + return result; + } + + /** + * get serviceId according to topic + */ + public static String getServiceId(String topic) { + String[] topicStrArr = topic.split("-"); + if (topicStrArr.length >= 3) { + return topicStrArr[2]; + } else { + return null; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ValueComparator.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ValueComparator.java new file mode 100644 index 0000000000..e3835985f0 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ValueComparator.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import java.util.Comparator; +import java.util.Map; + +public class ValueComparator implements Comparator> { + @Override + public int compare(Map.Entry x, Map.Entry y) { + if (x.getValue().intValue() != y.getValue().intValue()) { + return x.getValue() - y.getValue(); + } else { + return x.getKey().compareTo(y.getKey()); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/WebhookUtil.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/WebhookUtil.java new file mode 100644 index 0000000000..658a6677c3 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/WebhookUtil.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import org.apache.eventmesh.api.auth.AuthService; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpOptions; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.message.BasicHeader; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class for implementing CloudEvents Http Webhook spec + * + * @see CloudEvents Http Webhook + */ +public class WebhookUtil { + + private static final Logger logger = LoggerFactory.getLogger(WebhookUtil.class.getName()); + + private static final String CONTENT_TYPE_HEADER = "Content-Type"; + private static final String REQUEST_ORIGIN_HEADER = "WebHook-Request-Origin"; + private static final String ALLOWED_ORIGIN_HEADER = "WebHook-Allowed-Origin"; + + private static final Map authServices = new ConcurrentHashMap<>(); + + public static boolean obtainDeliveryAgreement(CloseableHttpClient httpClient, String targetUrl, String requestOrigin) { + logger.info("obtain webhook delivery agreement for url: {}", targetUrl); + HttpOptions builder = new HttpOptions(targetUrl); + builder.addHeader(REQUEST_ORIGIN_HEADER, requestOrigin); + + try (CloseableHttpResponse response = httpClient.execute(builder)) { + String allowedOrigin = response.getLastHeader(ALLOWED_ORIGIN_HEADER).getValue(); + return StringUtils.isEmpty(allowedOrigin) + || allowedOrigin.equals("*") || allowedOrigin.equalsIgnoreCase(requestOrigin); + } catch (Exception e) { + logger.warn("HTTP Options Method is not supported at the Delivery Target: {}," + + " unable to obtain the webhook delivery agreement.", targetUrl); + } + return true; + } + + public static void setWebhookHeaders(HttpPost builder, String contentType, String requestOrigin, String urlAuthType) { + builder.setHeader(CONTENT_TYPE_HEADER, contentType); + builder.setHeader(REQUEST_ORIGIN_HEADER, requestOrigin); + + Map authParam = getHttpAuthParam(urlAuthType); + if (authParam != null) { + authParam.forEach((k, v) -> builder.addHeader(new BasicHeader(k, v))); + } + } + + @SuppressWarnings("unchecked") + private static Map getHttpAuthParam(String authType) { + if (StringUtils.isEmpty(authType)) { + return null; + } + AuthService authService = getHttpAuthPlugin(authType); + if (authService != null) { + return authService.getAuthParams(); + } else { + return null; + } + } + + private static AuthService getHttpAuthPlugin(String pluginType) { + if (authServices.containsKey(pluginType)) { + return authServices.get(pluginType); + } + + AuthService authService = EventMeshExtensionFactory.getExtension(AuthService.class, pluginType); + + if (authService == null) { + logger.error("can't load the authService plugin, please check."); + throw new RuntimeException("doesn't load the authService plugin, please check."); + } + try { + authService.init(); + authServices.put(pluginType, authService); + return authService; + } catch (Exception e) { + logger.error("Error in initializing authService", e); + } + return null; + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/controller/ClientManageControllerTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/controller/ClientManageControllerTest.java new file mode 100644 index 0000000000..a7303bf97c --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/controller/ClientManageControllerTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.admin.controller; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.admin.rocketmq.controller.AdminController; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.webhook.admin.AdminWebHookConfigOperationManage; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; + +import java.io.IOException; + +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import com.sun.net.httpserver.HttpServer; + +public class ClientManageControllerTest { + + @Test + public void testStart() throws IOException { + EventMeshTCPServer eventMeshTCPServer = mock(EventMeshTCPServer.class); + AdminController adminController = mock(AdminController.class); + EventMeshTCPConfiguration tcpConfiguration = mock(EventMeshTCPConfiguration.class); + doNothing().when(tcpConfiguration).init(); + when(eventMeshTCPServer.getEventMeshTCPConfiguration()).thenReturn(tcpConfiguration); + ClientManageController controller = new ClientManageController(eventMeshTCPServer); + + AdminWebHookConfigOperationManage adminWebHookConfigOperationManage = mock(AdminWebHookConfigOperationManage.class); + WebHookConfigOperation webHookConfigOperation = mock(WebHookConfigOperation.class); + when(adminWebHookConfigOperationManage.getWebHookConfigOperation()).thenReturn(webHookConfigOperation); + controller.setAdminWebHookConfigOperationManage(adminWebHookConfigOperationManage); + + try (MockedStatic dummyStatic = Mockito.mockStatic(HttpServer.class)) { + HttpServer server = mock(HttpServer.class); + dummyStatic.when(() -> HttpServer.create(any(), anyInt())).thenReturn(server); + Mockito.doNothing().when(adminController).run(server); + controller.start(); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/QueryRecommendEventMeshHandlerTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/QueryRecommendEventMeshHandlerTest.java new file mode 100644 index 0000000000..1112cedab7 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/QueryRecommendEventMeshHandlerTest.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend.EventMeshRecommendImpl; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.net.URI; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.MockedConstruction; + +import com.sun.net.httpserver.HttpExchange; + +public class QueryRecommendEventMeshHandlerTest { + + @Test + public void testHandle() throws Exception { + HttpExchange httpExchange = mock(HttpExchange.class); + URI uri = mock(URI.class); + when(uri.getQuery()).thenReturn("group=group&purpose=purpose"); + when(httpExchange.getRequestURI()).thenReturn(uri); + + // mock eventMeshTCPServer + EventMeshTCPServer eventMeshTCPServer = mock(EventMeshTCPServer.class); + EventMeshTCPConfiguration tcpConfiguration = mock(EventMeshTCPConfiguration.class); + doNothing().when(tcpConfiguration).init(); + tcpConfiguration.eventMeshServerRegistryEnable = true; + when(eventMeshTCPServer.getEventMeshTCPConfiguration()).thenReturn(tcpConfiguration); + + OutputStream outputStream = new ByteArrayOutputStream(); + when(httpExchange.getResponseBody()).thenReturn(outputStream); + + QueryRecommendEventMeshHandler handler = new QueryRecommendEventMeshHandler(eventMeshTCPServer); + try (MockedConstruction ignored = mockConstruction(EventMeshRecommendImpl.class, + (mock, context) -> when(mock.calculateRecommendEventMesh(anyString(), anyString())).thenReturn("result"))) { + handler.handle(httpExchange); + String response = outputStream.toString(); + Assert.assertEquals("result", response); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByIpPortHandlerTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByIpPortHandlerTest.java new file mode 100644 index 0000000000..7ed08f7db4 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByIpPortHandlerTest.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.powermock.api.mockito.PowerMockito; + +import com.sun.net.httpserver.HttpExchange; + +public class RedirectClientByIpPortHandlerTest { + + private RedirectClientByIpPortHandler redirectClientByIpPortHandler; + + @Before + public void init() { + EventMeshTCPServer mockServer = PowerMockito.mock(EventMeshTCPServer.class); + redirectClientByIpPortHandler = new RedirectClientByIpPortHandler(mockServer); + } + + @Test + public void testHandleParamIllegal() throws IOException { + OutputStream outputStream = new ByteArrayOutputStream(); + URI uri = URI.create("ip=127.0.0.1&port=1234&desteventMeshIp=127.0.0.1&desteventMeshPort="); + + HttpExchange mockExchange = PowerMockito.mock(HttpExchange.class); + PowerMockito.when(mockExchange.getResponseBody()).thenReturn(outputStream); + PowerMockito.when(mockExchange.getRequestURI()).thenReturn(uri); + + redirectClientByIpPortHandler.handle(mockExchange); + + String response = outputStream.toString(); + Assert.assertEquals("params illegal!", response); + + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByPathHandlerTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByPathHandlerTest.java new file mode 100644 index 0000000000..0a90172fac --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/admin/handler/RedirectClientByPathHandlerTest.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.eventmesh.runtime.admin.handler; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.EventMeshTcp2Client; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.group.ClientSessionGroupMapping; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.NetUtils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import com.sun.net.httpserver.HttpExchange; + +public class RedirectClientByPathHandlerTest { + + @Mock + private EventMeshTCPServer eventMeshTCPServer; + + @Before + public void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void testHandle() throws IOException { + final OutputStream outputStream = new ByteArrayOutputStream(); + + ClientSessionGroupMapping mapping = mock(ClientSessionGroupMapping.class); + when(eventMeshTCPServer.getClientSessionGroupMapping()).thenReturn(mapping); + + // mock session map + ConcurrentHashMap sessionMap = new ConcurrentHashMap<>(); + Session session = mock(Session.class); + UserAgent agent = mock(UserAgent.class); + when(agent.getPath()).thenReturn("path"); + when(session.getClient()).thenReturn(agent); + sessionMap.put(new InetSocketAddress(8080), session); + when(mapping.getSessionMap()).thenReturn(sessionMap); + + RedirectClientByPathHandler redirectClientByPathHandler = new RedirectClientByPathHandler(eventMeshTCPServer); + + HttpExchange mockExchange = mock(HttpExchange.class); + when(mockExchange.getResponseBody()).thenReturn(outputStream); + + // mock uri + URI uri = mock(URI.class); + when(uri.getQuery()).thenReturn("path=path&ip=127.0.0.1&port=1234&desteventMeshIp=127.0.0.1&desteventmeshport=8080"); + when(mockExchange.getRequestURI()).thenReturn(uri); + + try (MockedStatic netUtilsMockedStatic = Mockito.mockStatic(NetUtils.class)) { + Map queryStringInfo = new HashMap<>(); + queryStringInfo.put(EventMeshConstants.MANAGE_PATH, EventMeshConstants.MANAGE_PATH); + queryStringInfo.put(EventMeshConstants.MANAGE_DEST_IP, "127.0.0.1"); + queryStringInfo.put(EventMeshConstants.MANAGE_DEST_PORT, "8080"); + netUtilsMockedStatic.when(() -> NetUtils.formData2Dic(anyString())).thenReturn(queryStringInfo); + + try (MockedStatic clientMockedStatic = Mockito.mockStatic(EventMeshTcp2Client.class)) { + clientMockedStatic.when(() -> EventMeshTcp2Client.redirectClient2NewEventMesh(any(), anyString(), anyInt(), any(), + any())).thenReturn("redirectResult"); + redirectClientByPathHandler.handle(mockExchange); + + String response = outputStream.toString(); + Assert.assertTrue(response.contains("redirectClientByPath success")); + } + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/EventMeshClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/EventMeshClient.java new file mode 100644 index 0000000000..59c060e826 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/EventMeshClient.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.api; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; + +/** + * EventMeshClient + */ +public interface EventMeshClient { + + Package rr(Package msg, long timeout) throws Exception; + + Package publish(Package msg, long timeout) throws Exception; + + Package broadcast(Package msg, long timeout) throws Exception; + + void init() throws Exception; + + void close(); + + void heartbeat() throws Exception; + + Package listen() throws Exception; + + Package justSubscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) throws Exception; + + Package justUnsubscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) throws Exception; + + void registerPubBusiHandler(ReceiveMsgHook handler) throws Exception; + + void registerSubBusiHandler(ReceiveMsgHook handler) throws Exception; + + void goodbye() throws Exception; +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/PubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/PubClient.java new file mode 100644 index 0000000000..f0097af0b7 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/PubClient.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.api; + +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; + +/** + * PubClient + */ +public interface PubClient { + + void init() throws Exception; + + void close(); + + void heartbeat() throws Exception; + + void reconnect() throws Exception; + + Package rr(Package msg, long timeout) throws Exception; + + Package publish(Package msg, long timeout) throws Exception; + + Package broadcast(Package msg, long timeout) throws Exception; + + void registerBusiHandler(ReceiveMsgHook handler) throws Exception; + + UserAgent getUserAgent(); + + Package dispatcher(Package request, long timeout) throws Exception; + + void goodbye() throws Exception; + + Package askRecommend() throws Exception; + +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/SubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/SubClient.java new file mode 100644 index 0000000000..524b1ba14a --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/api/SubClient.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.api; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; + +/** + * SubClient + */ +public interface SubClient { + void init() throws Exception; + + void close(); + + void heartbeat() throws Exception; + + void reconnect() throws Exception; + + Package justSubscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) throws Exception; + + Package justUnsubscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) throws Exception; + + Package listen() throws Exception; + + void registerBusiHandler(ReceiveMsgHook handler) throws Exception; + + UserAgent getUserAgent(); + + Package goodbye() throws Exception; + +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/ClientConstants.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/ClientConstants.java new file mode 100644 index 0000000000..466e8d1e5e --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/ClientConstants.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.common; + +/** + * ClientConstants + */ +public interface ClientConstants { + + /** + * CLIENT HEART BEAT TIME + */ + int HEARTBEAT = 1000 * 60; + + long DEFAULT_TIMEOUT_IN_MILLISECONDS = 3000; + + String SYNC_TOPIC = "TEST-TOPIC-TCP-SYNC"; + String ASYNC_TOPIC = "TEST-TOPIC-TCP-ASYNC"; + String BROADCAST_TOPIC = "TEST-TOPIC-TCP-BROADCAST"; +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/ClientGlobal.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/ClientGlobal.java new file mode 100644 index 0000000000..65e14fd2fa --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/ClientGlobal.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.common; + +import java.util.TimeZone; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + + +public class ClientGlobal { + + private static Logger logger = LoggerFactory.getLogger(ClientGlobal.class); + + public static ClientGlobal INSTANCE = new ClientGlobal(); + + public static ClientGlobal getInstance() { + return INSTANCE; + } + + public static ObjectMapper jsonMapper; + + private ClientGlobal() { + init(); + } + + public void init() { + ObjectMapper jsonMapper = new ObjectMapper(); + jsonMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + jsonMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + jsonMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + jsonMapper.setTimeZone(TimeZone.getDefault()); + this.jsonMapper = jsonMapper; + logger.info("ClientGlobal init success"); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/Codec.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/Codec.java new file mode 100644 index 0000000000..1124287c86 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/Codec.java @@ -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 org.apache.eventmesh.runtime.client.common; + +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.RedirectInfo; +import org.apache.eventmesh.common.protocol.tcp.Subscription; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.handler.codec.ReplayingDecoder; + +public class Codec { + + private static final Logger logger = LoggerFactory.getLogger(Codec.class); + private static final int FRAME_MAX_LENGTH = 1024 * 1024 * 4; + private static final Charset UTF8 = Charset.forName(EventMeshConstants.DEFAULT_CHARSET); + private static final byte[] CONSTANT_MAGIC_FLAG = "EventMesh".getBytes(UTF8); + private static final byte[] VERSION = "0000".getBytes(UTF8); + + public static class Encoder extends MessageToByteEncoder { + @Override + public void encode(ChannelHandlerContext ctx, Package pkg, ByteBuf out) throws Exception { + byte[] headerData; + byte[] bodyData; + + final String headerJson = pkg != null ? ClientGlobal.jsonMapper.writeValueAsString(pkg.getHeader()) : null; + final String bodyJson = pkg != null ? ClientGlobal.jsonMapper.writeValueAsString(pkg.getBody()) : null; + + headerData = headerJson == null ? null : headerJson.getBytes(UTF8); + bodyData = bodyJson == null ? null : bodyJson.getBytes(UTF8); + + logger.debug("headerJson={}|bodyJson={}", headerJson, bodyJson); + + int headerLength = headerData == null ? 0 : headerData.length; + int bodyLength = bodyData == null ? 0 : bodyData.length; + + int length = 4 + 4 + headerLength + bodyLength; + + if (length > FRAME_MAX_LENGTH) { + throw new IllegalArgumentException("message size is exceed limit!"); + } + + out.writeBytes(CONSTANT_MAGIC_FLAG); + out.writeBytes(VERSION); + out.writeInt(length); + out.writeInt(headerLength); + if (headerData != null) { + out.writeBytes(headerData); + } + if (bodyData != null) { + out.writeBytes(bodyData); + } + } + } + + public static class Decoder extends ReplayingDecoder { + @Override + public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + Header header = null; + Object body = null; + + int length = 0; + int headerLength = 0; + int bodyLength = 0; + + try { + if (null == in) { + return; + } + + byte[] flagBytes = new byte[CONSTANT_MAGIC_FLAG.length]; + byte[] versionBytes = new byte[VERSION.length]; + + in.readBytes(flagBytes); + in.readBytes(versionBytes); + if (!Arrays.equals(flagBytes, CONSTANT_MAGIC_FLAG) || !Arrays.equals(versionBytes, VERSION)) { + String errorMsg = String.format("invalid magic flag or " + + + "version|flag=%s|version=%s|remoteAddress=%s", new String(flagBytes, UTF8), + new String(versionBytes, UTF8), ctx.channel().remoteAddress()); + throw new Exception(errorMsg); + } + + length = in.readInt(); + headerLength = in.readInt(); + bodyLength = length - 8 - headerLength; + byte[] headerData = new byte[headerLength]; + byte[] bodyData = new byte[bodyLength]; + + if (headerLength > 0) { + in.readBytes(headerData); + header = ClientGlobal.jsonMapper.readValue(new String(headerData, UTF8), Header.class); + } + + if (bodyLength > 0 && header != null) { + in.readBytes(bodyData); + body = parseFromJson(header.getCommand(), new String(bodyData, UTF8)); + } + + logger.debug("headerJson={}|bodyJson={}", new String(headerData, UTF8), new String(bodyData, UTF8)); + + Package pkg = new Package(header, body); + out.add(pkg); + } catch (Exception e) { + logger.error("decode|length={}|headerLength={}|bodyLength={}|header={}|body={}.", length, + headerLength, bodyLength, header, body); + throw e; + } + } + } + + private static Object parseFromJson(Command cmd, String data) throws Exception { + if (cmd == Command.HELLO_REQUEST || cmd == Command.RECOMMEND_REQUEST) { + return ClientGlobal.jsonMapper.readValue(data, UserAgent.class); + } else if (cmd == Command.SUBSCRIBE_REQUEST + || cmd == Command.UNSUBSCRIBE_REQUEST) { + return ClientGlobal.jsonMapper.readValue(data, Subscription.class); + } else if (cmd == Command.REQUEST_TO_SERVER + || cmd == Command.REQUEST_TO_CLIENT + || cmd == Command.RESPONSE_TO_SERVER + || cmd == Command.RESPONSE_TO_CLIENT + || cmd == Command.ASYNC_MESSAGE_TO_SERVER + || cmd == Command.ASYNC_MESSAGE_TO_CLIENT + || cmd == Command.BROADCAST_MESSAGE_TO_SERVER + || cmd == Command.BROADCAST_MESSAGE_TO_CLIENT + || cmd == Command.BROADCAST_MESSAGE_TO_CLIENT_ACK + || cmd == Command.ASYNC_MESSAGE_TO_CLIENT_ACK + || cmd == Command.REQUEST_TO_CLIENT_ACK + || cmd == Command.RESPONSE_TO_CLIENT_ACK) { + return ClientGlobal.jsonMapper.readValue(data, EventMeshMessage.class); + } else if (cmd == Command.REDIRECT_TO_CLIENT) { + return ClientGlobal.jsonMapper.readValue(data, RedirectInfo.class); + } else { + return null; + } + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/MessageUtils.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/MessageUtils.java new file mode 100644 index 0000000000..72b9b357ae --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/MessageUtils.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.common; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.Subscription; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +public class MessageUtils { + public static final int seqLength = 10; + + public static Package hello(UserAgent user) { + Package msg = new Package(); + msg.setHeader(new Header(Command.HELLO_REQUEST, 0, "sucess", generateRandomString(seqLength))); + msg.setBody(user); + return msg; + } + + public static Package heartBeat() { + Package msg = new Package(); + msg.setHeader(new Header(Command.HEARTBEAT_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package goodbye() { + Package msg = new Package(); + msg.setHeader(new Header(Command.CLIENT_GOODBYE_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package listen() { + Package msg = new Package(); + msg.setHeader(new Header(Command.LISTEN_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package subscribe() { + Package msg = new Package(); + msg.setHeader(new Header(Command.SUBSCRIBE_REQUEST, 0, null, generateRandomString(seqLength))); + msg.setBody(generateSubscription()); + return msg; + } + + public static Package subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) { + Package msg = new Package(); + msg.setHeader(new Header(Command.SUBSCRIBE_REQUEST, 0, null, generateRandomString(seqLength))); + msg.setBody(generateSubscription(topic, subscriptionMode, subscriptionType)); + return msg; + } + + public static Package unsubscribe() { + Package msg = new Package(); + msg.setHeader(new Header(Command.UNSUBSCRIBE_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package unsubscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) { + Package msg = new Package(); + msg.setHeader(new Header(Command.UNSUBSCRIBE_REQUEST, 0, null, generateRandomString(seqLength))); + msg.setBody(generateSubscription(topic, subscriptionMode, subscriptionType)); + return msg; + } + + public static Package rrMesssage(String topic, int i) { + Package msg = new Package(); + msg.setHeader(new Header(Command.REQUEST_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateRRMsg(topic, i)); + return msg; + } + + public static Package asyncMessage(String topic, int i) { + Package msg = new Package(); + msg.setHeader(new Header(Command.ASYNC_MESSAGE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateAsyncEventMsg(topic, i)); + return msg; + } + + public static Package broadcastMessage(String topic, int i) { + Package msg = new Package(); + msg.setHeader(new Header(Command.BROADCAST_MESSAGE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateBroadcastMsg(topic, i)); + return msg; + } + + public static Package rrResponse(Package request) { + Package msg = new Package(); + msg.setHeader(new Header(Command.RESPONSE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(request.getBody()); + return msg; + } + + public static Package asyncMessageAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.ASYNC_MESSAGE_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static Package broadcastMessageAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.BROADCAST_MESSAGE_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static Package requestToClientAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.REQUEST_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static Package responseToClientAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.RESPONSE_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static UserAgent generatePubClient() { + UserAgent user = new UserAgent(); + user.setHost("127.0.0.1"); + user.setPassword(generateRandomString(8)); + user.setUsername("PU4283"); + user.setPath("/data/app/umg_proxy"); + user.setPort(8362); + user.setSubsystem("5023"); + user.setPid(32893); + user.setVersion("2.0.11"); + user.setIdc("FT"); + return user; + } + + public static UserAgent generateSubServer() { + UserAgent user = new UserAgent(); + user.setHost("127.0.0.1"); + user.setPassword(generateRandomString(8)); + user.setUsername("PU4283"); + user.setPath("/data/app/umg_proxy"); + user.setPort(9437); + user.setSubsystem("5023"); + user.setPid(23948); + user.setVersion("2.0.11"); + return user; + } + + public static Subscription generateSubscription() { + + List subscriptionItems = new ArrayList<>(); + subscriptionItems.add(new SubscriptionItem("TEST-TOPIC-TCP-SYNC", SubscriptionMode.CLUSTERING, SubscriptionType.SYNC)); + subscriptionItems.add(new SubscriptionItem("TEST-TOPIC-TCP-SYNC2", SubscriptionMode.CLUSTERING, SubscriptionType.SYNC)); + subscriptionItems.add(new SubscriptionItem("TEST-TOPIC-TCP-SYNC3", SubscriptionMode.CLUSTERING, SubscriptionType.SYNC)); + subscriptionItems.add(new SubscriptionItem("TEST-TOPIC-TCP-SYNC4", SubscriptionMode.CLUSTERING, SubscriptionType.SYNC)); + Subscription subscription = new Subscription(); + subscription.setTopicList(subscriptionItems); + return subscription; + } + + public static Subscription generateSubscription(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) { + Subscription subscription = new Subscription(); + List subscriptionItems = new ArrayList<>(); + subscriptionItems.add(new SubscriptionItem(topic, subscriptionMode, subscriptionType)); + subscription.setTopicList(subscriptionItems); + return subscription; + } + + public static EventMeshMessage generateRRMsg(String topic, int i) { + EventMeshMessage msg = new EventMeshMessage(); + msg.setTopic(topic); + msg.getProperties().put("msgtype", "persistent"); + msg.getProperties().put("TTL", "300000"); + msg.getProperties().put("KEYS", generateRandomString(16)); + msg.setBody("testRR" + i); + return msg; + } + + public static EventMeshMessage generateAsyncEventMsg(String topic, int i) { + EventMeshMessage msg = new EventMeshMessage(); + msg.setTopic(topic); + msg.getProperties().put("REPLY_TO", "10.36.0.109@ProducerGroup-producerPool-9-access#V1_4_0#CI"); + msg.getProperties().put("TTL", "30000"); + msg.getProperties().put("PROPERTY_MESSAGE_REPLY_TO", "notnull"); + msg.setBody("testAsyncMessage" + i); + return msg; + } + + public static EventMeshMessage generateBroadcastMsg(String topic, int i) { + EventMeshMessage msg = new EventMeshMessage(); + msg.setTopic(topic); + msg.getProperties().put("REPLY_TO", ""); + msg.getProperties().put("TTL", "30000"); + msg.getProperties().put("PROPERTY_MESSAGE_REPLY_TO", "notnull"); + msg.setBody("testBroadCastMessage" + i); + return msg; + } + + public static String generateRandomString(int length) { + StringBuilder builder = new StringBuilder(length); + for (int i = 0; i < length; i++) { + builder.append((char) ThreadLocalRandom.current().nextInt(48, 57)); + } + return builder.toString(); + } + + public static Package askRecommend(UserAgent user) { + Package msg = new Package(); + msg.setHeader(new Header(Command.RECOMMEND_REQUEST, 0, "sucess", generateRandomString(seqLength))); + msg.setBody(user); + return msg; + } +} + diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/RequestContext.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/RequestContext.java new file mode 100644 index 0000000000..63044dbe79 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/RequestContext.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.common; + +import org.apache.eventmesh.common.protocol.tcp.Package; + +import java.util.concurrent.CountDownLatch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RequestContext { + + private static Logger logger = LoggerFactory.getLogger(RequestContext.class); + + private Object key; + private Package request; + private Package response; + private CountDownLatch latch; + + public RequestContext(Object key, Package request, CountDownLatch latch) { + this.key = key; + this.request = request; + this.latch = latch; + } + + public Object getKey() { + return key; + } + + public void setKey(Object key) { + this.key = key; + } + + public Package getRequest() { + return request; + } + + public void setRequest(Package request) { + this.request = request; + } + + public Package getResponse() { + return response; + } + + public void setResponse(Package response) { + this.response = response; + } + + public CountDownLatch getLatch() { + return latch; + } + + public void setLatch(CountDownLatch latch) { + this.latch = latch; + } + + public void finish(Package msg) { + this.response = msg; + latch.countDown(); + } + + public static RequestContext context(Object key, Package request, CountDownLatch latch) throws Exception { + RequestContext c = new RequestContext(key, request, latch); + logger.info("_RequestContext|create|key=" + key); + return c; + } + + public static Object key(Package request) { + return request.getHeader().getSeq(); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/Server.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/Server.java new file mode 100644 index 0000000000..d52eecc830 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/Server.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.common; + +import org.apache.eventmesh.runtime.boot.EventMeshServer; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; + +public class Server { + + EventMeshServer server; + + static { + System.setProperty("proxy.home", "E:\\projects\\external-1\\proxy"); + System.setProperty("confPath", "E:\\projects\\external-1\\proxy\\conf"); + System.setProperty("log4j.configurationFile", "E:\\projects\\external-1\\proxy\\conf\\log4j2.xml"); + System.setProperty("proxy.log.home", "E:\\projects\\external-1\\proxy\\logs"); + } + + public void startAccessServer() throws Exception { + EventMeshHTTPConfiguration eventMeshHttpConfiguration = new EventMeshHTTPConfiguration(null); + eventMeshHttpConfiguration.init(); + server = new EventMeshServer(eventMeshHttpConfiguration, null, null); + server.init(); + server.start(); + } + + public void shutdownAccessServer() throws Exception { + server.shutdown(); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/TCPClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/TCPClient.java new file mode 100644 index 0000000000..90d728a189 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/TCPClient.java @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.common; + +import org.apache.eventmesh.common.protocol.tcp.Package; + +import java.io.Closeable; +import java.net.InetSocketAddress; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.AdaptiveRecvByteBufAllocator; +import io.netty.channel.Channel; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; + + +/** + * one Client connects one ACCESS + * Provides the most basic connection, send capability, and cannot provide disconnected reconnection capability, + * The service is request-dependent. If the disconnection and reconnection capability is provided, + * it will cause business insensitivity, that is, it will not follow the business reconnection logic. + */ +public abstract class TCPClient implements Closeable { + + public int clientNo = (new Random()).nextInt(1000); + + protected ConcurrentHashMap contexts = new ConcurrentHashMap<>(); + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected String host = "10.255.34.120"; + + protected int port = 10000; + + private Bootstrap bootstrap = new Bootstrap(); + + protected static final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(4, + new ThreadFactory() { + AtomicInteger count = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, "TCPClientScheduler-" + count.incrementAndGet()); + t.setDaemon(true); + return t; + } + } + ); + + private NioEventLoopGroup workers = new NioEventLoopGroup(8, new ThreadFactory() { + AtomicInteger count = new AtomicInteger(0); + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r, "TCPClientWorker-" + count.incrementAndGet()); + return t; + } + }); + + public Channel channel; + + protected boolean isActive() { + return (channel != null) && (channel.isActive()); + } + + public TCPClient(String host, int port) { + this.host = host; + this.port = port; + } + + protected void send(Package msg) throws Exception { + if (channel.isWritable()) { + channel.writeAndFlush(msg).addListener((ChannelFutureListener) future -> { + if (!future.isSuccess()) { + logger.warn("send msg failed", future.isSuccess(), future.cause()); + } + }); + } else { + channel.writeAndFlush(msg).sync(); + } + } + + protected Package io(Package msg, long timeout) throws Exception { + if (msg.getHeader().getSeq() == null) { + send(msg); + return null; + } else { + Object key = RequestContext.key(msg); + CountDownLatch latch = new CountDownLatch(1); + RequestContext c = RequestContext.context(key, msg, latch); + if (!contexts.contains(c)) { + contexts.put(key, c); + } else { + logger.info("duplicate key : {}", key); + } + send(msg); + if (!c.getLatch().await(timeout, TimeUnit.MILLISECONDS)) { + throw new TimeoutException("operation timeout, context.key=" + c.getKey()); + } + + return c.getResponse(); + } + } + + protected synchronized void open(SimpleChannelInboundHandler handler) throws Exception { + bootstrap.group(workers); + bootstrap.channel(NioSocketChannel.class); + bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1_000) + .option(ChannelOption.SO_KEEPALIVE, false) + .option(ChannelOption.SO_SNDBUF, 64 * 1024) + .option(ChannelOption.SO_RCVBUF, 64 * 1024) + .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(1024, 8192, 65536)) + .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); + bootstrap.handler(new ChannelInitializer() { + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new Codec.Encoder(), new Codec.Decoder()) + .addLast(handler, newExceptionHandler()); + } + }); + + ChannelFuture f = bootstrap.connect(host, port).sync(); + InetSocketAddress localAddress = (InetSocketAddress) f.channel().localAddress(); + channel = f.channel(); + logger.info("connected|local={}:{}|server={}", localAddress.getAddress().getHostAddress(), localAddress.getPort(), host + ":" + port); + } + + protected synchronized void reconnect() throws Exception { + ChannelFuture f = bootstrap.connect(host, port).sync(); + channel = f.channel(); + } + + private ChannelDuplexHandler newExceptionHandler() { + return new ChannelDuplexHandler() { + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + logger.warn("exceptionCaught, close connection.|remote address={}", ctx.channel().remoteAddress(), cause); + ctx.close(); + } + }; + } + + @Override + public synchronized void close() { + try { + channel.disconnect().sync(); + } catch (InterruptedException e) { + logger.warn("close tcp client failed.|remote address={}", channel.remoteAddress(), e); + } + workers.shutdownGracefully(); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/UserAgentUtils.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/UserAgentUtils.java new file mode 100644 index 0000000000..a916a91679 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/common/UserAgentUtils.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.common; + +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import java.util.concurrent.ThreadLocalRandom; + +public class UserAgentUtils { + public static UserAgent createPubUserAgent() { + UserAgent userAgent = new UserAgent(); + userAgent.setSubsystem("5023"); + userAgent.setPid(32893); + userAgent.setVersion("2.0.11"); + userAgent.setIdc("FT"); + userAgent.setPath("/data/app/umg_proxy"); + userAgent.setHost("127.0.0.1"); + userAgent.setPort(8362); + userAgent.setUsername("PU4283"); + userAgent.setPassword(generateRandomString(8)); + userAgent.setPurpose(EventMeshConstants.PURPOSE_PUB); + + return userAgent; + } + + public static UserAgent createUserAgent() { + UserAgent userAgent = new UserAgent(); + userAgent.setSubsystem("5123"); + //userAgent.setPid(UtilAll.getPid()); + //userAgent.setHost(RemotingUtil.getLocalAddress()); + userAgent.setVersion("2.0.8"); + userAgent.setUsername("username"); + userAgent.setPassword("1234"); + return userAgent; + } + + public static UserAgent createSubUserAgent() { + UserAgent userAgent = new UserAgent(); + userAgent.setSubsystem("5243"); + //userAgent.setPid(UtilAll.getPid()); + //userAgent.setHost(RemotingUtil.getLocalAddress()); + userAgent.setPort(8888); + userAgent.setVersion("2.0.8"); + userAgent.setUsername("username"); + userAgent.setPassword("1234"); + userAgent.setPath("/data/app/defibus-acl/"); + userAgent.setPurpose(EventMeshConstants.PURPOSE_SUB); + return userAgent; + } + + public static String generateRandomString(int length) { + StringBuilder builder = new StringBuilder(length); + for (int i = 0; i < length; i++) { + builder.append((char) ThreadLocalRandom.current().nextInt(48, 57)); + } + return builder.toString(); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/hook/ReceiveMsgHook.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/hook/ReceiveMsgHook.java new file mode 100644 index 0000000000..a3364795dd --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/hook/ReceiveMsgHook.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.hook; + +import org.apache.eventmesh.common.protocol.tcp.Package; + +import io.netty.channel.ChannelHandlerContext; + +/** + * Business callback hook, which is a callback for all types of messages + */ +public interface ReceiveMsgHook { + void handle(Package msg, ChannelHandlerContext ctx); +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/EventMeshClientImpl.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/EventMeshClientImpl.java new file mode 100644 index 0000000000..5536c2eaf5 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/EventMeshClientImpl.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.impl; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.client.api.EventMeshClient; +import org.apache.eventmesh.runtime.client.api.PubClient; +import org.apache.eventmesh.runtime.client.api.SubClient; +import org.apache.eventmesh.runtime.client.common.UserAgentUtils; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; + +public class EventMeshClientImpl implements EventMeshClient { + protected UserAgent agent; + private String accessHost; + private int accessPort; + + private PubClient pubClient; + private SubClient subClient; + + public EventMeshClientImpl(String accessHost, int accessPort, UserAgent agent) { + this.accessHost = accessHost; + this.accessPort = accessPort; + this.agent = agent; + this.subClient = new SubClientImpl(accessHost, accessPort, agent); + this.pubClient = new PubClientImpl(accessHost, accessPort, agent); + } + + public EventMeshClientImpl(String accessHost, int accessPort) { + this.accessHost = accessHost; + this.accessPort = accessPort; + this.subClient = new SubClientImpl(accessHost, accessPort, UserAgentUtils.createSubUserAgent()); + this.pubClient = new PubClientImpl(accessHost, accessPort, UserAgentUtils.createPubUserAgent()); + } + + public Package rr(Package msg, long timeout) throws Exception { + return this.pubClient.rr(msg, timeout); + } + + public Package publish(Package msg, long timeout) throws Exception { + return this.pubClient.publish(msg, timeout); + } + + public Package broadcast(Package msg, long timeout) throws Exception { + return this.pubClient.broadcast(msg, timeout); + } + + public void init() throws Exception { + this.subClient.init(); + this.pubClient.init(); + } + + public void close() { + this.pubClient.close(); + this.subClient.close(); + } + + public void heartbeat() throws Exception { + this.pubClient.heartbeat(); + this.subClient.heartbeat(); + } + + public Package listen() throws Exception { + return this.subClient.listen(); + } + + @Override + public Package justSubscribe(String topic, SubscriptionMode subscriptionMode, + SubscriptionType subscriptionType) throws Exception { + return this.subClient.justSubscribe(topic, subscriptionMode, subscriptionType); + } + + @Override + public Package justUnsubscribe(String topic, SubscriptionMode subscriptionMode, + SubscriptionType subscriptionType) throws Exception { + return this.subClient.justUnsubscribe(topic, subscriptionMode, subscriptionType); + } + + public void registerSubBusiHandler(ReceiveMsgHook handler) throws Exception { + this.subClient.registerBusiHandler(handler); + } + + public void registerPubBusiHandler(ReceiveMsgHook handler) throws Exception { + this.pubClient.registerBusiHandler(handler); + } + + @Override + public String toString() { + return "AccessClientImpl{" + + + "accessHost='" + accessHost + '\'' + + + ", accessPort=" + accessPort + + + ", agent=" + agent + + + '}'; + } + + @Deprecated + public EventMeshClientImpl(String accessServer, String busiTag, String subSystem) { + //this.accessServer = accessServer; + //this.pubClient = new PubClientImpl(StringUtils.split(this.accessServer, ":")[0], + // Integer.parseInt(StringUtils.split(this.accessServer, ":")[1]), OldTestUserAgentFactory.createPubUserAgent + // (busiTag, subSystem)); + //this.subClient = new SubClientImpl(StringUtils.split(this.accessServer, ":")[0], + // Integer.parseInt(StringUtils.split(this.accessServer, ":")[1]), OldTestUserAgentFactory.createSubUserAgent + // (busiTag, subSystem)); + } + + //@Override + //public void sysLog() throws Exception { + // subClient.sysLog(); + //} + // + //@Override + //public void traceLog() throws Exception { + // subClient.traceLog(); + //} + + @Override + public void goodbye() throws Exception { + subClient.goodbye(); + pubClient.goodbye(); + } + +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/PubClientImpl.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/PubClientImpl.java new file mode 100644 index 0000000000..2e76d7febe --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/PubClientImpl.java @@ -0,0 +1,226 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.impl; + +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.client.api.PubClient; +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.common.RequestContext; +import org.apache.eventmesh.runtime.client.common.TCPClient; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +public class PubClientImpl extends TCPClient implements PubClient { + + private Logger publogger = LoggerFactory.getLogger(this.getClass()); + + private UserAgent userAgent; + + private ReceiveMsgHook callback; + + private ScheduledFuture task; + + public PubClientImpl(String accessIp, int port, UserAgent agent) { + super(accessIp, port); + this.userAgent = agent; + } + + public void registerBusiHandler(ReceiveMsgHook handler) throws Exception { + callback = handler; + } + + public void init() throws Exception { + open(new Handler()); + hello(); + publogger.info("PubClientImpl|{}|started!", clientNo); + } + + public void reconnect() throws Exception { + super.reconnect(); + hello(); + } + + public void close() { + try { + task.cancel(false); + super.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void heartbeat() throws Exception { + task = scheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + if (!isActive()) { + PubClientImpl.this.reconnect(); + } + Package msg = MessageUtils.heartBeat(); + publogger.debug("PubClientImpl|{}|send heartbeat|Command={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); + PubClientImpl.this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } catch (Exception e) { + //ignore + } + } + }, ClientConstants.HEARTBEAT, ClientConstants.HEARTBEAT, TimeUnit.MILLISECONDS); + } + + public void goodbye() throws Exception { + Package msg = MessageUtils.goodbye(); + this.io(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + public Package askRecommend() throws Exception { + Package msg = MessageUtils.askRecommend(userAgent); + return this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + private void hello() throws Exception { + Package msg = MessageUtils.hello(userAgent); + this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + /** + * send RR message + */ + @Override + public Package rr(Package msg, long timeout) throws Exception { + publogger.info("PubClientImpl|{}|rr|send|Command={}|msg={}", clientNo, msg.getHeader().getCommand().REQUEST_TO_SERVER, msg); + return dispatcher(msg, timeout); + } + + /** + * Add test case assertions on the basis of the original IO + */ + public Package dispatcher(Package request, long timeout) throws Exception { + Assert.assertNotNull(request); + Package response = super.io(request, timeout); + Assert.assertNotNull(response); + Command cmd = response.getHeader().getCommand(); + switch (request.getHeader().getCommand()) { + case RECOMMEND_REQUEST: + Assert.assertEquals(cmd, Command.RECOMMEND_RESPONSE); + break; + case HELLO_REQUEST: + Assert.assertEquals(cmd, Command.HELLO_RESPONSE); + break; + case HEARTBEAT_REQUEST: + Assert.assertEquals(cmd, Command.HEARTBEAT_RESPONSE); + break; + case CLIENT_GOODBYE_REQUEST: + Assert.assertEquals(cmd, Command.CLIENT_GOODBYE_RESPONSE); + break; + case BROADCAST_MESSAGE_TO_SERVER: + Assert.assertEquals(cmd, Command.BROADCAST_MESSAGE_TO_SERVER_ACK); + break; + case ASYNC_MESSAGE_TO_SERVER: + Assert.assertEquals(cmd, Command.ASYNC_MESSAGE_TO_SERVER_ACK); + break; + case REQUEST_TO_SERVER: + Assert.assertEquals(cmd, Command.RESPONSE_TO_CLIENT); + break; + default: + break; + } + assert response.getHeader().getCode() == OPStatus.SUCCESS.getCode(); + return response; + } + + /** + * Send an event message, the return value is ACCESS and ACK is given + */ + public Package publish(Package msg, long timeout) throws Exception { + publogger.info("PubClientImpl|{}|publish|send|command={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); + return dispatcher(msg, timeout); + } + + /** + * send broadcast message + */ + public Package broadcast(Package msg, long timeout) throws Exception { + publogger.info("PubClientImpl|{}|broadcast|send|type={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); + return dispatcher(msg, timeout); + } + + @Override + public UserAgent getUserAgent() { + return userAgent; + } + + @ChannelHandler.Sharable + private class Handler extends SimpleChannelInboundHandler { + @Override + protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Exception { + publogger.info("PubClientImpl|{}|receive|type={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); + Command cmd = msg.getHeader().getCommand(); + if (callback != null) { + callback.handle(msg, ctx); + } + /** + * RR send and accept the return packet ,and Ack + */ + if (cmd == Command.RESPONSE_TO_CLIENT) { + Package responseToClientAck = MessageUtils.responseToClientAck(msg); + send(responseToClientAck); + RequestContext context = contexts.get(RequestContext.key(msg)); + if (context != null) { + contexts.remove(context.getKey()); + context.finish(msg); + return; + } else { + publogger.error("msg ignored,context not found .|{}|{}", cmd, msg); + return; + } + } else if (cmd == Command.SERVER_GOODBYE_REQUEST) { + publogger.error("server goodby request: ---------------------------" + msg); + close(); + } else { + RequestContext context = contexts.get(RequestContext.key(msg)); + if (context != null) { + contexts.remove(context.getKey()); + context.finish(msg); + return; + } else { + publogger.error("msg ignored,context not found .|{}|{}", cmd, msg); + return; + } + } + } + } + + @Override + public String toString() { + return "PubClientImpl|clientNo=" + clientNo + "|" + userAgent; + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/SubClientImpl.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/SubClientImpl.java new file mode 100644 index 0000000000..6af8b4c0eb --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/client/impl/SubClientImpl.java @@ -0,0 +1,248 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.client.impl; + +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.OPStatus; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.client.api.SubClient; +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.common.RequestContext; +import org.apache.eventmesh.runtime.client.common.TCPClient; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +public class SubClientImpl extends TCPClient implements SubClient { + + private static final Logger logger = LoggerFactory.getLogger(SubClientImpl.class); + + private UserAgent userAgent; + + private ReceiveMsgHook callback; + + private List subscriptionItems = new ArrayList(); + + private ScheduledFuture task; + + public SubClientImpl(String accessIp, int port, UserAgent agent) { + super(accessIp, port); + this.userAgent = agent; + } + + public void registerBusiHandler(ReceiveMsgHook handler) throws Exception { + callback = handler; + } + + public void init() throws Exception { + open(new Handler()); + hello(); + logger.info("SubClientImpl|{}|started!", clientNo); + } + + public void reconnect() throws Exception { + super.reconnect(); + hello(); + if (!CollectionUtils.isEmpty(subscriptionItems)) { + for (SubscriptionItem item : subscriptionItems) { + Package request = MessageUtils.subscribe(item.getTopic(), item.getMode(), item.getType()); + this.dispatcher(request, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + } + listen(); + } + + public void close() { + try { + task.cancel(false); + super.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void heartbeat() throws Exception { + task = scheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + if (!isActive()) { + SubClientImpl.this.reconnect(); + } + Package msg = MessageUtils.heartBeat(); + logger.debug("SubClientImpl|{}|send heartbeat|Command={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); + SubClientImpl.this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } catch (Exception e) { + //ignore + } + } + }, ClientConstants.HEARTBEAT, ClientConstants.HEARTBEAT, TimeUnit.MILLISECONDS); + } + + public Package goodbye() throws Exception { + Package msg = MessageUtils.goodbye(); + return this.io(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + private void hello() throws Exception { + Package msg = MessageUtils.hello(userAgent); + this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + public Package justSubscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) throws Exception { + subscriptionItems.add(new SubscriptionItem(topic, subscriptionMode, subscriptionType)); + Package msg = MessageUtils.subscribe(topic, subscriptionMode, subscriptionType); + return this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + public Package listen() throws Exception { + Package request = MessageUtils.listen(); + return this.dispatcher(request, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + //@Override + //public void traceLog() throws Exception { + // Package msg = MessageUtils.traceLog(); + // this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + //} + + //public void sysLog() throws Exception { + // Package msg = MessageUtils.sysLog(); + // this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + //} + + public Package justUnsubscribe(String topic, SubscriptionMode subscriptionMode, + SubscriptionType subscriptionType) throws Exception { + subscriptionItems.remove(topic); + Package msg = MessageUtils.unsubscribe(topic, subscriptionMode, subscriptionType); + return this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); + } + + public UserAgent getUserAgent() { + return userAgent; + } + + public Package dispatcher(Package request, long timeout) throws Exception { + Assert.assertNotNull(request); + Package response = super.io(request, timeout); + switch (request.getHeader().getCommand()) { + case HELLO_REQUEST: + Assert.assertEquals(response.getHeader().getCommand(), Command.HELLO_RESPONSE); + break; + case HEARTBEAT_REQUEST: + Assert.assertEquals(response.getHeader().getCommand(), Command.HEARTBEAT_RESPONSE); + break; + case LISTEN_REQUEST: + Assert.assertEquals(response.getHeader().getCommand(), Command.LISTEN_RESPONSE); + break; + case CLIENT_GOODBYE_REQUEST: + Assert.assertEquals(response.getHeader().getCommand(), Command.CLIENT_GOODBYE_RESPONSE); + break; + case SUBSCRIBE_REQUEST: + Assert.assertEquals(response.getHeader().getCommand(), Command.SUBSCRIBE_RESPONSE); + break; + case UNSUBSCRIBE_REQUEST: + Assert.assertEquals(response.getHeader().getCommand(), Command.UNSUBSCRIBE_RESPONSE); + break; + case SYS_LOG_TO_LOGSERVER: + Assert.assertNull(response); + break; + case TRACE_LOG_TO_LOGSERVER: + Assert.assertNull(response); + break; + default: + break; + } + if (response != null) { + assert response.getHeader().getCode() == OPStatus.SUCCESS.getCode(); + } + return response; + } + + @ChannelHandler.Sharable + private class Handler extends SimpleChannelInboundHandler { + @SuppressWarnings("Duplicates") + @Override + protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Exception { + logger.info(SubClientImpl.class.getSimpleName() + "|receive|command={}|msg={}", msg.getHeader().getCommand(), msg); + Command cmd = msg.getHeader().getCommand(); + if (callback != null) { + callback.handle(msg, ctx); + } + if (cmd == Command.REQUEST_TO_CLIENT) { + try { + Package ackMsg = MessageUtils.requestToClientAck(msg); + send(ackMsg); + Package responsePKG = MessageUtils.rrResponse(msg); + send(responsePKG); + } catch (Exception e) { + logger.info("send rr request to client ack failed"); + } + } else if (cmd == Command.ASYNC_MESSAGE_TO_CLIENT) { + Package asyncAck = MessageUtils.asyncMessageAck(msg); + try { + send(asyncAck); + } catch (Exception e) { + logger.info("send async request to client ack failed"); + } + } else if (cmd == Command.BROADCAST_MESSAGE_TO_CLIENT) { + Package broadcastAck = MessageUtils.broadcastMessageAck(msg); + try { + send(broadcastAck); + } catch (Exception e) { + logger.info("send broadcast request to client ack failed"); + } + } else if (cmd == Command.SERVER_GOODBYE_REQUEST) { + logger.error("server goodby request: ---------------------------" + msg); + close(); + } else { + //control instruction set + RequestContext context = contexts.get(RequestContext.key(msg)); + if (context != null) { + contexts.remove(context.getKey()); + context.finish(msg); + } else { + logger.error("msg ignored,context not found.|{}|{}", cmd, msg); + } + } + } + } + + @Override + public String toString() { + return "SubClientImpl|clientNo=" + clientNo + "|" + userAgent; + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/AsyncPubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/AsyncPubClient.java new file mode 100644 index 0000000000..a2dd1d904d --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/AsyncPubClient.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.common.UserAgentUtils; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; +import org.apache.eventmesh.runtime.client.impl.PubClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class AsyncPubClient { + + private static final Logger logger = LoggerFactory.getLogger(AsyncPubClient.class); + + public static void main(String[] args) throws Exception { + PubClientImpl pubClient = new PubClientImpl("127.0.0.1", 10000, UserAgentUtils.createUserAgent()); + pubClient.init(); + pubClient.heartbeat(); + pubClient.registerBusiHandler(new ReceiveMsgHook() { + @Override + public void handle(Package msg, ChannelHandlerContext ctx) { + logger.error("receive msg-----------------------------" + msg.toString()); + } + }); + + for (int i = 0; i < 1; i++) { + ThreadUtils.randomSleep(0, 500); + pubClient.broadcast(MessageUtils.asyncMessage(ClientConstants.ASYNC_TOPIC, i), 5000); + } + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/AsyncSubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/AsyncSubClient.java new file mode 100644 index 0000000000..2783e136ed --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/AsyncSubClient.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; +import org.apache.eventmesh.runtime.client.impl.SubClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class AsyncSubClient { + + private static final Logger logger = LoggerFactory.getLogger(AsyncSubClient.class); + + public static void main(String[] args) throws Exception { + SubClientImpl client = new SubClientImpl("127.0.0.1", 10002, MessageUtils.generateSubServer()); + client.init(); + client.heartbeat(); + client.justSubscribe(ClientConstants.ASYNC_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC); + client.registerBusiHandler(new ReceiveMsgHook() { + @Override + public void handle(Package msg, ChannelHandlerContext ctx) { + if (msg.getBody() instanceof EventMeshMessage) { + String body = ((EventMeshMessage) msg.getBody()).getBody(); + logger.error("receive message -------------------------------" + body); + } + } + }); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/BroadCastPubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/BroadCastPubClient.java new file mode 100644 index 0000000000..5f3fa158bd --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/BroadCastPubClient.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.common.UserAgentUtils; +import org.apache.eventmesh.runtime.client.impl.PubClientImpl; + +public class BroadCastPubClient { + public static void main(String[] args) throws Exception { + PubClientImpl pubClient = new PubClientImpl("127.0.0.1", 10000, UserAgentUtils.createUserAgent()); + pubClient.init(); + pubClient.heartbeat(); + for (int i = 0; i < 10000; i++) { + ThreadUtils.randomSleep(0, 500); + pubClient.broadcast(MessageUtils.broadcastMessage(ClientConstants.BROADCAST_TOPIC, i), 5000); + } + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/BroadCastSubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/BroadCastSubClient.java new file mode 100644 index 0000000000..8e00541dc0 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/BroadCastSubClient.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; +import org.apache.eventmesh.runtime.client.impl.SubClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class BroadCastSubClient { + + private static final Logger logger = LoggerFactory.getLogger(BroadCastSubClient.class); + + public static void main(String[] args) throws Exception { + SubClientImpl client = new SubClientImpl("127.0.0.1", 10000, MessageUtils.generateSubServer()); + client.init(); + client.heartbeat(); + client.justSubscribe(ClientConstants.BROADCAST_TOPIC, SubscriptionMode.BROADCASTING, SubscriptionType.ASYNC); + client.registerBusiHandler(new ReceiveMsgHook() { + @Override + public void handle(Package msg, ChannelHandlerContext ctx) { + if (msg.getHeader().getCommand() == Command.BROADCAST_MESSAGE_TO_CLIENT) { + if (msg.getBody() instanceof EventMeshMessage) { + String body = ((EventMeshMessage) msg.getBody()).getBody(); + logger.error("receive message -------------------------------" + body); + } + } + } + }); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCPubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCPubClient.java new file mode 100644 index 0000000000..a05a24ab31 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCPubClient.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.common.UserAgentUtils; +import org.apache.eventmesh.runtime.client.impl.PubClientImpl; + +public class CCPubClient { + + public static void main(String[] args) throws Exception { + PubClientImpl pubClient = new PubClientImpl("127.0.0.1", 10000, UserAgentUtils.createUserAgent()); + pubClient.init(); + pubClient.heartbeat(); + + pubClient.broadcast(MessageUtils.rrMesssage(ClientConstants.ASYNC_TOPIC, 0), 5000); + + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCSubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCSubClient.java new file mode 100644 index 0000000000..9e60011fa5 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CCSubClient.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.common.UserAgentUtils; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; +import org.apache.eventmesh.runtime.client.impl.SubClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class CCSubClient { + + private static final Logger logger = LoggerFactory.getLogger(CCSubClient.class); + + public static void main(String[] args) throws Exception { + SubClientImpl subClient = new SubClientImpl("127.0.0.1", 10000, UserAgentUtils.createUserAgent()); + subClient.init(); + subClient.heartbeat(); + subClient.listen(); + subClient.justSubscribe("TEST-TOPIC-TCP-SYNC", SubscriptionMode.CLUSTERING, SubscriptionType.SYNC); + subClient.registerBusiHandler(new ReceiveMsgHook() { + @Override + public void handle(Package msg, ChannelHandlerContext ctx) { + logger.error("Received message: -----------------------------------------" + msg.toString()); + if (msg.getHeader().getCommand() == Command.REQUEST_TO_CLIENT) { + Package rrResponse = MessageUtils.rrResponse(msg); + ctx.writeAndFlush(rrResponse); + } + } + }); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CClientDemo.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CClientDemo.java new file mode 100644 index 0000000000..0b53764c8a --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/CClientDemo.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; +import org.apache.eventmesh.runtime.client.impl.EventMeshClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +/** + * simple client usage example + */ +public class CClientDemo { + + public static Logger logger = LoggerFactory.getLogger(CClientDemo.class); + + private static final String SYNC_TOPIC = "TEST-TOPIC-TCP-SYNC"; + private static final String ASYNC_TOPIC = "TEST-TOPIC-TCP-ASYNC"; + private static final String BROADCAST_TOPIC = "TEST-TOPIC-TCP-BROADCAST"; + + public static void main(String[] args) throws Exception { + EventMeshClientImpl client = new EventMeshClientImpl("127.0.0.1", 10000); + client.init(); + client.heartbeat(); + client.justSubscribe(ASYNC_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC); + client.justSubscribe(BROADCAST_TOPIC, SubscriptionMode.BROADCASTING, SubscriptionType.ASYNC); + client.listen(); + client.registerSubBusiHandler(new ReceiveMsgHook() { + @Override + public void handle(Package msg, ChannelHandlerContext ctx) { + if (msg.getHeader().getCmd() == Command.ASYNC_MESSAGE_TO_CLIENT || msg.getHeader().getCmd() == Command.BROADCAST_MESSAGE_TO_CLIENT) { + logger.error("receive message-------------------------------------" + msg); + } + } + }); + for (int i = 0; i < 10000; i++) { + //ThreadUtil.randomSleep(0,200); + //broadcast message + client.broadcast(MessageUtils.broadcastMessage("TEST-TOPIC-TCP-BROADCAST", i), 5000); + //asynchronous message + client.publish(MessageUtils.asyncMessage(ASYNC_TOPIC, i), 5000); + } + // + //Thread.sleep(10000); + //client.close(); + + + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/SyncPubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/SyncPubClient.java new file mode 100644 index 0000000000..172c7a269b --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/SyncPubClient.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.common.UserAgentUtils; +import org.apache.eventmesh.runtime.client.impl.PubClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SyncPubClient { + + private static final Logger logger = LoggerFactory.getLogger(SyncPubClient.class); + + public static void main(String[] args) throws Exception { + PubClientImpl pubClient = new PubClientImpl("127.0.0.1", 10000, UserAgentUtils.createUserAgent()); + pubClient.init(); + pubClient.heartbeat(); + + for (int i = 0; i < 100; i++) { + Package rr = pubClient.rr(MessageUtils.rrMesssage("TEST-TOPIC-TCP-SYNC", i), 3000); + if (rr.getBody() instanceof EventMeshMessage) { + String body = ((EventMeshMessage) rr.getBody()).getBody(); + logger.error("rrMessage: " + body + " " + "rr-reply-------------------------------------------------" + rr); + } + } + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/SyncSubClient.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/SyncSubClient.java new file mode 100644 index 0000000000..f7d2f12df5 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/demo/SyncSubClient.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.demo; + +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.runtime.client.common.ClientConstants; +import org.apache.eventmesh.runtime.client.common.MessageUtils; +import org.apache.eventmesh.runtime.client.hook.ReceiveMsgHook; +import org.apache.eventmesh.runtime.client.impl.SubClientImpl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class SyncSubClient { + + private static final Logger logger = LoggerFactory.getLogger(SyncSubClient.class); + + public static void main(String[] args) throws Exception { + SubClientImpl client = new SubClientImpl("127.0.0.1", 10000, MessageUtils.generateSubServer()); + client.init(); + client.heartbeat(); + client.justSubscribe(ClientConstants.SYNC_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.SYNC); + client.registerBusiHandler(new ReceiveMsgHook() { + @Override + public void handle(Package msg, ChannelHandlerContext ctx) { + if (msg.getHeader().getCommand() == Command.REQUEST_TO_CLIENT) { + logger.error("receive message -------------------------------" + msg); + } + } + }); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/EventMeshThreadFactoryImplTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/EventMeshThreadFactoryImplTest.java new file mode 100644 index 0000000000..f9b4821852 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/EventMeshThreadFactoryImplTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import org.junit.Assert; +import org.junit.Test; + +public class EventMeshThreadFactoryImplTest { + + @Test + public void testGetThreadNamePrefix() { + final String threadNamePrefix = "threadNamePrefix"; + EventMeshThreadFactoryImpl factory = new EventMeshThreadFactoryImpl(threadNamePrefix, false); + Assert.assertEquals(threadNamePrefix, factory.getThreadNamePrefix()); + } + + @Test + public void testNewThread() { + final String threadNamePrefix = "threadNamePrefix"; + EventMeshThreadFactoryImpl factory = new EventMeshThreadFactoryImpl(threadNamePrefix, true); + Thread t = factory.newThread(() -> {}); + Assert.assertNotNull(t); + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/EventMeshUtilTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/EventMeshUtilTest.java new file mode 100644 index 0000000000..d70424eed7 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/EventMeshUtilTest.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; + +import org.apache.http.client.utils.URIBuilder; + +import java.net.InetAddress; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.util.Map; +import java.util.UUID; +import java.util.regex.Pattern; + +import org.junit.Assert; +import org.junit.Test; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EventMeshUtilTest { + + @Test + public void testBuildPushMsgSeqNo() { + String seq = EventMeshUtil.buildPushMsgSeqNo(); + Assert.assertTrue(Pattern.compile("\\d{17}").matcher(seq).matches()); + Assert.assertEquals(17, seq.length()); + } + + @Test + public void testBuildMeshClientID() { + String clientGroup = "clientGroup"; + String clientID = EventMeshUtil.buildMeshClientID(clientGroup, "LS"); + Assert.assertTrue(clientID.contains(clientGroup)); + } + + @Test + public void testBuildMeshTcpClientID() { + String clientSysId = "clientSysId"; + String clientID = EventMeshUtil.buildMeshTcpClientID(clientSysId, "purpose", "meshCluster"); + Assert.assertTrue(clientID.contains(clientSysId)); + } + + @Test + public void testBuildClientGroup() { + String systemId = "systemId"; + String clientGroup = EventMeshUtil.buildClientGroup(systemId); + Assert.assertEquals(clientGroup, systemId); + } + + @Test + public void testStackTrace() { + Throwable e = new EventMeshException("error"); + String exception = EventMeshUtil.stackTrace(e); + Assert.assertTrue(exception.contains(e.getMessage())); + } + + @Test + public void testCreateJsoner() { + ObjectMapper mapper = EventMeshUtil.createJsoner(); + Assert.assertNotNull(mapper); + } + + @Test + public void testPrintMqMessage() { + EventMeshMessage meshMessage = new EventMeshMessage(); + String result = EventMeshUtil.printMqMessage(meshMessage); + Assert.assertTrue(result.contains("Message")); + } + + @Test + public void testGetMessageBizSeq() throws URISyntaxException { + String value = "keys"; + CloudEvent cloudEvent = CloudEventBuilder.v03().withExtension(EventMeshConstants.KEYS_LOWERCASE, value) + .withId(UUID.randomUUID().toString()) + .withSource(new URIBuilder().build()) + .withType("type") + .build(); + String result = EventMeshUtil.getMessageBizSeq(cloudEvent); + Assert.assertEquals(result, value); + } + + @Test + public void testGetEventProp() throws URISyntaxException { + String value = "keys"; + CloudEvent cloudEvent = CloudEventBuilder.v03().withExtension(EventMeshConstants.KEYS_LOWERCASE, value) + .withId(UUID.randomUUID().toString()) + .withSource(new URIBuilder().build()) + .withType("type") + .build(); + Map result = EventMeshUtil.getEventProp(cloudEvent); + Assert.assertEquals(result.get(EventMeshConstants.KEYS_LOWERCASE), value); + } + + @Test + public void testGetLocalAddr() { + String addr = EventMeshUtil.getLocalAddr(); + Assert.assertNotNull(addr); + } + + @Test + public void testNormalizeHostAddress() throws UnknownHostException { + InetAddress localAddress = InetAddress.getLocalHost(); + String result = EventMeshUtil.normalizeHostAddress(localAddress); + Assert.assertNotNull(result); + } + + @Test + public void testBuildUserAgentClientId() { + String subSystem = "subsystem"; + String host = "127.0.0.1"; + int pid = 1; + int port = 8080; + UserAgent agent = UserAgent.builder().subsystem(subSystem).host(host) + .pid(pid).port(port).build(); + String result = EventMeshUtil.buildUserAgentClientId(agent); + Assert.assertEquals(result, String.format("%s--%d-%s:%d", subSystem, pid, host, port)); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/HttpTinyClientTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/HttpTinyClientTest.java new file mode 100644 index 0000000000..6bfdc82041 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/HttpTinyClientTest.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.runtime.util.HttpTinyClient.HttpResult; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +public class HttpTinyClientTest { + + @Test + public void testHttpGet() throws IOException { + String content = "http mock response"; + HttpURLConnection conn = mock(HttpURLConnection.class); + URL url = mock(URL.class); + doNothing().when(conn).connect(); + when(url.openConnection()).thenReturn(conn); + when(conn.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + try (MockedStatic dummyStatic = Mockito.mockStatic(IOTinyUtils.class)) { + dummyStatic.when(() -> IOTinyUtils.toString(any(), any())).thenReturn(content); + String requestUrl = "https://eventmesh.apache.org"; + HttpResult result = HttpTinyClient.httpGet(requestUrl, null, null, "utf-8", 0); + Assert.assertEquals(result.getContent(), content); + Assert.assertEquals(result.getCode(), HttpURLConnection.HTTP_OK); + } + } + + @Test + public void testHttpPost() throws IOException { + String content = "http mock response"; + HttpURLConnection conn = mock(HttpURLConnection.class); + URL url = mock(URL.class); + doNothing().when(conn).connect(); + when(url.openConnection()).thenReturn(conn); + when(conn.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + + OutputStream outputStream = mock(OutputStream.class); + doNothing().when(outputStream).write(new byte[0]); + when(conn.getOutputStream()).thenReturn(outputStream); + try (MockedStatic dummyStatic = Mockito.mockStatic(IOTinyUtils.class)) { + dummyStatic.when(() -> IOTinyUtils.toString(any(), any())).thenReturn(content); + String requestUrl = "https://eventmesh.apache.org"; + HttpResult result = HttpTinyClient.httpPost(requestUrl, anyList(), anyList(), "utf-8", 0); + Assert.assertEquals(result.getContent(), content); + Assert.assertEquals(result.getCode(), HttpURLConnection.HTTP_OK); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/IOTinyUtilsTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/IOTinyUtilsTest.java new file mode 100644 index 0000000000..05888a2b7f --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/IOTinyUtilsTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.when; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.MockedConstruction; + +public class IOTinyUtilsTest { + + @Test + public void testCopy() throws Exception { + BufferedReader input = mock(BufferedReader.class); + BufferedWriter output = mock(BufferedWriter.class); + int count = 10; + char[] buffer = new char[1 << 12]; + doNothing().when(output).write(buffer, 0, count); + when(input.read(buffer)).thenReturn(10, 10, -1); + long result = IOTinyUtils.copy(input, output); + Assert.assertEquals(result, count * 2); + } + + @Test + public void testReadLines() throws IOException { + BufferedReader input = mock(BufferedReader.class); + when(input.readLine()).thenReturn("hello", "world", null); + List result = IOTinyUtils.readLines(input); + Assert.assertEquals(result.get(0), "hello"); + } + + @Test + public void testCopyFile() { + } + + @Test + public void testCleanDirectory() throws IOException { + File dirFile = mock(File.class); + when(dirFile.exists()).thenReturn(true); + when(dirFile.isDirectory()).thenReturn(true); + + File normalFile = mock(File.class); + when(normalFile.exists()).thenReturn(true); + when(normalFile.isDirectory()).thenReturn(false); + when(normalFile.delete()).thenReturn(true); + + File[] files = {normalFile}; + when(dirFile.listFiles()).thenReturn(files); + IOTinyUtils.cleanDirectory(dirFile); + } + + @Test + public void testWriteStringToFile() throws IOException { + File file = mock(File.class); + try (MockedConstruction ignored = mockConstruction(FileOutputStream.class, + (mock, context) -> doNothing().when(mock).write(any()))) { + IOTinyUtils.writeStringToFile(file, "data", "utf-8"); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/NetUtilsTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/NetUtilsTest.java new file mode 100644 index 0000000000..26e87d7aa2 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/NetUtilsTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class NetUtilsTest { + + @Test + public void testFormData2Dic() { + String formData = ""; + Map result = NetUtils.formData2Dic(formData); + Assert.assertTrue(result.isEmpty()); + + formData = "item_id=10081&item_name=test item name"; + result = NetUtils.formData2Dic(formData); + Assert.assertEquals(result.get("item_id"), "10081"); + } + + @Test + public void testAddressToString() { + List clients = new ArrayList<>(); + String result = NetUtils.addressToString(clients); + Assert.assertEquals(result, "no session had been closed"); + + InetSocketAddress localAddress = new InetSocketAddress(80); + clients.add(localAddress); + result = NetUtils.addressToString(clients); + Assert.assertEquals(result, localAddress + "|"); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/RemotingHelperTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/RemotingHelperTest.java new file mode 100644 index 0000000000..0f82bd1db9 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/RemotingHelperTest.java @@ -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 org.apache.eventmesh.runtime.util; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import io.netty.channel.Channel; + +public class RemotingHelperTest { + + @Test + public void testExceptionSimpleDesc() { + String result = RemotingHelper.exceptionSimpleDesc(new NullPointerException()); + Assert.assertNotNull(result); + } + + @Test + public void testString2SocketAddress() { + String addr = "10.1.1.1:11002"; + SocketAddress address = RemotingHelper.string2SocketAddress(addr); + Assert.assertNotNull(address); + } + + @Test + public void testParseChannelRemoteAddr() { + SocketAddress address = new InetSocketAddress("127.0.0.1", 80); + Channel channel = Mockito.mock(Channel.class); + Mockito.when(channel.remoteAddress()).thenReturn(address); + String addr = RemotingHelper.parseChannelRemoteAddr(channel); + Assert.assertEquals(addr, "127.0.0.1:80"); + } + + @Test + public void testParseSocketAddressAddr() { + SocketAddress address = new InetSocketAddress("127.0.0.1", 80); + String addr = RemotingHelper.parseSocketAddressAddr(address); + Assert.assertEquals(addr, "127.0.0.1:80"); + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/WebhookUtilTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/WebhookUtilTest.java new file mode 100644 index 0000000000..6dd5bcedb1 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/WebhookUtilTest.java @@ -0,0 +1,70 @@ +/* + @Test + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.runtime.util; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; + +import org.apache.eventmesh.api.auth.AuthService; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.message.BasicHeader; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +public class WebhookUtilTest { + + @Test + public void testObtainDeliveryAgreement() throws Exception { + CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class); + CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); + Mockito.when(response.getLastHeader("WebHook-Allowed-Origin")).thenReturn(new BasicHeader("WebHook-Allowed-Origin", "*")); + Mockito.when(httpClient.execute(any())).thenReturn(response); + Assert.assertTrue(WebhookUtil.obtainDeliveryAgreement(httpClient, "https://eventmesh.apache.org", "*")); + } + + @Test + public void testSetWebhookHeaders() { + String authType = "auth-http-basic"; + AuthService authService = mock(AuthService.class); + doNothing().when(authService).init(); + Map authParams = new HashMap<>(); + String key = "Authorization"; + String value = "Basic ****"; + authParams.put(key, value); + Mockito.when(authService.getAuthParams()).thenReturn(authParams); + + try (MockedStatic dummyStatic = Mockito.mockStatic(EventMeshExtensionFactory.class)) { + dummyStatic.when(() -> EventMeshExtensionFactory.getExtension(AuthService.class, authType)).thenReturn(authService); + HttpPost post = new HttpPost(); + WebhookUtil.setWebhookHeaders(post, "application/json", "eventmesh.FT", authType); + Assert.assertEquals(post.getLastHeader(key).getValue(), value); + } + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/test/resources/log4j2.xml b/eventmesh-runtime/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..da0a6059fa --- /dev/null +++ b/eventmesh-runtime/src/test/resources/log4j2.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eventmesh-sdk-go/README.md b/eventmesh-sdk-go/README.md new file mode 100644 index 0000000000..efdb1cef74 --- /dev/null +++ b/eventmesh-sdk-go/README.md @@ -0,0 +1,6 @@ +EventMesh Go SDK +--- +support api +1. gRPC +2. HTTP +3. TCP \ No newline at end of file diff --git a/eventmesh-sdk-go/common/constants.go b/eventmesh-sdk-go/common/constants.go new file mode 100644 index 0000000000..b4f8449b61 --- /dev/null +++ b/eventmesh-sdk-go/common/constants.go @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +var Constants = struct { + LANGUAGE_GO string + HTTP_PROTOCOL_PREFIX string + HTTPS_PROTOCOL_PREFIX string + PROTOCOL_TYPE string + PROTOCOL_VERSION string + PROTOCOL_DESC string + DEFAULT_HTTP_TIME_OUT int64 + EVENTMESH_MESSAGE_CONST_TTL string + + // Client heartbeat interval + HEARTBEAT int64 + + // Protocol type + CLOUD_EVENTS_PROTOCOL_NAME string + EM_MESSAGE_PROTOCOL_NAME string + OPEN_MESSAGE_PROTOCOL_NAME string +}{ + LANGUAGE_GO: "GO", + HTTP_PROTOCOL_PREFIX: "http://", + HTTPS_PROTOCOL_PREFIX: "https://", + PROTOCOL_TYPE: "protocoltype", + PROTOCOL_VERSION: "protocolversion", + PROTOCOL_DESC: "protocoldesc", + DEFAULT_HTTP_TIME_OUT: 15000, + EVENTMESH_MESSAGE_CONST_TTL: "ttl", + HEARTBEAT: 30 * 1000, + CLOUD_EVENTS_PROTOCOL_NAME: "cloudevents", + EM_MESSAGE_PROTOCOL_NAME: "eventmeshmessage", + OPEN_MESSAGE_PROTOCOL_NAME: "openmessage", +} diff --git a/eventmesh-sdk-go/common/id/api.go b/eventmesh-sdk-go/common/id/api.go new file mode 100644 index 0000000000..379b5457c5 --- /dev/null +++ b/eventmesh-sdk-go/common/id/api.go @@ -0,0 +1,22 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package id + +// Interface api to generate uniq id +type Interface interface { + // Next create uniq ID + Next() string +} diff --git a/eventmesh-sdk-go/common/id/id_snake.go b/eventmesh-sdk-go/common/id/id_snake.go new file mode 100644 index 0000000000..675669a55e --- /dev/null +++ b/eventmesh-sdk-go/common/id/id_snake.go @@ -0,0 +1,79 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package id + +import ( + "bytes" + "fmt" + "net" + "strconv" + "strings" + + "github.com/sony/sonyflake" +) + +// flake generate uid by flake +type flake struct { + sf *sonyflake.Sonyflake +} + +func NewFlake() Interface { + macAddr := getMacAddr() + st := sonyflake.Settings{ + MachineID: func() (uint16, error) { + ma := strings.Split(macAddr, ":") + mid, err := strconv.ParseInt(ma[0]+ma[1], 16, 16) + return uint16(mid), err + }, + } + return &flake{ + sf: sonyflake.NewSonyflake(st), + } +} + +// getMacAddr return the current machine mac address +func getMacAddr() (addr string) { + interfaces, err := net.Interfaces() + if err == nil { + for _, i := range interfaces { + if i.Flags&net.FlagUp != 0 && bytes.Compare(i.HardwareAddr, nil) != 0 { + // Don't use random as we have a real address + addr = i.HardwareAddr.String() + break + } + } + } + return +} + +// Nextv generates next id as an uint64 +func (f *flake) Nextv() (id uint64, err error) { + var i uint64 + if f.sf != nil { + i, err = f.sf.NextID() + if err == nil { + id = i + } + } + return +} + +// Next generates next id as a string +func (f *flake) Next() string { + var i uint64 + i, _ = f.Nextv() + return fmt.Sprintf("%d", i) +} diff --git a/eventmesh-sdk-go/common/id/id_uuid.go b/eventmesh-sdk-go/common/id/id_uuid.go new file mode 100644 index 0000000000..fb1c36a5ef --- /dev/null +++ b/eventmesh-sdk-go/common/id/id_uuid.go @@ -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 id + +import ( + "github.com/google/uuid" + "strings" +) + +// UUID generate id by uuid +type UUID struct { +} + +// NewUUID uuid instance +func NewUUID() Interface { + return &UUID{} +} + +func (u *UUID) Next() string { + return strings.ReplaceAll(uuid.New().String(), "-", "") +} diff --git a/eventmesh-sdk-go/common/protocol/http/body/body.go b/eventmesh-sdk-go/common/protocol/http/body/body.go new file mode 100644 index 0000000000..f7053ffdf5 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/body/body.go @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package body + +type Body struct { + ToMap map[string]interface{} +} + +func (b *Body) BuildBody(requestCode string, originalMap map[string]interface{}) *Body { + return nil +} diff --git a/eventmesh-sdk-go/common/protocol/http/body/client/heartbeat_request_body.go b/eventmesh-sdk-go/common/protocol/http/body/client/heartbeat_request_body.go new file mode 100644 index 0000000000..e7ebe973b7 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/body/client/heartbeat_request_body.go @@ -0,0 +1,72 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/http/body" +) + +var HeartbeatRequestBodyKey = struct { + CLIENTTYPE string + CONSUMERGROUP string + HEARTBEATENTITIES string +}{ + CLIENTTYPE: "clientType", + HEARTBEATENTITIES: "heartbeatEntities", + CONSUMERGROUP: "consumerGroup", +} + +type HeartbeatEntity struct { + Topic string `json:"topic"` + Url string `json:"url"` + ServiceId string `json:"serviceId"` + InstanceId string `json:"instanceId"` +} + +type HeartbeatRequestBody struct { + body.Body + consumerGroup string + clientType string + heartbeatEntities string +} + +func (h *HeartbeatRequestBody) ConsumerGroup() string { + return h.consumerGroup +} + +func (h *HeartbeatRequestBody) SetConsumerGroup(consumerGroup string) { + h.consumerGroup = consumerGroup +} + +func (h *HeartbeatRequestBody) ClientType() string { + return h.clientType +} + +func (h *HeartbeatRequestBody) SetClientType(clientType string) { + h.clientType = clientType +} + +func (h *HeartbeatRequestBody) HeartbeatEntities() string { + return h.heartbeatEntities +} + +func (h *HeartbeatRequestBody) SetHeartbeatEntities(heartbeatEntities string) { + h.heartbeatEntities = heartbeatEntities +} + +func (h *HeartbeatRequestBody) BuildBody(bodyParam map[string]interface{}) *HeartbeatRequestBody { + return nil +} diff --git a/eventmesh-sdk-go/common/protocol/http/body/client/subscribe_request_body.go b/eventmesh-sdk-go/common/protocol/http/body/client/subscribe_request_body.go new file mode 100644 index 0000000000..78dc39cccc --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/body/client/subscribe_request_body.go @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package client + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/http/body" +) + +var SubscribeRequestBodyKey = struct { + TOPIC string + URL string + CONSUMERGROUP string +}{ + TOPIC: "topic", + URL: "url", + CONSUMERGROUP: "consumerGroup", +} + +type SubscribeRequestBody struct { + body.Body + topics []protocol.SubscriptionItem + url string + consumerGroup string +} diff --git a/eventmesh-sdk-go/common/protocol/http/common/client_type.go b/eventmesh-sdk-go/common/protocol/http/common/client_type.go new file mode 100644 index 0000000000..28e8d05784 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/common/client_type.go @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +type ClientType struct { + Type int `json:"type"` + Desc string `json:"desc"` +} + +var DefaultClientType = struct { + PUB ClientType + SUB ClientType +}{ + PUB: ClientType{ + Type: 1, + Desc: "Client for publishing", + }, + SUB: ClientType{ + Type: 2, + Desc: "Client for subscribing", + }, +} diff --git a/eventmesh-sdk-go/common/protocol/http/common/eventmesh_ret_code.go b/eventmesh-sdk-go/common/protocol/http/common/eventmesh_ret_code.go new file mode 100644 index 0000000000..55358cb7d9 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/common/eventmesh_ret_code.go @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +type EventMeshRetCode struct { + RetCode int `json:"retCode"` + ErrMsg string `json:"errMsg"` +} + +var DefaultEventMeshRetCode = struct { + SUCCESS EventMeshRetCode +}{ + SUCCESS: EventMeshRetCode{RetCode: 0, ErrMsg: "success"}, +} diff --git a/eventmesh-sdk-go/common/protocol/http/common/protocol_key.go b/eventmesh-sdk-go/common/protocol/http/common/protocol_key.go new file mode 100644 index 0000000000..11337ccc0d --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/common/protocol_key.go @@ -0,0 +1,85 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +type ClientInstanceKey struct { + //Protocol layer requester description + ENV string + IDC string + SYS string + PID string + IP string + USERNAME string + PASSWORD string + BIZSEQNO string + UNIQUEID string +} + +type EventMeshInstanceKey struct { + //Protocol layer EventMesh description + EVENTMESHCLUSTER string + EVENTMESHIP string + EVENTMESHENV string + EVENTMESHIDC string +} + +var ProtocolKey = struct { + REQUEST_CODE string + LANGUAGE string + VERSION string + PROTOCOL_TYPE string + PROTOCOL_VERSION string + PROTOCOL_DESC string + + ClientInstanceKey ClientInstanceKey + + EventMeshInstanceKey EventMeshInstanceKey + + //return of CLIENT <-> EventMesh + RETCODE string + RETMSG string + RESTIME string +}{ + REQUEST_CODE: "code", + LANGUAGE: "language", + VERSION: "version", + PROTOCOL_TYPE: "protocoltype", + PROTOCOL_VERSION: "protocolversion", + PROTOCOL_DESC: "protocoldesc", + + ClientInstanceKey: ClientInstanceKey{ + ENV: "env", + IDC: "idc", + SYS: "sys", + PID: "pid", + IP: "ip", + USERNAME: "username", + PASSWORD: "passwd", + BIZSEQNO: "bizseqno", + UNIQUEID: "uniqueid", + }, + + EventMeshInstanceKey: EventMeshInstanceKey{ + EVENTMESHCLUSTER: "eventmeshcluster", + EVENTMESHIP: "eventmeship", + EVENTMESHENV: "eventmeshenv", + EVENTMESHIDC: "eventmeshidc", + }, + + RETCODE: "retCode", + RETMSG: "retMsg", + RESTIME: "resTime", +} diff --git a/eventmesh-sdk-go/common/protocol/http/common/protocol_version.go b/eventmesh-sdk-go/common/protocol/http/common/protocol_version.go new file mode 100644 index 0000000000..bdf774686a --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/common/protocol_version.go @@ -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 common + +type ProtocolVersion struct { + version string +} + +func (p *ProtocolVersion) Version() string { + return p.version +} + +func (p *ProtocolVersion) SetVersion(version string) { + p.version = version +} + +var DefaultProtocolVersion = struct { + V1 ProtocolVersion + V2 ProtocolVersion +}{ + V1: ProtocolVersion{ + version: "1.0", + }, + V2: ProtocolVersion{ + version: "2.0", + }, +} diff --git a/eventmesh-sdk-go/common/protocol/http/common/request_code.go b/eventmesh-sdk-go/common/protocol/http/common/request_code.go new file mode 100644 index 0000000000..38407f19f0 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/common/request_code.go @@ -0,0 +1,95 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +type RequestCode struct { + RequestCode int `json:"requestCode"` + Desc string `json:"desc"` +} + +var DefaultRequestCode = struct { + MSG_BATCH_SEND RequestCode + MSG_BATCH_SEND_V2 RequestCode + MSG_SEND_SYNC RequestCode + MSG_SEND_ASYNC RequestCode + HTTP_PUSH_CLIENT_ASYNC RequestCode + HTTP_PUSH_CLIENT_SYNC RequestCode + REGISTER RequestCode + UNREGISTER RequestCode + HEARTBEAT RequestCode + SUBSCRIBE RequestCode + UNSUBSCRIBE RequestCode + REPLY_MESSAGE RequestCode + ADMIN_METRICS RequestCode + ADMIN_SHUTDOWN RequestCode +}{ + MSG_BATCH_SEND: RequestCode{ + RequestCode: 102, + Desc: "SEND BATCH MSG", + }, + MSG_BATCH_SEND_V2: RequestCode{ + RequestCode: 107, + Desc: "SEND BATCH MSG V2", + }, + MSG_SEND_SYNC: RequestCode{ + RequestCode: 101, + Desc: "SEND SINGLE MSG SYNC", + }, + MSG_SEND_ASYNC: RequestCode{ + RequestCode: 104, + Desc: "SEND SINGLE MSG ASYNC", + }, + HTTP_PUSH_CLIENT_ASYNC: RequestCode{ + RequestCode: 105, + Desc: "PUSH CLIENT BY HTTP POST", + }, + HTTP_PUSH_CLIENT_SYNC: RequestCode{ + RequestCode: 106, + Desc: "PUSH CLIENT BY HTTP POST", + }, + REGISTER: RequestCode{ + RequestCode: 201, + Desc: "REGISTER", + }, + UNREGISTER: RequestCode{ + RequestCode: 202, + Desc: "UNREGISTER", + }, + HEARTBEAT: RequestCode{ + RequestCode: 203, + Desc: "HEARTBEAT", + }, + SUBSCRIBE: RequestCode{ + RequestCode: 206, + Desc: "SUBSCRIBE", + }, + UNSUBSCRIBE: RequestCode{ + RequestCode: 207, + Desc: "UNSUBSCRIBE", + }, + REPLY_MESSAGE: RequestCode{ + RequestCode: 301, + Desc: "REPLY MESSAGE", + }, + ADMIN_METRICS: RequestCode{ + RequestCode: 603, + Desc: "ADMIN METRICS", + }, + ADMIN_SHUTDOWN: RequestCode{ + RequestCode: 601, + Desc: "ADMIN SHUTDOWN", + }, +} diff --git a/eventmesh-sdk-go/common/protocol/http/message/send_message_request_body.go b/eventmesh-sdk-go/common/protocol/http/message/send_message_request_body.go new file mode 100644 index 0000000000..a74fdbeaa2 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/http/message/send_message_request_body.go @@ -0,0 +1,111 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package message + +type SendMessageRequestBody struct { + topic string + bizSeqNo string + uniqueId string + ttl string + content string + tag string + extFields map[string]string + producerGroup string +} + +func (s *SendMessageRequestBody) Topic() string { + return s.topic +} + +func (s *SendMessageRequestBody) SetTopic(topic string) { + s.topic = topic +} + +func (s *SendMessageRequestBody) BizSeqNo() string { + return s.bizSeqNo +} + +func (s *SendMessageRequestBody) SetBizSeqNo(bizSeqNo string) { + s.bizSeqNo = bizSeqNo +} + +func (s *SendMessageRequestBody) UniqueId() string { + return s.uniqueId +} + +func (s *SendMessageRequestBody) SetUniqueId(uniqueId string) { + s.uniqueId = uniqueId +} + +func (s *SendMessageRequestBody) Ttl() string { + return s.ttl +} + +func (s *SendMessageRequestBody) SetTtl(ttl string) { + s.ttl = ttl +} + +func (s *SendMessageRequestBody) Content() string { + return s.content +} + +func (s *SendMessageRequestBody) SetContent(content string) { + s.content = content +} + +func (s *SendMessageRequestBody) Tag() string { + return s.tag +} + +func (s *SendMessageRequestBody) SetTag(tag string) { + s.tag = tag +} + +func (s *SendMessageRequestBody) ExtFields() map[string]string { + return s.extFields +} + +func (s *SendMessageRequestBody) SetExtFields(extFields map[string]string) { + s.extFields = extFields +} + +func (s *SendMessageRequestBody) ProducerGroup() string { + return s.producerGroup +} + +func (s *SendMessageRequestBody) SetProducerGroup(producerGroup string) { + s.producerGroup = producerGroup +} + +var SendMessageRequestBodyKey = struct { + TOPIC string + BIZSEQNO string + UNIQUEID string + CONTENT string + TTL string + TAG string + EXTFIELDS string + PRODUCERGROUP string +}{ + TOPIC: "topic", + BIZSEQNO: "bizseqno", + UNIQUEID: "uniqueid", + CONTENT: "content", + TTL: "ttl", + TAG: "tag", + EXTFIELDS: "extFields", + PRODUCERGROUP: "producergroup", +} diff --git a/eventmesh-sdk-go/common/protocol/message_type.go b/eventmesh-sdk-go/common/protocol/message_type.go new file mode 100644 index 0000000000..590d189878 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/message_type.go @@ -0,0 +1,28 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +type MessageType string + +var DefaultMessageType = struct { + CloudEvent MessageType + OpenMessage MessageType + EventMeshMessage MessageType +}{ + CloudEvent: "CloudEvent", + OpenMessage: "OpenMessage", + EventMeshMessage: "EventMeshMessage", +} diff --git a/eventmesh-sdk-go/common/protocol/subscription_item.go b/eventmesh-sdk-go/common/protocol/subscription_item.go new file mode 100644 index 0000000000..65e828663f --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/subscription_item.go @@ -0,0 +1,22 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +type SubscriptionItem struct { + Topic string `json:"topic"` + Mode SubscriptionMode `json:"mode"` + Type SubscriptionType `json:"type"` +} diff --git a/eventmesh-sdk-go/common/protocol/subscription_mode.go b/eventmesh-sdk-go/common/protocol/subscription_mode.go new file mode 100644 index 0000000000..89f933c8dc --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/subscription_mode.go @@ -0,0 +1,26 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +type SubscriptionMode string + +var DefaultSubscriptionMode = struct { + BROADCASTING SubscriptionMode + CLUSTERING SubscriptionMode +}{ + BROADCASTING: "BROADCASTING", + CLUSTERING: "CLUSTERING", +} diff --git a/eventmesh-sdk-go/common/protocol/subscription_type.go b/eventmesh-sdk-go/common/protocol/subscription_type.go new file mode 100644 index 0000000000..cacf314b8b --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/subscription_type.go @@ -0,0 +1,26 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package protocol + +type SubscriptionType string + +var DefaultSubscriptionType = struct { + SYNC SubscriptionType + ASYNC SubscriptionType +}{ + SYNC: "SYNC", + ASYNC: "ASYNC", +} diff --git a/eventmesh-sdk-go/common/protocol/tcp/codec/codec.go b/eventmesh-sdk-go/common/protocol/tcp/codec/codec.go new file mode 100644 index 0000000000..a2f588715c --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/tcp/codec/codec.go @@ -0,0 +1,184 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package codec + +import ( + "bytes" + "encoding/binary" + + gcommon "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + gutils "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/common" +) + +const ( + MAGIC = "EventMesh" + VERSION = "0000" + LENGTH_SIZE = 4 +) + +func EncodePackage(message tcp.Package) *bytes.Buffer { + + header := message.Header + headerData := header.Marshal() + + var bodyData []byte + if header.GetProperty(gcommon.Constants.PROTOCOL_TYPE) != common.EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME { + bodyData = gutils.MarshalJsonBytes(message.Body) + } else { + bodyData = (message.Body).([]byte) + } + + headerLen := len(headerData) + bodyLen := len(bodyData) + + length := LENGTH_SIZE + LENGTH_SIZE + headerLen + bodyLen + + var out bytes.Buffer + out.WriteString(MAGIC) + out.WriteString(VERSION) + + lengthBytes := make([]byte, LENGTH_SIZE) + binary.BigEndian.PutUint32(lengthBytes, uint32(length)) + + headerLenBytes := make([]byte, LENGTH_SIZE) + binary.BigEndian.PutUint32(headerLenBytes, uint32(headerLen)) + + out.Write(lengthBytes) + out.Write(headerLenBytes) + out.Write(headerData) + out.Write(bodyData) + + return &out +} + +func DecodePackage(in *bytes.Buffer) tcp.Package { + flagBytes := parseFlag(in) + versionBytes := parseVersion(in) + validateFlag(flagBytes, versionBytes) + + length := parseLength(in) + headerLen := parseLength(in) + bodyLen := length - headerLen - LENGTH_SIZE - LENGTH_SIZE + header := parseHeader(in, int(headerLen)) + body := parseBody(in, header, int(bodyLen)) + return tcp.Package{Header: header, Body: body} +} + +func parseFlag(in *bytes.Buffer) []byte { + flagLen := len([]byte(MAGIC)) + flagBytes := make([]byte, flagLen) + n, err := in.Read(flagBytes) + if err != nil { + return nil + } + log.Infof("read %d bytes (flag) ", n) + return flagBytes +} + +func parseVersion(in *bytes.Buffer) []byte { + verLen := len([]byte(VERSION)) + verBytes := make([]byte, verLen) + n, err := in.Read(verBytes) + if err != nil { + return nil + } + log.Infof("read %d bytes (version) ", n) + return verBytes +} + +func parseLength(in *bytes.Buffer) uint32 { + lenBytes := make([]byte, 4) + n, err := in.Read(lenBytes) + if err != nil { + log.Errorf("Failed to parse length") + } + log.Infof("read %d bytes (length) ", n) + return binary.BigEndian.Uint32(lenBytes) +} + +func parseHeader(in *bytes.Buffer, headerLen int) tcp.Header { + headerBytes := make([]byte, headerLen) + n, err := in.Read(headerBytes) + if err != nil { + log.Errorf("Failed to parse header") + } + log.Infof("read %d bytes (header) ", n) + + var header tcp.Header + return header.Unmarshal(headerBytes) +} + +func parseBody(in *bytes.Buffer, header tcp.Header, bodyLen int) interface{} { + if bodyLen <= 0 { + return nil + } + + bodyBytes := make([]byte, bodyLen) + n, err := in.Read(bodyBytes) + if err != nil { + log.Errorf("Failed to parse body") + } + log.Infof("read %d bytes (body) ", n) + + bodyStr := string(bodyBytes) + return deserializeBody(bodyStr, header) +} + +func deserializeBody(bodyStr string, header tcp.Header) interface{} { + command := header.Cmd + switch command { + case tcp.DefaultCommand.HELLO_REQUEST: + case tcp.DefaultCommand.RECOMMEND_REQUEST: + var useAgent tcp.UserAgent + gutils.UnMarshalJsonString(bodyStr, &useAgent) + return useAgent + case tcp.DefaultCommand.SUBSCRIBE_REQUEST: + case tcp.DefaultCommand.UNSUBSCRIBE_REQUEST: + return nil + //return OBJECT_MAPPER.readValue(bodyJsonString, Subscription.class); + case tcp.DefaultCommand.REQUEST_TO_SERVER: + case tcp.DefaultCommand.RESPONSE_TO_SERVER: + case tcp.DefaultCommand.ASYNC_MESSAGE_TO_SERVER: + case tcp.DefaultCommand.BROADCAST_MESSAGE_TO_SERVER: + case tcp.DefaultCommand.REQUEST_TO_CLIENT: + case tcp.DefaultCommand.RESPONSE_TO_CLIENT: + case tcp.DefaultCommand.ASYNC_MESSAGE_TO_CLIENT: + case tcp.DefaultCommand.BROADCAST_MESSAGE_TO_CLIENT: + case tcp.DefaultCommand.REQUEST_TO_CLIENT_ACK: + case tcp.DefaultCommand.RESPONSE_TO_CLIENT_ACK: + case tcp.DefaultCommand.ASYNC_MESSAGE_TO_CLIENT_ACK: + case tcp.DefaultCommand.BROADCAST_MESSAGE_TO_CLIENT_ACK: + // The message string will be deserialized by protocol plugin, if the event is cloudevents, the body is + // just a string. + return bodyStr + case tcp.DefaultCommand.REDIRECT_TO_CLIENT: + return nil + //return OBJECT_MAPPER.readValue(bodyJsonString, RedirectInfo.class); + default: + // FIXME improve codes + log.Errorf("Invalidate TCP command: %s", command) + return nil + } + + return nil +} + +func validateFlag(flagBytes, versionBytes []byte) { + // TODO add check +} diff --git a/eventmesh-sdk-go/common/protocol/tcp/command.go b/eventmesh-sdk-go/common/protocol/tcp/command.go new file mode 100644 index 0000000000..8b316dffbf --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/tcp/command.go @@ -0,0 +1,217 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp + +type Command string + +var DefaultCommand = struct { + //heartbeat + HEARTBEAT_REQUEST Command //client send heartbeat packet to server + HEARTBEAT_RESPONSE Command //server response heartbeat packet of client + + //handshake + HELLO_REQUEST Command //client send handshake request to server + HELLO_RESPONSE Command //server response handshake request of client + + //disconnection + CLIENT_GOODBYE_REQUEST Command //Notify server when client actively disconnects + CLIENT_GOODBYE_RESPONSE Command //Server replies to client's active disconnection notification + SERVER_GOODBYE_REQUEST Command //Notify client when server actively disconnects + SERVER_GOODBYE_RESPONSE Command //Client replies to server's active disconnection notification + + //subscription management + SUBSCRIBE_REQUEST Command //Subscription request sent by client to server + SUBSCRIBE_RESPONSE Command //Server replies to client's subscription request + UNSUBSCRIBE_REQUEST Command //Unsubscribe request from client to server + UNSUBSCRIBE_RESPONSE Command //Server replies to client's unsubscribe request + + //monitor + LISTEN_REQUEST Command //Request from client to server to start topic listening + LISTEN_RESPONSE Command //The server replies to the client's listening request + + //RR + REQUEST_TO_SERVER Command //The client sends the RR request to the server + REQUEST_TO_CLIENT Command //The server pushes the RR request to the client + REQUEST_TO_CLIENT_ACK Command //After receiving RR request, the client sends ACK to the server + RESPONSE_TO_SERVER Command //The client sends the RR packet back to the server + RESPONSE_TO_CLIENT Command //The server pushes the RR packet back to the client + RESPONSE_TO_CLIENT_ACK Command //After receiving the return packet, the client sends ACK to the server + + //Asynchronous events + ASYNC_MESSAGE_TO_SERVER Command //The client sends asynchronous events to the server + ASYNC_MESSAGE_TO_SERVER_ACK Command //After receiving the asynchronous event, the server sends ack to the client + ASYNC_MESSAGE_TO_CLIENT Command //The server pushes asynchronous events to the client + ASYNC_MESSAGE_TO_CLIENT_ACK Command //After the client receives the asynchronous event, the ACK is sent to the server + + //radio broadcast + BROADCAST_MESSAGE_TO_SERVER Command //The client sends the broadcast message to the server + BROADCAST_MESSAGE_TO_SERVER_ACK Command //After receiving the broadcast message, the server sends ACK to the client + BROADCAST_MESSAGE_TO_CLIENT Command //The server pushes the broadcast message to the client + BROADCAST_MESSAGE_TO_CLIENT_ACK Command //After the client receives the broadcast message, the ACK is sent to the server + + //Log reporting + SYS_LOG_TO_LOGSERVER Command //Business log reporting + + //RMB tracking log reporting + TRACE_LOG_TO_LOGSERVER Command //RMB tracking log reporting + + //Redirecting instruction + REDIRECT_TO_CLIENT Command //The server pushes the redirection instruction to the client + + //service register + REGISTER_REQUEST Command //Client sends registration request to server + REGISTER_RESPONSE Command //The server sends the registration result to the client + + //service unregister + UNREGISTER_REQUEST Command //The client sends a de registration request to the server + UNREGISTER_RESPONSE Command //The server will register the result to the client + + //The client asks which EventMesh to recommend + RECOMMEND_REQUEST Command //Client sends recommendation request to server + RECOMMEND_RESPONSE Command //The server will recommend the results to the client +}{ + //heartbeat + HEARTBEAT_REQUEST: "HEARTBEAT_REQUEST", + HEARTBEAT_RESPONSE: "HEARTBEAT_RESPONSE", + + //handshake + HELLO_REQUEST: "HELLO_REQUEST", + HELLO_RESPONSE: "HELLO_RESPONSE", + + //disconnection + CLIENT_GOODBYE_REQUEST: "CLIENT_GOODBYE_REQUEST", + CLIENT_GOODBYE_RESPONSE: "CLIENT_GOODBYE_RESPONSE", + SERVER_GOODBYE_REQUEST: "SERVER_GOODBYE_REQUEST", + SERVER_GOODBYE_RESPONSE: "SERVER_GOODBYE_RESPONSE", + + //subscription management + SUBSCRIBE_REQUEST: "SUBSCRIBE_REQUEST", + SUBSCRIBE_RESPONSE: "SUBSCRIBE_RESPONSE", + UNSUBSCRIBE_REQUEST: "UNSUBSCRIBE_REQUEST", + UNSUBSCRIBE_RESPONSE: "UNSUBSCRIBE_RESPONSE", + + //monitor + LISTEN_REQUEST: "LISTEN_REQUEST", + LISTEN_RESPONSE: "LISTEN_RESPONSE", + + //RR + REQUEST_TO_SERVER: "REQUEST_TO_SERVER", + REQUEST_TO_CLIENT: "REQUEST_TO_CLIENT", + REQUEST_TO_CLIENT_ACK: "REQUEST_TO_CLIENT_ACK", + RESPONSE_TO_SERVER: "RESPONSE_TO_SERVER", + RESPONSE_TO_CLIENT: "RESPONSE_TO_CLIENT", + RESPONSE_TO_CLIENT_ACK: "RESPONSE_TO_CLIENT_ACK", + + //Asynchronous events + ASYNC_MESSAGE_TO_SERVER: "ASYNC_MESSAGE_TO_SERVER", + ASYNC_MESSAGE_TO_SERVER_ACK: "ASYNC_MESSAGE_TO_SERVER_ACK", + ASYNC_MESSAGE_TO_CLIENT: "ASYNC_MESSAGE_TO_CLIENT", + ASYNC_MESSAGE_TO_CLIENT_ACK: "ASYNC_MESSAGE_TO_CLIENT_ACK", + + //radio broadcast + BROADCAST_MESSAGE_TO_SERVER: "BROADCAST_MESSAGE_TO_SERVER", + BROADCAST_MESSAGE_TO_SERVER_ACK: "BROADCAST_MESSAGE_TO_SERVER_ACK", + BROADCAST_MESSAGE_TO_CLIENT: "BROADCAST_MESSAGE_TO_CLIENT", + BROADCAST_MESSAGE_TO_CLIENT_ACK: "BROADCAST_MESSAGE_TO_CLIENT_ACK", + + //Log reporting + SYS_LOG_TO_LOGSERVER: "SYS_LOG_TO_LOGSERVER", + + //RMB tracking log reporting + TRACE_LOG_TO_LOGSERVER: "TRACE_LOG_TO_LOGSERVER", + + //Redirecting instruction + REDIRECT_TO_CLIENT: "REDIRECT_TO_CLIENT", + + //service register + REGISTER_REQUEST: "REGISTER_REQUEST", + REGISTER_RESPONSE: "REGISTER_RESPONSE", + + //service unregister + UNREGISTER_REQUEST: "UNREGISTER_REQUEST", + UNREGISTER_RESPONSE: "UNREGISTER_RESPONSE", + + //The client asks which EventMesh to recommend + RECOMMEND_REQUEST: "RECOMMEND_REQUEST", + RECOMMEND_RESPONSE: "RECOMMEND_RESPONSE", +} + +//{ +// //heartbeat +// HEARTBEAT_REQUEST: 0, +// HEARTBEAT_RESPONSE: 1, +// +// //handshake +// HELLO_REQUEST: 2, +// HELLO_RESPONSE: 3, +// +// //disconnection +// CLIENT_GOODBYE_REQUEST: 4, +// CLIENT_GOODBYE_RESPONSE: 5, +// SERVER_GOODBYE_REQUEST: 6, +// SERVER_GOODBYE_RESPONSE: 7, +// +// //subscription management +// SUBSCRIBE_REQUEST: 8, +// SUBSCRIBE_RESPONSE: 9, +// UNSUBSCRIBE_REQUEST: 10, +// UNSUBSCRIBE_RESPONSE: 11, +// +// //monitor +// LISTEN_REQUEST: 12, +// LISTEN_RESPONSE: 13, +// +// //RR +// REQUEST_TO_SERVER: 14, +// REQUEST_TO_CLIENT: 15, +// REQUEST_TO_CLIENT_ACK: 16, +// RESPONSE_TO_SERVER: 17, +// RESPONSE_TO_CLIENT: 18, +// RESPONSE_TO_CLIENT_ACK: 19, +// +// //Asynchronous events +// ASYNC_MESSAGE_TO_SERVER: 20, +// ASYNC_MESSAGE_TO_SERVER_ACK: 21, +// ASYNC_MESSAGE_TO_CLIENT: 22, +// ASYNC_MESSAGE_TO_CLIENT_ACK: 23, +// +// //radio broadcast +// BROADCAST_MESSAGE_TO_SERVER: 24, +// BROADCAST_MESSAGE_TO_SERVER_ACK: 25, +// BROADCAST_MESSAGE_TO_CLIENT: 26, +// BROADCAST_MESSAGE_TO_CLIENT_ACK: 27, +// +// //Log reporting +// SYS_LOG_TO_LOGSERVER: 28, +// +// //RMB tracking log reporting +// TRACE_LOG_TO_LOGSERVER: 29, +// +// //Redirecting instruction +// REDIRECT_TO_CLIENT: 30, +// +// //service register +// REGISTER_REQUEST: 31, +// REGISTER_RESPONSE: 32, +// +// //service unregister +// UNREGISTER_REQUEST: 33, +// UNREGISTER_RESPONSE: 34, +// +// //The client asks which EventMesh to recommend +// RECOMMEND_REQUEST: 35, +// RECOMMEND_RESPONSE: 36, +//} diff --git a/eventmesh-sdk-go/common/protocol/tcp/header.go b/eventmesh-sdk-go/common/protocol/tcp/header.go new file mode 100644 index 0000000000..ed8dcf81ee --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/tcp/header.go @@ -0,0 +1,95 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" +) + +type Header struct { + Cmd Command `json:"cmd"` + Code int `json:"code"` + Desc string `json:"desc"` + Seq string `json:"seq"` + Properties map[string]interface{} `json:"properties"` +} + +func (h Header) PutProperty(name string, value interface{}) { + h.Properties[name] = value +} + +func (h Header) GetProperty(name string) interface{} { + if h.Properties == nil { + return nil + } + + if val, ok := h.Properties[name]; ok { + return val + } + + return nil +} + +func (h Header) Marshal() []byte { + newHeader := make(map[string]interface{}) + newHeader["cmd"] = h.Cmd + // Compatible with Java Enum serialization + newHeader["command"] = h.Cmd + newHeader["code"] = h.Code + newHeader["desc"] = h.Desc + newHeader["seq"] = h.Seq + newHeader["properties"] = h.Properties + return utils.MarshalJsonBytes(newHeader) +} + +func (h Header) getVal(key string, headerDict map[string]interface{}) interface{} { + if val, ok := headerDict[key]; ok { + return val + } + return nil +} + +func (h Header) Unmarshal(header []byte) Header { + + var headerDict map[string]interface{} + utils.UnMarshalJsonBytes(header, &headerDict) + + if val := h.getVal("cmd", headerDict); val != nil { + h.Cmd = Command(val.(string)) + } + + if val := h.getVal("code", headerDict); val != nil { + h.Code = int(val.(float64)) + } + + if val := h.getVal("desc", headerDict); val != nil { + h.Desc = val.(string) + } + + if val := h.getVal("seq", headerDict); val != nil { + h.Seq = val.(string) + } + + if val := h.getVal("properties", headerDict); val != nil { + h.Properties = val.(map[string]interface{}) + } + + return h +} + +func NewHeader(cmd Command, code int, desc string, seq string) Header { + return Header{Cmd: cmd, Code: code, Desc: desc, Seq: seq, Properties: map[string]interface{}{}} +} diff --git a/eventmesh-sdk-go/common/protocol/tcp/package.go b/eventmesh-sdk-go/common/protocol/tcp/package.go new file mode 100644 index 0000000000..7e579047ff --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/tcp/package.go @@ -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 tcp + +type Package struct { + Header Header `json:"header"` + Body interface{} `json:"body"` +} + +func NewPackage(header Header) Package { + return Package{Header: header} +} diff --git a/eventmesh-sdk-go/common/protocol/tcp/user_agent.go b/eventmesh-sdk-go/common/protocol/tcp/user_agent.go new file mode 100644 index 0000000000..8c309e1895 --- /dev/null +++ b/eventmesh-sdk-go/common/protocol/tcp/user_agent.go @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp + +type UserAgent struct { + Env string `json:"env"` + Subsystem string `json:"subsystem"` + Path string `json:"path"` + Pid int `json:"pid"` + Host string `json:"host"` + Port int `json:"port"` + Version string `json:"version"` + Username string `json:"username"` + Password string `json:"password"` + Idc string `json:"idc"` + Group string `json:"group"` + Purpose string `json:"purpose"` + Unack int `json:"unack"` +} + +func NewUserAgent(env string, subsystem string, path string, pid int, host string, port int, version string, + username string, password string, idc string, producerGroup string, consumerGroup string) *UserAgent { + return &UserAgent{Env: env, Subsystem: subsystem, Path: path, Pid: pid, Host: host, Port: port, Version: version, + Username: username, Password: password, Idc: idc, Group: producerGroup} +} diff --git a/eventmesh-sdk-go/common/seq/num.go b/eventmesh-sdk-go/common/seq/num.go new file mode 100644 index 0000000000..c962ea8731 --- /dev/null +++ b/eventmesh-sdk-go/common/seq/num.go @@ -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 seq + +import ( + "fmt" + "go.uber.org/atomic" +) + +// Interface to generate sequence number +type Interface interface { + Next() string +} + +// AtomicSeq use atomic.Int64 to create seq number +type AtomicSeq struct { + *atomic.Uint64 +} + +// NewAtomicSeq new atomic sequence instance +func NewAtomicSeq() Interface { + return &AtomicSeq{ + Uint64: atomic.NewUint64(0), + } +} + +func (a *AtomicSeq) Next() string { + return fmt.Sprintf("%v", a.Inc()) +} diff --git a/eventmesh-sdk-go/common/utils/ip.go b/eventmesh-sdk-go/common/utils/ip.go new file mode 100644 index 0000000000..588cff3d32 --- /dev/null +++ b/eventmesh-sdk-go/common/utils/ip.go @@ -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 utils + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + + "net" + "sync" +) + +var ( + // hostIP hold the client ip for current machine + hostIPv4 string + + // ipOnce once to set the hostIP + ipOnce sync.Once +) + +// HostIPV4 return the current client ip v4 +func HostIPV4() string { + ipOnce.Do(func() { + addrs, err := net.InterfaceAddrs() + if err != nil { + log.Panicf("get client ipv4, enum addrs err:%v", err) + } + for _, addr := range addrs { + if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + hostIPv4 = ipnet.IP.String() + } + } + } + if hostIPv4 == "" { + log.Panicf("get client ipv4 is empty") + } + }) + return hostIPv4 +} diff --git a/eventmesh-sdk-go/common/utils/json_utils.go b/eventmesh-sdk-go/common/utils/json_utils.go new file mode 100644 index 0000000000..f871609d87 --- /dev/null +++ b/eventmesh-sdk-go/common/utils/json_utils.go @@ -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 utils + +import ( + "encoding/json" + + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" +) + +func MarshalJsonBytes(obj interface{}) []byte { + ret, err := json.Marshal(obj) + if err != nil { + log.Fatalf("Failed to marshal json") + } + return ret +} + +func MarshalJsonString(obj interface{}) string { + return string(MarshalJsonBytes(obj)) +} + +func UnMarshalJsonBytes(data []byte, obj interface{}) { + err := json.Unmarshal(data, obj) + if err != nil { + log.Fatalf("Failed to unmarshal json") + } +} + +func UnMarshalJsonString(data string, obj interface{}) { + UnMarshalJsonBytes([]byte(data), obj) +} diff --git a/eventmesh-sdk-go/common/utils/pid.go b/eventmesh-sdk-go/common/utils/pid.go new file mode 100644 index 0000000000..abfdc8bd85 --- /dev/null +++ b/eventmesh-sdk-go/common/utils/pid.go @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "fmt" + "os" + "sync" +) + +var ( + // pid the current running process id + pid string + + // pidOnce make sure get pid once + pidOnce sync.Once +) + +// CurrentPID return the current running process id +func CurrentPID() string { + pidOnce.Do(func() { + pid = fmt.Sprintf("%v", os.Getpid()) + }) + return pid +} diff --git a/eventmesh-sdk-go/examples/grpc/consumer/asyncsub/main.go b/eventmesh-sdk-go/examples/grpc/consumer/asyncsub/main.go new file mode 100644 index 0000000000..28f26a7b54 --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/consumer/asyncsub/main.go @@ -0,0 +1,77 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "io/ioutil" + "net/http" + "time" +) + +func main() { + cli, err := grpc.New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-async-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + if err != nil { + panic(err) + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + err = cli.SubscribeWebhook(conf.SubscribeItem{ + SubscribeMode: conf.CLUSTERING, + SubscribeType: conf.ASYNC, + Topic: "async-sub-grpc-topic", + }, "http://localhost:8080/onmessage") + if err != nil { + fmt.Println(err.Error()) + return + } + http.HandleFunc("/onmessage", func(writer http.ResponseWriter, request *http.Request) { + buf, err := ioutil.ReadAll(request.Body) + if err != nil { + return + } + defer request.Body.Close() + fmt.Println(string(buf)) + }) + http.ListenAndServe(":8080", nil) +} diff --git a/eventmesh-sdk-go/examples/grpc/consumer/boradcast/main.go b/eventmesh-sdk-go/examples/grpc/consumer/boradcast/main.go new file mode 100644 index 0000000000..6d5c518820 --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/consumer/boradcast/main.go @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "time" +) + +func main() { + cli, err := grpc.New(&conf.GRPCConfig{ + Host: "101.43.84.47", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-broadcast-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + if err != nil { + panic(err) + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + err = cli.SubscribeWebhook(conf.SubscribeItem{ + SubscribeMode: conf.BROADCASTING, + SubscribeType: conf.ASYNC, + Topic: "grpc-broadcast-topic", + }, "") + if err != nil { + fmt.Println(err.Error()) + return + } + time.Sleep(time.Hour) +} diff --git a/eventmesh-sdk-go/examples/grpc/consumer/broadcast/main.go b/eventmesh-sdk-go/examples/grpc/consumer/broadcast/main.go new file mode 100644 index 0000000000..47973c5e70 --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/consumer/broadcast/main.go @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "time" +) + +func main() { + cli, err := grpc.New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-broadcast-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + if err != nil { + panic(err) + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + err = cli.SubscribeWebhook(conf.SubscribeItem{ + SubscribeMode: conf.BROADCASTING, + SubscribeType: conf.ASYNC, + Topic: "grpc-broadcast-topic", + }, "http://localhost:18080/onmessage") + if err != nil { + fmt.Println(err.Error()) + return + } + time.Sleep(time.Hour) +} diff --git a/eventmesh-sdk-go/examples/grpc/consumer/rr/main.go b/eventmesh-sdk-go/examples/grpc/consumer/rr/main.go new file mode 100644 index 0000000000..d95b44ef81 --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/consumer/rr/main.go @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "time" +) + +func main() { + cli, err := grpc.New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-sync-consumer-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + if err != nil { + panic(err) + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + err = cli.SubscribeWebhook(conf.SubscribeItem{ + SubscribeMode: conf.CLUSTERING, + SubscribeType: conf.SYNC, + Topic: "grpc-topic", + }, "") + if err != nil { + fmt.Println(err.Error()) + return + } + time.Sleep(time.Hour) +} diff --git a/eventmesh-sdk-go/examples/grpc/consumer/stream/main.go b/eventmesh-sdk-go/examples/grpc/consumer/stream/main.go new file mode 100644 index 0000000000..32303feb7d --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/consumer/stream/main.go @@ -0,0 +1,71 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "time" +) + +func main() { + cli, err := grpc.New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-sync-consumer-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + if err != nil { + panic(err) + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + err = cli.SubscribeStream(conf.SubscribeItem{ + SubscribeMode: conf.CLUSTERING, + SubscribeType: conf.ASYNC, + Topic: "grpc-topic", + }, func(msg *proto.SimpleMessage) interface{} { + fmt.Println("receive msg: " + msg.String()) + return nil + }) + if err != nil { + fmt.Println(err.Error()) + return + } + time.Sleep(time.Hour) +} diff --git a/eventmesh-sdk-go/examples/grpc/producer/bp/main.go b/eventmesh-sdk-go/examples/grpc/producer/bp/main.go new file mode 100644 index 0000000000..fe3cb55607 --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/producer/bp/main.go @@ -0,0 +1,88 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" +) + +func main() { + cfg := &conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-batch-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: false, + }, + } + cli, err := grpc.New(cfg) + if err != nil { + fmt.Println("create publish client err:" + err.Error()) + return + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + batchMsg := &proto.BatchMessage{ + Header: grpc.CreateHeader(cfg), + ProducerGroup: "grpc-producergroup", + Topic: "grpc-batch-topic", + MessageItem: []*proto.BatchMessage_MessageItem{ + { + Content: "test for batch publish go grpc -1", + Ttl: "1024", + UniqueId: "110", + SeqNum: "111", + Tag: "batch publish tag 1", + Properties: map[string]string{ + "from": "grpc", + "type": "batch publish", + }, + }, + { + Content: "test for batch publish go grpc", + Ttl: "1024", + UniqueId: "210", + SeqNum: "211", + Tag: "batch publish tag 2", + Properties: map[string]string{ + "from": "grpc", + "type": "batch publish", + }, + }, + }, + } + resp, err := cli.BatchPublish(context.TODO(), batchMsg) + if err != nil { + panic(err) + } + fmt.Println(resp.String()) +} diff --git a/eventmesh-sdk-go/examples/grpc/producer/publish/main.go b/eventmesh-sdk-go/examples/grpc/producer/publish/main.go new file mode 100644 index 0000000000..c86fcedc8e --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/producer/publish/main.go @@ -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 main + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/google/uuid" + "time" +) + +func main() { + cfg := &conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: false, + }, + } + cli, err := grpc.New(cfg) + if err != nil { + fmt.Println("create publish client err:" + err.Error()) + return + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + for i := 0; i < 10; i++ { + builder := grpc.NewMessageBuilder() + builder.WithHeader(grpc.CreateHeader(cfg)). + WithContent("test for publish go grpc"). + WithProperties(map[string]string{ + "from": "grpc", + "for": "test"}). + WithProducerGroup("grpc-publish-producergroup"). + WithTag("grpc publish tag"). + WithTopic("grpc-topic"). + WithTTL(time.Hour). + WithSeqNO(uuid.New().String()). + WithUniqueID(uuid.New().String()) + resp, err := cli.Publish(context.TODO(), builder.SimpleMessage) + if err != nil { + panic(err) + } + fmt.Println(resp.String()) + } +} diff --git a/eventmesh-sdk-go/examples/grpc/producer/rr/main.go b/eventmesh-sdk-go/examples/grpc/producer/rr/main.go new file mode 100644 index 0000000000..70e486bf09 --- /dev/null +++ b/eventmesh-sdk-go/examples/grpc/producer/rr/main.go @@ -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 main + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "time" +) + +func main() { + cfg := &conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 10205, + ENV: "go-grpc-test-env", + Region: "sh", + IDC: "pd", + SYS: "grpc-go", + Username: "grpc-go-username", + Password: "grpc-go-passwd", + ProtocolType: grpc.EventmeshMessage, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-rr-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: false, + }, + } + cli, err := grpc.New(cfg) + if err != nil { + panic(err) + } + defer func() { + if err := cli.Close(); err != nil { + panic(err) + } + }() + builder := grpc.NewMessageBuilder() + builder.WithHeader(grpc.CreateHeader(cfg)). + WithContent("test for rr go grpc"). + WithProperties(map[string]string{ + "from": "grpc", + "for": "test"}). + WithProducerGroup("grpc-rr-producergroup"). + WithTag("grpc rr tag"). + WithTopic("grpc-topic"). + WithTTL(time.Hour). + WithSeqNO("1"). + WithUniqueID("1") + + msg, err := cli.RequestReply(context.TODO(), builder.SimpleMessage) + if err != nil { + fmt.Println("send rr msg err:" + err.Error()) + return + } + fmt.Println(msg.String()) + +} diff --git a/eventmesh-sdk-go/examples/http/async_pub_cloudevents.go b/eventmesh-sdk-go/examples/http/async_pub_cloudevents.go new file mode 100644 index 0000000000..5ca6362ae5 --- /dev/null +++ b/eventmesh-sdk-go/examples/http/async_pub_cloudevents.go @@ -0,0 +1,69 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package http + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/producer" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + + cloudevents "github.com/cloudevents/sdk-go/v2" + "github.com/google/uuid" + + "os" + "strconv" +) + +func AsyncPubCloudEvents() { + eventMeshIPPort := "127.0.0.1" + ":" + "10105" + producerGroup := "EventMeshTest-producerGroup" + topic := "TEST-TOPIC-HTTP-ASYNC" + env := "P" + idc := "FT" + subSys := "1234" + // FIXME Get ip dynamically + localIp := "127.0.0.1" + + // (Deep) Copy of default config + eventMeshClientConfig := conf.DefaultEventMeshHttpClientConfig + eventMeshClientConfig.SetLiteEventMeshAddr(eventMeshIPPort) + eventMeshClientConfig.SetProducerGroup(producerGroup) + eventMeshClientConfig.SetEnv(env) + eventMeshClientConfig.SetIdc(idc) + eventMeshClientConfig.SetSys(subSys) + eventMeshClientConfig.SetIp(localIp) + eventMeshClientConfig.SetPid(strconv.Itoa(os.Getpid())) + + // Make event to send + event := cloudevents.NewEvent() + event.SetID(uuid.New().String()) + event.SetSubject(topic) + event.SetSource("example/uri") + event.SetType(common.Constants.CLOUD_EVENTS_PROTOCOL_NAME) + event.SetExtension(common.Constants.EVENTMESH_MESSAGE_CONST_TTL, strconv.Itoa(4*1000)) + event.SetDataContentType(cloudevents.ApplicationCloudEventsJSON) + data := map[string]string{"hello": "EventMesh"} + err := event.SetData(cloudevents.ApplicationCloudEventsJSON, utils.MarshalJsonBytes(data)) + if err != nil { + log.Fatalf("Failed to set cloud event data, error: %v", err) + } + + // Publish event + httpProducer := producer.NewEventMeshHttpProducer(eventMeshClientConfig) + httpProducer.Publish(event) +} diff --git a/eventmesh-sdk-go/examples/http/sub_cloudevents.go b/eventmesh-sdk-go/examples/http/sub_cloudevents.go new file mode 100644 index 0000000000..76b9866cc8 --- /dev/null +++ b/eventmesh-sdk-go/examples/http/sub_cloudevents.go @@ -0,0 +1,115 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package http + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/consumer" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + + cloudevents "github.com/cloudevents/sdk-go/v2" + "net/http" + "os" + "strconv" + "strings" +) + +func SubCloudEvents() { + eventMeshIPPort := "127.0.0.1" + ":" + "10105" + consumerGroup := "EventMeshTest-consumerGroup" + topic := "TEST-TOPIC-HTTP-ASYNC" + env := "P" + idc := "FT" + subSys := "1234" + // FIXME Get ip dynamically + localIp := "127.0.0.1" + localPort := 8090 + + subscribeUrl := "http://" + localIp + ":" + strconv.Itoa(localPort) + "/hello" + topicList := []protocol.SubscriptionItem{ + { + Topic: topic, + Mode: protocol.DefaultSubscriptionMode.CLUSTERING, + Type: protocol.DefaultSubscriptionType.ASYNC, + }, + } + + // Callback handle + exit := make(chan bool) + go httpServer(localIp, localPort, exit) + + // (Deep) Copy of default config + eventMeshClientConfig := conf.DefaultEventMeshHttpClientConfig + eventMeshClientConfig.SetLiteEventMeshAddr(eventMeshIPPort) + eventMeshClientConfig.SetConsumerGroup(consumerGroup) + eventMeshClientConfig.SetEnv(env) + eventMeshClientConfig.SetIdc(idc) + eventMeshClientConfig.SetSys(subSys) + eventMeshClientConfig.SetIp(localIp) + eventMeshClientConfig.SetPid(strconv.Itoa(os.Getpid())) + + // Subscribe + eventMeshHttpConsumer := consumer.NewEventMeshHttpConsumer(eventMeshClientConfig) + eventMeshHttpConsumer.Subscribe(topicList, subscribeUrl) + eventMeshHttpConsumer.HeartBeat(topicList, subscribeUrl) + + // FIXME Add unsubscribe + + // Wait for exit + <-exit +} + +func httpServer(ip string, port int, exit chan<- bool) { + http.HandleFunc("/hello", hello) + err := http.ListenAndServe(ip+":"+strconv.Itoa(port), nil) + if err != nil { + log.Fatalf("Failed to launch a callback http server, error: %v", err) + } + + exit <- true +} + +func hello(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/hello" { + http.NotFound(w, r) + return + } + + switch r.Method { + case "POST": + contentType := r.Header.Get("Content-Type") + + // FIXME Now we only support post form + if strings.Contains(contentType, "application/x-www-form-urlencoded") { + err := r.ParseForm() + if err != nil { + log.Errorf("Failed to parse post form parameter, error: %v", err) + } + content := r.FormValue("content") + event := cloudevents.NewEvent() + utils.UnMarshalJsonString(content, &event) + log.Infof("Received data from eventmesh server: %v", string(event.Data())) + return + } + + w.WriteHeader(http.StatusUnsupportedMediaType) + default: + w.WriteHeader(http.StatusNotImplemented) + w.Write([]byte(http.StatusText(http.StatusNotImplemented))) + } +} diff --git a/eventmesh-sdk-go/examples/tcp/async_pub_cloudevents.go b/eventmesh-sdk-go/examples/tcp/async_pub_cloudevents.go new file mode 100644 index 0000000000..0af60d5f53 --- /dev/null +++ b/eventmesh-sdk-go/examples/tcp/async_pub_cloudevents.go @@ -0,0 +1,60 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp + +import ( + "time" + + "github.com/google/uuid" + "strconv" + + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol" + gtcp "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/conf" + cloudevents "github.com/cloudevents/sdk-go/v2" +) + +func AsyncPubCloudEvents() { + eventMeshIp := "127.0.0.1" + eventMeshTcpPort := 10000 + topic := "TEST-TOPIC-TCP-ASYNC" + + // Init client + userAgent := gtcp.UserAgent{Env: "test", Subsystem: "5023", Path: "/data/app/umg_proxy", Pid: 32893, + Host: "127.0.0.1", Port: 8362, Version: "2.0.11", Username: "PU4283", Password: "PUPASS", Idc: "FT", + Group: "EventmeshTestGroup", Purpose: "pub"} + config := conf.NewEventMeshTCPClientConfig(eventMeshIp, eventMeshTcpPort, userAgent) + client := tcp.CreateEventMeshTCPClient(*config, protocol.DefaultMessageType.CloudEvent) + client.Init() + + // Make event to send + event := cloudevents.NewEvent() + event.SetID(uuid.New().String()) + event.SetSubject(topic) + event.SetSource("example/uri") + event.SetType(common.Constants.CLOUD_EVENTS_PROTOCOL_NAME) + event.SetExtension(common.Constants.EVENTMESH_MESSAGE_CONST_TTL, strconv.Itoa(4*1000)) + event.SetDataContentType(cloudevents.ApplicationCloudEventsJSON) + data := map[string]string{"hello": "EventMesh"} + event.SetData(cloudevents.ApplicationCloudEventsJSON, utils.MarshalJsonBytes(data)) + + // Publish event + client.Publish(event, 10000) + time.Sleep(10 * time.Second) +} diff --git a/eventmesh-sdk-go/go.mod b/eventmesh-sdk-go/go.mod new file mode 100644 index 0000000000..2ae6bd6c9a --- /dev/null +++ b/eventmesh-sdk-go/go.mod @@ -0,0 +1,32 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +module github.com/apache/incubator-eventmesh/eventmesh-sdk-go + +go 1.16 + +require ( + github.com/cespare/xxhash v1.1.0 + github.com/cloudevents/sdk-go/v2 v2.6.0 + github.com/google/uuid v1.3.0 + github.com/json-iterator/go v1.1.10 + github.com/panjf2000/ants v1.3.0 + github.com/sony/sonyflake v1.0.0 + github.com/stretchr/testify v1.7.0 + go.uber.org/atomic v1.4.0 + go.uber.org/zap v1.10.0 + google.golang.org/grpc v1.45.0 + google.golang.org/protobuf v1.28.0 +) diff --git a/eventmesh-sdk-go/go.sum b/eventmesh-sdk-go/go.sum new file mode 100644 index 0000000000..80f6b9c21c --- /dev/null +++ b/eventmesh-sdk-go/go.sum @@ -0,0 +1,172 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudevents/sdk-go/v2 v2.6.0 h1:yp6zLEvhXSi6P25zzfgORgFI0quG2/NXoH9QoHzvKn8= +github.com/cloudevents/sdk-go/v2 v2.6.0/go.mod h1:nlXhgFkf0uTopxmRXalyMwS2LG70cRGPrxzmjJgSG0U= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= +github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/panjf2000/ants v1.3.0 h1:8pQ+8leaLc9lys2viEEr8md0U4RN6uOSUCE9bOYjQ9M= +github.com/panjf2000/ants v1.3.0/go.mod h1:AaACblRPzq35m1g3enqYcxspbbiOJJYaxU2wMpm1cXY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= +github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/eventmesh-sdk-go/grpc/README.md b/eventmesh-sdk-go/grpc/README.md new file mode 100644 index 0000000000..e22a5a9555 --- /dev/null +++ b/eventmesh-sdk-go/grpc/README.md @@ -0,0 +1,43 @@ +grpc +=== +grpc client for evenemesh, support multiple type of loadbalancer + +how to use +--- +### send message + +### subscribe message + +setup with option +--- +### 1. setup the logger +if you want to rewrite the log to other place, such as some promethus and so on, you need to implements the ```log.Logger``` +interface, and set it with ```GRPCOption``` +for example: +```GO +type selfLogger struct{ +} + +func (s *selfLogger) Infof(template string, args ...interface{}) { + // todo +} +// ... +// other methods + +cli, err := grpc.New(&conf.GRPCConfig{}, []Option{WithLogger(&selfLogger{})}) +``` +### 2. setup the idgen +in grpc client, we provide two kinds of id generator, uuid/flake, you can refers to ```commom/id``` for details. +and if you want to implement it yourself, just implement the ```id.Interface``` api, for example: +```GO +type selfIdg struct{} +func (s* selfIdg) Next() string { + return "uniq id" +} + +cli, err := grpc.New(&conf.GRPCConfig{}, []Option{WithID(&selfIdg{})}) +``` + +TODO +--- +use etcd as service discovery \ No newline at end of file diff --git a/eventmesh-sdk-go/grpc/api.go b/eventmesh-sdk-go/grpc/api.go new file mode 100644 index 0000000000..b6568e6d6f --- /dev/null +++ b/eventmesh-sdk-go/grpc/api.go @@ -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 grpc + +import ( + "context" + + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "google.golang.org/grpc" +) + +// OnMessage on receive message from eventmesh, used in subscribe message +type OnMessage func(*proto.SimpleMessage) interface{} + +// Interface grpc client to producer and consumer message +type Interface interface { + // Publish send message to eventmesh, without wait the response from other client + Publish(ctx context.Context, msg *proto.SimpleMessage, opts ...grpc.CallOption) (*proto.Response, error) + + // RequestReply send message to eventmesh, and wait for the response + RequestReply(ctx context.Context, msg *proto.SimpleMessage, opts ...grpc.CallOption) (*proto.SimpleMessage, error) + + // BatchPublish send batch message to eventmesh + BatchPublish(ctx context.Context, msg *proto.BatchMessage, opts ...grpc.CallOption) (*proto.Response, error) + + // SubscribeWebhook consumer message in webhook, and OnMessage invoked when new message arrived + SubscribeWebhook(item conf.SubscribeItem, callbackURL string) error + + // SubscribeStream stream subscribe the message + SubscribeStream(item conf.SubscribeItem, handler OnMessage) error + + // UnSubscribe unsubcribe topic, and don't subscribe msg anymore + UnSubscribe() error + + // Close release all resources in the client + Close() error +} diff --git a/eventmesh-sdk-go/grpc/client.go b/eventmesh-sdk-go/grpc/client.go new file mode 100644 index 0000000000..d77373e070 --- /dev/null +++ b/eventmesh-sdk-go/grpc/client.go @@ -0,0 +1,192 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/id" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/seq" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "math/rand" + "time" +) + +// New create new eventmesh grpc client +func New(cfg *conf.GRPCConfig, opts ...GRPCOption) (Interface, error) { + cli, err := newEventMeshGRPCClient(cfg, opts...) + if err != nil { + return nil, err + } + + return cli, err +} + +// eventMeshGRPCClient define the grpc client for eventmesh api +type eventMeshGRPCClient struct { + grpcConn *grpc.ClientConn + // producer used to send msg to evenmesh + *eventMeshProducer + // consumer used to subscribe msg from eventmesh + *eventMeshConsumer + // cancel to close the client + cancel context.CancelFunc + // idg generate id api + idg id.Interface + // seqg generate uniq id + seqg seq.Interface +} + +// newEventMeshGRPCClient create new grpc client +func newEventMeshGRPCClient(cfg *conf.GRPCConfig, opts ...GRPCOption) (*eventMeshGRPCClient, error) { + var ( + err error + ctx, cancel = context.WithCancel(context.Background()) + grpConn *grpc.ClientConn + ) + if err = conf.ValidateDefaultConf(cfg); err != nil { + return nil, err + } + defer func() { + if err != nil && grpConn != nil { + // if err != nil and the grpc.ClientConn is connected + // we need to close it + if err := grpConn.Close(); err != nil { + log.Warnf("failed to close conn with, err:%v", err) + } + } + }() + makeGRPCConn := func(host string, port int) (*grpc.ClientConn, error) { + addr := fmt.Sprintf("%v:%v", host, port) + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + log.Warnf("failed to make grpc conn with:%s, err:%v", addr, err) + return nil, err + } + log.Infof("success make grpc conn with:%s", addr) + return conn, nil + } + cli := &eventMeshGRPCClient{} + for _, opt := range opts { + opt(cli) + } + if cli.idg == nil { + cli.idg = id.NewUUID() + } + if cli.seqg == nil { + cli.seqg = seq.NewAtomicSeq() + } + time.Sleep(time.Nanosecond * time.Duration(rand.Int31n(50))) + conn, err := makeGRPCConn(cfg.Host, cfg.Port) + if err != nil { + return nil, err + } + grpConn = conn + producer, err := newProducer(grpConn) + if err != nil { + log.Warnf("failed to create producer, err:%v", err) + return nil, err + } + cli.grpcConn = grpConn + cli.eventMeshProducer = producer + cli.cancel = cancel + if cfg.ConsumerConfig.Enabled { + log.Infof("subscribe enabled") + consumer, err := newConsumer(ctx, cfg, grpConn, cli.idg, cli.seqg) + if err != nil { + log.Warnf("failed to create producer, err:%v", err) + return nil, err + } + if err := consumer.startConsumerStream(); err != nil { + return nil, err + } + cli.eventMeshConsumer = consumer + } + + return cli, nil +} + +// Publish send message to eventmesh, without wait the response from other client +func (e *eventMeshGRPCClient) Publish(ctx context.Context, msg *proto.SimpleMessage, opts ...grpc.CallOption) (*proto.Response, error) { + ctx = e.setupContext(ctx) + return e.eventMeshProducer.Publish(ctx, msg, opts...) +} + +// RequestReply send message to eventmesh, and wait for the response +func (e *eventMeshGRPCClient) RequestReply(ctx context.Context, msg *proto.SimpleMessage, opts ...grpc.CallOption) (*proto.SimpleMessage, error) { + ctx = e.setupContext(ctx) + return e.eventMeshProducer.RequestReply(ctx, msg, opts...) +} + +// BatchPublish send batch message to eventmesh +func (e *eventMeshGRPCClient) BatchPublish(ctx context.Context, msg *proto.BatchMessage, opts ...grpc.CallOption) (*proto.Response, error) { + ctx = e.setupContext(ctx) + return e.eventMeshProducer.BatchPublish(ctx, msg, opts...) +} + +// SubscribeWebhook consumer message, and OnMessage invoked when new message arrived +func (e *eventMeshGRPCClient) SubscribeWebhook(item conf.SubscribeItem, callbackURL string) error { + return e.Subscribe(item, callbackURL) +} + +// SubscribeStream subscribe stream for topic +func (e *eventMeshGRPCClient) SubscribeStream(item conf.SubscribeItem, handler OnMessage) error { + return e.SubscribeWithStream(item, handler) +} + +// UnSubscribe unsubcribe topic, and don't subscribe msg anymore +func (e *eventMeshGRPCClient) UnSubscribe() error { + return e.eventMeshConsumer.UnSubscribe() +} + +// setupContext set up the context, add id if not exist +func (e *eventMeshGRPCClient) setupContext(ctx context.Context) context.Context { + val := ctx.Value(GRPC_ID_KEY) + if val == nil { + ctx = context.WithValue(ctx, GRPC_ID_KEY, e.idg.Next()) + } + return ctx +} + +// Close meshclient and free all resources +func (e *eventMeshGRPCClient) Close() error { + log.Infof("close grpc client") + if e.cancel != nil { + e.cancel() + } + if e.eventMeshProducer != nil { + if err := e.eventMeshProducer.Close(); err != nil { + log.Warnf("close producer err:%v", err) + } + e.eventMeshProducer = nil + } + if e.eventMeshConsumer != nil { + if err := e.eventMeshConsumer.close(); err != nil { + log.Warnf("close consumer err:%v", err) + } + e.eventMeshConsumer = nil + } + if err := e.grpcConn.Close(); err != nil { + log.Warnf("err in close conn with err:%v", err) + } + + log.Infof("success close grpc client") + return nil +} diff --git a/eventmesh-sdk-go/grpc/client_test.go b/eventmesh-sdk-go/grpc/client_test.go new file mode 100644 index 0000000000..f3ebf3b8ec --- /dev/null +++ b/eventmesh-sdk-go/grpc/client_test.go @@ -0,0 +1,464 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + "testing" + "time" +) + +func Test_newEventMeshGRPCClient(t *testing.T) { + type args struct { + cfg *conf.GRPCConfig + } + tests := []struct { + name string + args args + want *eventMeshGRPCClient + wantErr bool + }{ + { + name: "host is empty", + args: args{cfg: &conf.GRPCConfig{ + Host: "", + }}, + wantErr: true, + want: nil, + }, + { + name: "producer wrong", + args: args{cfg: &conf.GRPCConfig{ + Host: "1.1.1.1", + ProducerConfig: conf.ProducerConfig{}, + }}, + wantErr: true, + want: nil, + }, + { + name: "client with send msg", + args: args{cfg: &conf.GRPCConfig{ + Host: "101.43.84.47", + Port: 10205, + ENV: "sendmsgenv", + Region: "sh", + IDC: "idc01", + SYS: "test-system", + ProtocolType: "grpc", + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-producer-group", + }, + Username: "user", + Password: "passwd", + }}, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cli, err := newEventMeshGRPCClient(tt.args.cfg) + if (err != nil) != tt.wantErr { + t.Errorf("newEventMeshGRPCClient() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err == nil { + assert.NoError(t, cli.Close()) + } + }) + } +} + +func Test_multiple_set_context(t *testing.T) { + root := context.Background() + onec, cancel := context.WithTimeout(root, time.Second*5) + defer cancel() + valc := context.WithValue(onec, "test", "got") + + select { + case <-valc.Done(): + val := valc.Value("test") + t.Logf("5 s reached, value in context:%v", val) + case <-time.After(time.Second * 10): + t.Logf("ooor, 10s timeout") + } + +} + +func Test_eventMeshGRPCClient_Publish(t *testing.T) { + // run fake server + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go runFakeServer(ctx) + cli, err := New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 8086, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: false, + }, + }) + assert.NoError(t, err, "create grpc client") + type args struct { + ctx context.Context + msg *proto.SimpleMessage + opts []grpc.CallOption + } + tests := []struct { + name string + args args + want *proto.Response + wantErr assert.ErrorAssertionFunc + }{ + { + name: "publish msg", + args: args{ + ctx: context.TODO(), + msg: &proto.SimpleMessage{ + Header: &proto.RequestHeader{}, + Topic: "test-publish-topic", + }, + }, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return true + }, + }, + { + name: "publish with timeout", + args: args{ + ctx: func() context.Context { + ctx, _ := context.WithTimeout(context.Background(), time.Second*10) + return ctx + }(), + msg: &proto.SimpleMessage{ + Header: &proto.RequestHeader{}, + Topic: "test-timeout-topic", + }, + }, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return true + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := cli.Publish(tt.args.ctx, tt.args.msg, tt.args.opts...) + assert.NoError(t, err) + t.Logf("receive publish response:%v", got.String()) + assert.NoError(t, cli.Close()) + }) + } +} + +func Test_eventMeshGRPCClient_RequestReply(t *testing.T) { + // run fake server + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go runFakeServer(ctx) + cli, err := New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 8086, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: false, + }, + }) + assert.NoError(t, err, "create grpc client") + type args struct { + ctx context.Context + msg *proto.SimpleMessage + opts []grpc.CallOption + } + tests := []struct { + name string + args args + want *proto.SimpleMessage + wantErr assert.ErrorAssertionFunc + }{ + { + name: "test-request-reply", + args: args{ + ctx: context.TODO(), + msg: &proto.SimpleMessage{ + Header: &proto.RequestHeader{}, + Topic: "test-request-reply-topic", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := cli.RequestReply(tt.args.ctx, tt.args.msg, tt.args.opts...) + assert.NoError(t, err) + t.Logf("receive request reply response:%v", got.String()) + assert.NoError(t, cli.Close()) + }) + } +} + +func Test_eventMeshGRPCClient_BatchPublish(t *testing.T) { + // run fake server + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go runFakeServer(ctx) + cli, err := New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 8086, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: false, + }, + }) + assert.NoError(t, err, "create grpc client") + type args struct { + ctx context.Context + msg *proto.BatchMessage + opts []grpc.CallOption + } + tests := []struct { + name string + args args + want *proto.Response + wantErr assert.ErrorAssertionFunc + }{ + { + name: "test batch publish", + args: args{ + ctx: context.TODO(), + msg: &proto.BatchMessage{ + Header: &proto.RequestHeader{}, + ProducerGroup: "fake-batch-group", + Topic: "fake-batch-topic", + MessageItem: []*proto.BatchMessage_MessageItem{ + { + Content: "batch-1", + Ttl: "1", + UniqueId: "batch-id", + SeqNum: "1", + Tag: "tag", + Properties: map[string]string{ + "from": "test", + "type": "batch-msg", + }, + }, + { + Content: "batch-2", + Ttl: "2", + UniqueId: "batch-id", + SeqNum: "2", + Tag: "tag", + Properties: map[string]string{ + "from": "test", + "type": "batch-msg", + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := cli.BatchPublish(tt.args.ctx, tt.args.msg, tt.args.opts...) + assert.NoError(t, err) + t.Logf("receive request reply response:%v", got.String()) + assert.NoError(t, cli.Close()) + }) + } +} + +func Test_eventMeshGRPCClient_webhook_subscribe(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + go runWebhookServer(ctx) + go runFakeServer(ctx) + cli, err := New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 8086, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + assert.NoError(t, err, "create grpc client") + assert.NoError(t, cli.SubscribeWebhook(conf.SubscribeItem{ + SubscribeMode: 1, + SubscribeType: 1, + Topic: "topic-1", + }, "http://localhost:8080/onmessage")) + time.Sleep(time.Second * 5) +} + +func Test_eventMeshGRPCClient_Subscribe(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go runFakeServer(ctx) + cli, err := New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 8086, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + assert.NoError(t, err, "create grpc client") + type args struct { + item conf.SubscribeItem + handler OnMessage + } + tests := []struct { + name string + args args + wantErr assert.ErrorAssertionFunc + }{ + { + name: "subcribe one", + args: args{ + item: conf.SubscribeItem{ + SubscribeMode: 1, + SubscribeType: 1, + Topic: "topic-1", + }, + handler: func(message *proto.SimpleMessage) interface{} { + t.Logf("receive subscribe response:%s", message.String()) + return nil + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := cli.SubscribeStream(tt.args.item, tt.args.handler) + assert.NoError(t, err) + assert.NoError(t, cli.Close()) + }) + } +} + +func Test_eventMeshGRPCClient_UnSubscribe(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go runFakeServer(ctx) + cli, err := New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 8086, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test-consumer-group-subscribe", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + assert.NoError(t, err, "create grpc client") + err = cli.SubscribeStream(conf.SubscribeItem{ + SubscribeMode: 1, + SubscribeType: 1, + Topic: "topic-1", + }, func(message *proto.SimpleMessage) interface{} { + t.Logf("receive subscribe response:%s", message.String()) + return nil + }) + assert.NoError(t, err, "subscribe err") + tests := []struct { + name string + wantErr assert.ErrorAssertionFunc + }{ + { + name: "unsubcribe", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.NoError(t, cli.UnSubscribe()) + assert.NoError(t, cli.Close()) + }) + } +} + +type fakeidg struct { +} + +func (f *fakeidg) Next() string { + return "fake" +} + +func Test_eventMeshGRPCClient_setupContext(t *testing.T) { + type args struct { + ctx context.Context + } + + cli := &eventMeshGRPCClient{ + idg: &fakeidg{}, + } + tests := []struct { + name string + args args + want string + }{ + { + name: "setup with uid", + args: args{ + ctx: context.WithValue(context.Background(), GRPC_ID_KEY, "value"), + }, + want: "value", + }, + { + name: "setup without uid", + args: args{ + ctx: context.TODO(), + }, + want: "fake", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := cli.setupContext(tt.args.ctx) + assert.Equal(t, ctx.Value(GRPC_ID_KEY).(string), tt.want) + }) + } +} diff --git a/eventmesh-sdk-go/grpc/conf/config.go b/eventmesh-sdk-go/grpc/conf/config.go new file mode 100644 index 0000000000..522bb2a99f --- /dev/null +++ b/eventmesh-sdk-go/grpc/conf/config.go @@ -0,0 +1,155 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package conf + +import ( + "fmt" + "time" +) + +var ( + // Language define the current sdk language + Language = "GO" + // ProtocolDesc the protocol type + ProtocolDesc = "grpc" + + // ProtocolVersion version for current sdk used + ProtocolVersion = "1.0" +) + +// GRPCConfig grpc configuration +type GRPCConfig struct { + // Hosts about the target eventmesh server + Host string `validator:"required"` + // Port port for eventmesh server + Port int `validator:"required"` + // ENV environment for client + ENV string + // Region always be the location + Region string + // IDC idc district + IDC string + // SYS system name + SYS string + // Username to access the eventmesh + Username string + // Password to access the eventmesh + Password string + // ProtocolType the type for current protocol + ProtocolType string + // ConsumerConfig if the client is listen some event + // optional + ConsumerConfig + + // ProducerConfig if the client need to send message + // you should configure it + // optional + ProducerConfig + + // HeartbeatConfig heartbeat configuration + HeartbeatConfig +} + +// LoadBalancerType type for LoadBalancer +type LoadBalancerType string + +var ( + Random LoadBalancerType = "random" + RoundRobin LoadBalancerType = "roundrobin" + IPHash LoadBalancerType = "iphash" +) + +// ProducerConfig configuration producer +type ProducerConfig struct { + // LoadBalancerType load balancer type, support random/roundrobin/iphash + LoadBalancerType LoadBalancerType + // ProducerGroup uniq consumer group for current client + ProducerGroup string +} + +// HeartbeatConfig heartbeat configuration +// required +type HeartbeatConfig struct { + // Period duration to send heartbeat + // default to 5s + Period time.Duration + // Timeout ticker in send heartbeat msg + // default to 3s + Timeout time.Duration +} + +// ConsumerConfig consumer configuration, include subscribe configurations +type ConsumerConfig struct { + // Enabled enable subscribe + Enabled bool + // ConsumerGroup uniq consumergroup for current client + ConsumerGroup string + // PoolSize goroutine pool to dispatch msg for a topic + PoolSize int + // Timeout in handle received msg + // default to 5s + Timeout time.Duration +} + +type SubscriptionMode int + +const ( + CLUSTERING SubscriptionMode = 0 + BROADCASTING SubscriptionMode = 1 +) + +type SubscriptionType int + +const ( + ASYNC = 0 + SYNC = 1 +) + +// SubscribeItem content about subscribe +type SubscribeItem struct { + // Topic uniq for eventmesh + Topic string + // SubscribeType type for subscribe, support as fellow + SubscribeType SubscriptionType + // SubscribeMode mode for subscribe, support as fellow + SubscribeMode SubscriptionMode +} + +// ValidateDefaultConf set the default configuration if user not provided +// check the conf which is required, and return not nil with parameter error +func ValidateDefaultConf(cfg *GRPCConfig) error { + if len(cfg.Host) == 0 { + return fmt.Errorf("no host provided") + } + if cfg.ConsumerConfig.Enabled { + if cfg.ConsumerConfig.ConsumerGroup == "" { + return fmt.Errorf("consumer enabled, but consumer group is empty") + } + } + if cfg.HeartbeatConfig.Timeout == 0 { + cfg.HeartbeatConfig.Timeout = time.Second * 3 + } + if cfg.HeartbeatConfig.Period == 0 { + cfg.HeartbeatConfig.Period = time.Second * 5 + } + if cfg.ConsumerConfig.PoolSize == 0 { + cfg.ConsumerConfig.PoolSize = 5 + } + if cfg.ConsumerConfig.Timeout == 0 { + cfg.ConsumerConfig.Timeout = time.Second * 5 + } + return nil +} diff --git a/eventmesh-sdk-go/grpc/conf/config_test.go b/eventmesh-sdk-go/grpc/conf/config_test.go new file mode 100644 index 0000000000..6b5b32db6d --- /dev/null +++ b/eventmesh-sdk-go/grpc/conf/config_test.go @@ -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 conf + +import "testing" + +func TestValidateDefaultConf(t *testing.T) { + type args struct { + cfg *GRPCConfig + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "test no hosts", + args: args{ + cfg: &GRPCConfig{}, + }, + wantErr: true, + }, + { + name: "test default duration", + args: args{ + cfg: &GRPCConfig{ + Host: "1", + }, + }, + wantErr: false, + }, + { + name: "test consumer enable, but no group", + args: args{ + cfg: &GRPCConfig{ + Host: "1", + ConsumerConfig: ConsumerConfig{ + Enabled: true, + }, + }, + }, + wantErr: true, + }, + { + name: "test consumer enable, but no group", + args: args{ + cfg: &GRPCConfig{ + Host: "1", + ConsumerConfig: ConsumerConfig{ + Enabled: true, + ConsumerGroup: "test", + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ValidateDefaultConf(tt.args.cfg); (err != nil) != tt.wantErr { + t.Errorf("ValidateDefaultConf() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/eventmesh-sdk-go/grpc/consts.go b/eventmesh-sdk-go/grpc/consts.go new file mode 100644 index 0000000000..e487dd8c1b --- /dev/null +++ b/eventmesh-sdk-go/grpc/consts.go @@ -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 grpc + +// Success grpc code success +var Success = "0" + +// GRPC_ID_KEY key to indicate the uniq id +var GRPC_ID_KEY = "GRPC_ID_KEY" + +// EVENTMESH_MESSAGE_CONST_TTL msg ttl store in the properties +var EVENTMESH_MESSAGE_CONST_TTL = "ttl" diff --git a/eventmesh-sdk-go/grpc/consumer.go b/eventmesh-sdk-go/grpc/consumer.go new file mode 100644 index 0000000000..26d271a0b6 --- /dev/null +++ b/eventmesh-sdk-go/grpc/consumer.go @@ -0,0 +1,293 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/id" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/seq" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + jsoniter "github.com/json-iterator/go" + "google.golang.org/grpc" + "io" + "reflect" + "sync" + "time" +) + +var ( + // ErrSubscribeResponse subscribe response code not ok + ErrSubscribeResponse = fmt.Errorf("subscribe response code err") + // ErrUnSupportResponse only support reflect.String, reflect.Struct, reflect.Ptr, reflect.Map + ErrUnSupportResponse = fmt.Errorf("un support response msg type") + + // defaultTTL default msg ttl + defaultTTL = time.Second * 4 +) + +// eventMeshConsumer consumer to implements the ConsumerService +type eventMeshConsumer struct { + // client subscribe api client + client proto.ConsumerServiceClient + // topics subscribe topics + // map[string]*proto.Subscription_SubscriptionItem + topics *sync.Map + // cfg configuration + cfg *conf.GRPCConfig + // dispatcher for topic + dispatcher *messageDispatcher + // heartbeat used to keepalive with eventmesh + heartbeat *eventMeshHeartbeat + // closeCtx close context + closeCtx context.Context + // streamSubscribeChan chan to receive the subscribe request with stream type + streamSubscribeChan chan *proto.Subscription + // idg generate uniq id + idg id.Interface + // seqg generate sequenced id + seqg seq.Interface +} + +// newConsumer create new consumer +func newConsumer(ctx context.Context, cfg *conf.GRPCConfig, grpcConn *grpc.ClientConn, idg id.Interface, seqg seq.Interface) (*eventMeshConsumer, error) { + cli := proto.NewConsumerServiceClient(grpcConn) + heartbeat, err := newHeartbeat(ctx, cfg, grpcConn) + if err != nil { + log.Warnf("failed to create producer, err:%v", err) + return nil, err + } + return &eventMeshConsumer{ + client: cli, + closeCtx: ctx, + topics: new(sync.Map), + cfg: cfg, + heartbeat: heartbeat, + dispatcher: newMessageDispatcher(cfg.ConsumerConfig.PoolSize, cfg.ConsumerConfig.Timeout), + streamSubscribeChan: make(chan *proto.Subscription, 1024), + idg: idg, + seqg: seqg, + }, nil +} + +// startConsumerStream run stream goroutine to receive the msg send by stream not webhook +func (d *eventMeshConsumer) startConsumerStream() error { + stream, err := d.client.SubscribeStream(d.closeCtx) + if err != nil { + log.Warnf("failed to get subscribe stream, err:%v", err) + return err + } + go func() { + ss := stream + for { + select { + case <-d.closeCtx.Done(): + log.Infof("close consumer subscribe goroutine") + case sub, ok := <-d.streamSubscribeChan: + if ok { + if err := ss.Send(sub); err != nil { + log.Warnf("send subscribe stream msg err:%v", err) + } + } + } + } + }() + go func() { + ss := stream + log.Infof("start receive msg stream") + for { + msg, err := ss.Recv() + if err == io.EOF { + log.Infof("receive msg got io.EOF exit stream") + break + } + if err != nil { + log.Warnf("receive msg got err:%v, need to return", err) + return + } + reply, err := d.dispatcher.onMessage(msg) + if err != nil { + log.Warnf("dispatch msg got err:%v, msgID:%s", err, msg.UniqueId) + continue + } + + if reply == nil { + continue + } + // for async message, do not need to reply it + if !d.needToReply(msg.Topic) { + continue + } + if err := d.replyMsg(msg, reply); err != nil { + log.Warnf("reply msg err:%v, msgID:%s", err, msg.UniqueId) + continue + } + } + log.Infof("close receive stream") + }() + + return nil +} + +func (d *eventMeshConsumer) replyMsg(msg *proto.SimpleMessage, reply interface{}) error { + replyContent := "" + typ := reflect.TypeOf(reply) + switch typ.Kind() { + case reflect.String: + replyContent = reply.(string) + case reflect.Ptr, reflect.Struct, reflect.Map: + jv, err := jsoniter.MarshalToString(reply) + if err != nil { + log.Warnf("failed to unmarshal the response for kind:%v, err:%v, msgID:%s", typ.Kind(), err, msg.UniqueId) + return err + } + replyContent = jv + default: + log.Warnf("un support response msg type:%v", typ.Kind()) + return ErrUnSupportResponse + } + ttl := GetTTLWithDefault(msg, defaultTTL) + d.streamSubscribeChan <- &proto.Subscription{ + Header: msg.Header, + ConsumerGroup: d.cfg.ConsumerGroup, + Reply: &proto.Subscription_Reply{ + ProducerGroup: d.cfg.ConsumerGroup, + Topic: msg.Topic, + Content: replyContent, + Ttl: fmt.Sprintf("%v", ttl.Seconds()), + UniqueId: d.idg.Next(), + SeqNum: d.seqg.Next(), + Tag: msg.Tag, + Properties: msg.Properties, + }, + } + + return nil +} + +// Subscribe topic for webhook +func (d *eventMeshConsumer) Subscribe(item conf.SubscribeItem, callbackURL string) error { + log.Infof("subscribe with webhook topic:%v, url:%s", item, callbackURL) + if callbackURL == "" { + return fmt.Errorf("webhook subscribe err, url is empty") + } + subItem := &proto.Subscription_SubscriptionItem{ + Topic: item.Topic, + Mode: proto.Subscription_SubscriptionItem_SubscriptionMode(item.SubscribeMode), + Type: proto.Subscription_SubscriptionItem_SubscriptionType(item.SubscribeType), + } + subMsg := &proto.Subscription{ + Header: CreateHeader(d.cfg), + ConsumerGroup: d.cfg.ConsumerGroup, + SubscriptionItems: []*proto.Subscription_SubscriptionItem{subItem}, + Url: callbackURL, + } + resp, err := d.client.Subscribe(context.TODO(), subMsg) + if err != nil { + log.Warnf("failed to subscribe topic:%v, err :%v", subItem, err) + return err + } + if resp.RespCode != Success { + log.Warnf("failed to subscribe resp:%v", resp.String()) + return ErrSubscribeResponse + } + d.topics.Store(item.Topic, subItem) + d.heartbeat.addHeartbeat(subItem) + log.Infof("success subscribe with topic:%s, resp:%s", item.Topic, resp.String()) + return nil +} + +// UnSubscribe unsubscribe topic with all eventmesh server +func (d *eventMeshConsumer) UnSubscribe() error { + log.Infof("unsubscribe topics") + resp, err := d.client.Unsubscribe(context.TODO(), &proto.Subscription{ + Header: CreateHeader(d.cfg), + ConsumerGroup: d.cfg.ConsumerGroup, + SubscriptionItems: func() []*proto.Subscription_SubscriptionItem { + var sitems []*proto.Subscription_SubscriptionItem + d.topics.Range(func(key, value interface{}) bool { + sitems = append(sitems, value.(*proto.Subscription_SubscriptionItem)) + return true + }) + return sitems + }(), + }) + if err != nil { + log.Warnf("failed to subscribe topic:%v, err :%v", d.topics, err) + return err + } + log.Infof("success unsubscribe with resp:%s", resp.String()) + + return nil +} + +// SubscribeWithStream subscribe stream, dispatch the message for all topic +func (d *eventMeshConsumer) SubscribeWithStream(item conf.SubscribeItem, handler OnMessage) error { + log.Infof("subscribe stream topic:%v", item) + subItem := &proto.Subscription_SubscriptionItem{ + Topic: item.Topic, + Mode: proto.Subscription_SubscriptionItem_SubscriptionMode(item.SubscribeMode), + Type: proto.Subscription_SubscriptionItem_SubscriptionType(item.SubscribeType), + } + if err := d.addSubscribeHandler(item, handler); err != nil { + return err + } + d.streamSubscribeChan <- &proto.Subscription{ + Header: CreateHeader(d.cfg), + ConsumerGroup: d.cfg.ConsumerGroup, + SubscriptionItems: []*proto.Subscription_SubscriptionItem{subItem}, + } + + log.Infof("success subscribe stream with topic:%s", item.Topic) + return nil +} + +func (d *eventMeshConsumer) addSubscribeHandler(item conf.SubscribeItem, handler OnMessage) error { + subItem := &proto.Subscription_SubscriptionItem{ + Topic: item.Topic, + Mode: proto.Subscription_SubscriptionItem_SubscriptionMode(item.SubscribeMode), + Type: proto.Subscription_SubscriptionItem_SubscriptionType(item.SubscribeType), + } + if err := d.dispatcher.addHandler(item.Topic, handler); err != nil { + log.Warnf("failed to add handler for topic:%s", item.Topic) + return err + } + d.topics.Store(item.Topic, subItem) + d.heartbeat.addHeartbeat(subItem) + return nil +} + +func (d *eventMeshConsumer) close() error { + if d.heartbeat != nil { + if err := d.heartbeat.close(); err != nil { + log.Warnf("failed to close heartbeat:%v", err) + } + d.heartbeat = nil + } + return nil +} + +// needToReply check the message need to reply, only works on RequestReply +func (d *eventMeshConsumer) needToReply(topic string) bool { + val, ok := d.topics.Load(topic) + if !ok { + return false + } + subType := val.(*proto.Subscription_SubscriptionItem) + return subType.Type == proto.Subscription_SubscriptionItem_SYNC +} diff --git a/eventmesh-sdk-go/grpc/dispatcher.go b/eventmesh-sdk-go/grpc/dispatcher.go new file mode 100644 index 0000000000..cb1017bb10 --- /dev/null +++ b/eventmesh-sdk-go/grpc/dispatcher.go @@ -0,0 +1,120 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "sync" + "time" + + "github.com/panjf2000/ants" +) + +var ( + // ErrTopicDispatcherExist repeated dispatcher for topic + ErrTopicDispatcherExist = fmt.Errorf("already exist dispatcher for given topic") +) + +// pooledHandler internal handler for subscribe message with goroutine pool +type pooledHandler struct { + *ants.Pool + handler OnMessage + timeout time.Duration +} + +// OnMessage redirect the msg with pool +func (p *pooledHandler) OnMessage(msg *proto.SimpleMessage) interface{} { + ch := make(chan interface{}) + if err := p.Submit(func() { + m := *msg + ch <- p.handler(&m) + }); err != nil { + log.Warnf("submit msg to pool err:%v, msgID:%v", err, msg.UniqueId) + return err + } + select { + case <-time.After(p.timeout): + log.Warnf("timeout in wait the response, msgID:%v", msg.UniqueId) + break + case val, ok := <-ch: + if !ok { + log.Warnf("wait response, msg chan closed, msgID:%v", msg.UniqueId) + } else { + if val != nil { + log.Infof("reply for msg:%v", msg.UniqueId) + return val + } + } + } + return nil +} + +// messageDispatcher dispatch the message to different handler according to +// it's topic +type messageDispatcher struct { + // topicMap key is the topic name, value is the SubscribeMessageHandler + topicMap *sync.Map + // poolSize concurrent for dispatch received msg + poolsize int + // timeout to process on message + timeout time.Duration +} + +// newMessageDispatcher create new message dispatcher +func newMessageDispatcher(ps int, tm time.Duration) *messageDispatcher { + return &messageDispatcher{ + topicMap: new(sync.Map), + poolsize: ps, + timeout: tm, + } +} + +// addHandler add msg handler +func (m *messageDispatcher) addHandler(topic string, hdl OnMessage) error { + _, ok := m.topicMap.Load(topic) + if ok { + return ErrTopicDispatcherExist + } + pool, err := ants.NewPool(m.poolsize, ants.WithPanicHandler(func(i interface{}) { + log.Warnf("process message failure, err:%v", i) + })) + if err != nil { + return err + } + m.topicMap.Store(topic, &pooledHandler{ + Pool: pool, + handler: hdl, + timeout: m.timeout, + }) + return nil +} + +// OnMessage dispatch the message by topic +func (m *messageDispatcher) onMessage(msg *proto.SimpleMessage) (interface{}, error) { + // subscribe response ignore it + if msg.Topic == "" { + return nil, nil + } + val, ok := m.topicMap.Load(msg.Topic) + if !ok { + log.Warnf("no dispatch found for topic:%s, drop msg", msg.Topic) + return nil, ErrTopicDispatcherExist + } + ph := val.(*pooledHandler) + return ph.OnMessage(msg), nil +} diff --git a/eventmesh-sdk-go/grpc/dispatcher_test.go b/eventmesh-sdk-go/grpc/dispatcher_test.go new file mode 100644 index 0000000000..49392057fb --- /dev/null +++ b/eventmesh-sdk-go/grpc/dispatcher_test.go @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/stretchr/testify/assert" + "sync" + "testing" +) + +func Test_messageDispatcher_addHandler(t *testing.T) { + type fields struct { + topicMap *sync.Map + poolsize int + } + type args struct { + topic string + hdl OnMessage + } + tests := []struct { + name string + fields fields + args args + wantErr assert.ErrorAssertionFunc + }{ + { + name: "test add handler", + fields: fields{ + topicMap: new(sync.Map), + poolsize: 5, + }, + args: args{ + topic: "handler-1", + hdl: func(message *proto.SimpleMessage) interface{} { + t.Logf("handle message") + return nil + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &messageDispatcher{ + topicMap: tt.fields.topicMap, + poolsize: tt.fields.poolsize, + } + tt.wantErr(t, m.addHandler(tt.args.topic, tt.args.hdl), fmt.Sprintf("addHandler(%v, %v)", tt.args.topic, tt.args.hdl)) + }) + } +} diff --git a/eventmesh-sdk-go/grpc/fake_grpcserver.go b/eventmesh-sdk-go/grpc/fake_grpcserver.go new file mode 100644 index 0000000000..077e214af3 --- /dev/null +++ b/eventmesh-sdk-go/grpc/fake_grpcserver.go @@ -0,0 +1,208 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/seq" + "io" + "io/ioutil" + "net" + "net/http" + "strings" + "sync" + "time" + + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/id" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + + "google.golang.org/grpc" +) + +// fakeServer used to do the test +type fakeServer struct { + proto.UnsafeConsumerServiceServer + proto.UnimplementedPublisherServiceServer + proto.UnimplementedHeartbeatServiceServer + idg id.Interface + seq seq.Interface + closeCtx context.Context +} + +// newFakeServer create new fake grpc server for eventmesh +func runFakeServer(ctx context.Context) error { + lis, err := net.Listen("tcp", ":8086") + if err != nil { + return err + } + f := &fakeServer{ + idg: id.NewUUID(), + seq: seq.NewAtomicSeq(), + closeCtx: ctx, + } + srv := grpc.NewServer() + proto.RegisterConsumerServiceServer(srv, f) + proto.RegisterHeartbeatServiceServer(srv, f) + proto.RegisterPublisherServiceServer(srv, f) + go func() { + select { + case <-ctx.Done(): + srv.GracefulStop() + } + }() + log.Infof("serve fake server on:%v", srv.GetServiceInfo()) + if err := srv.Serve(lis); err != nil { + log.Warnf("create fake server err:%v", err) + return err + } + log.Infof("stop fake server") + return nil +} + +// Subscribe The subscribed event will be delivered by invoking the webhook url in the Subscription +func (f *fakeServer) Subscribe(ctx context.Context, msg *proto.Subscription) (*proto.Response, error) { + log.Infof("fake-server, receive subcribe request:%v", msg.String()) + go func() { + // send a fake msg by webhook + resp, err := http.Post(msg.Url, "Content-Type:application/json", strings.NewReader("msg from webhook")) + if err != nil { + log.Errorf("err in create http webhook url:%s, err:%v", msg.Url, err) + return + } + buf, _ := ioutil.ReadAll(resp.Body) + log.Infof("send webhook msg success", string(buf)) + }() + return &proto.Response{ + RespCode: "0", + RespMsg: "OK", + RespTime: time.Now().Format("2006-01-02 15:04:05"), + }, nil +} + +// SubscribeStream The subscribed event will be delivered through stream of Message +func (f *fakeServer) SubscribeStream(srv proto.ConsumerService_SubscribeStreamServer) error { + wg := new(sync.WaitGroup) + wg.Add(2) + go func() { + defer wg.Done() + for { + sub, err := srv.Recv() + if err == io.EOF { + log.Infof("return sub as rece io.EOF") + break + } + if err != nil { + log.Warnf("return sub as rece err:%v", err) + break + } + log.Infof("rece sub:%s", sub.String()) + } + }() + go func() { + defer wg.Done() + var index int = 0 + for { + msg := &proto.SimpleMessage{ + Header: &proto.RequestHeader{}, + ProducerGroup: "substream-fake-group", + Topic: "fake-topic", + Content: fmt.Sprintf("%v msg from fake server", index), + Ttl: fmt.Sprintf("%v", time.Hour.Seconds()*24), + UniqueId: f.idg.Next(), + SeqNum: f.seq.Next(), + Tag: "substream-fake-tag", + Properties: map[string]string{ + "from": "fake", + "service": "substream", + }, + } + err := srv.Send(msg) + if err == io.EOF { + log.Infof("return send as rece io.EOF") + break + } + if err != nil { + log.Warnf("return send as rece err:%v", err) + break + } + log.Infof("send msg:%s", msg.String()) + index++ + time.Sleep(time.Second * 5) + } + }() + wg.Wait() + log.Infof("close SubscribeStream") + return nil +} + +func (f *fakeServer) Unsubscribe(ctx context.Context, msg *proto.Subscription) (*proto.Response, error) { + log.Infof("fake-server, receive unsubcribe request:%v", msg.String()) + return &proto.Response{ + RespCode: "OK", + RespMsg: "OK", + RespTime: time.Now().Format("2006-01-02 15:04:05"), + }, nil +} + +func (f *fakeServer) Heartbeat(ctx context.Context, msg *proto.Heartbeat) (*proto.Response, error) { + log.Infof("fake-server, receive heartbeat request:%v", msg.String()) + return &proto.Response{ + RespCode: "OK", + RespMsg: "OK", + RespTime: time.Now().Format("2006-01-02 15:04:05"), + }, nil +} + +// Publish Async event publish +func (f *fakeServer) Publish(ctx context.Context, msg *proto.SimpleMessage) (*proto.Response, error) { + log.Infof("fake-server, receive publish request:%v", msg.String()) + return &proto.Response{ + RespCode: "OK", + RespMsg: "OK", + RespTime: time.Now().Format("2006-01-02 15:04:05"), + }, nil +} + +// RequestReply Sync event publish +func (f *fakeServer) RequestReply(ctx context.Context, rece *proto.SimpleMessage) (*proto.SimpleMessage, error) { + log.Infof("receive request reply topic:%s, content:%s", rece.Topic, rece.Content) + return &proto.SimpleMessage{ + Header: rece.Header, + ProducerGroup: "fake-mock-group", + Topic: rece.Topic, + Content: "fake response for request reply" + rece.Content, + Ttl: fmt.Sprintf("%v", time.Hour.Seconds()*24), + UniqueId: f.idg.Next(), + SeqNum: f.seq.Next(), + Tag: "fake-tag", + Properties: map[string]string{ + "from": "fake", + "service": "RequestReply", + }, + }, nil +} + +// BatchPublish Async batch event publish +func (f *fakeServer) BatchPublish(ctx context.Context, rece *proto.BatchMessage) (*proto.Response, error) { + log.Infof("receive batch publish topic:%s, content len:%s", rece.Topic, len(rece.MessageItem)) + return &proto.Response{ + RespCode: "OK", + RespMsg: "Response for batchpublish", + RespTime: time.Now().Format("2006-01-02 15:04:05"), + }, nil +} diff --git a/eventmesh-sdk-go/grpc/fake_webhookserver.go b/eventmesh-sdk-go/grpc/fake_webhookserver.go new file mode 100644 index 0000000000..46ed6a0971 --- /dev/null +++ b/eventmesh-sdk-go/grpc/fake_webhookserver.go @@ -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 grpc + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" +) + +// runWebhookServer start a webhook server for fake server on +// subscribe topic with webhook +// need to call srv.Shutdown() to close the http.Server gracefully +func runWebhookServer(ctx context.Context) { + mux := http.NewServeMux() + mux.HandleFunc("/onmessage", func(writer http.ResponseWriter, request *http.Request) { + buf, err := ioutil.ReadAll(request.Body) + if err != nil { + fmt.Printf("read webhook msg from body, err:%v", err) + writer.WriteHeader(http.StatusOK) + writer.Write([]byte("read body err")) + return + } + fmt.Printf("got webhook msg:%s\n", string(buf)) + writer.WriteHeader(http.StatusOK) + writer.Write([]byte("OK")) + }) + srv := &http.Server{ + Addr: ":8080", + Handler: mux, + } + go func() { + if err := srv.ListenAndServe(); err != nil { + return + } + fmt.Println("http server shutdown") + }() + + select { + case <-ctx.Done(): + srv.Shutdown(context.TODO()) + } +} diff --git a/eventmesh-sdk-go/grpc/heartbeat.go b/eventmesh-sdk-go/grpc/heartbeat.go new file mode 100644 index 0000000000..105b1656e6 --- /dev/null +++ b/eventmesh-sdk-go/grpc/heartbeat.go @@ -0,0 +1,136 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "google.golang.org/grpc" + "sync" + "time" +) + +var ( + // ErrHeartbeatResp err in sent heartbeat msg to mesh server, response not success + ErrHeartbeatResp = fmt.Errorf("heartbeat response err") +) + +// eventMeshHeartbeat heartbeat to keep the client conn +type eventMeshHeartbeat struct { + // clientsMap hold all grp client to send heartbeat msg + client proto.HeartbeatServiceClient + // cfg the configuration for grpc client + cfg *conf.GRPCConfig + // closeCtx close context + closeCtx context.Context + // subscribeItems subscribe items, heartbeat for these topic + subscribeItems []*proto.Subscription_SubscriptionItem + // subscribeItemsLock lock for subscribeItems + subscribeItemsLock *sync.RWMutex +} + +// newHeartbeat create heartbeat service, and start a goroutine +// with all eventmesh server +func newHeartbeat(ctx context.Context, cfg *conf.GRPCConfig, grpcConn *grpc.ClientConn) (*eventMeshHeartbeat, error) { + cli := proto.NewHeartbeatServiceClient(grpcConn) + heartbeat := &eventMeshHeartbeat{ + client: cli, + cfg: cfg, + closeCtx: ctx, + subscribeItemsLock: new(sync.RWMutex), + } + go heartbeat.run() + return heartbeat, nil +} + +// run the ticker to send heartbeat msg +func (e *eventMeshHeartbeat) run() { + log.Infof("start heartbeat goroutine") + tick := time.NewTicker(e.cfg.Period) + for { + select { + case <-tick.C: + go e.sendMsg(e.client) + case <-e.closeCtx.Done(): + log.Infof("exit heartbeat goroutine as closed") + return + } + } +} + +// sendMsg send heartbeat msg to eventmesh server +func (e *eventMeshHeartbeat) sendMsg(cli proto.HeartbeatServiceClient) error { + log.Debugf("send heartbeat msg to server:%s") + cancelCtx, cancel := context.WithTimeout(e.closeCtx, e.cfg.HeartbeatConfig.Timeout) + defer cancel() + e.subscribeItemsLock.RLock() + defer e.subscribeItemsLock.RUnlock() + msg := &proto.Heartbeat{ + Header: CreateHeader(e.cfg), + ClientType: proto.Heartbeat_SUB, + ConsumerGroup: e.cfg.ConsumerGroup, + HeartbeatItems: func() []*proto.Heartbeat_HeartbeatItem { + var items []*proto.Heartbeat_HeartbeatItem + for _, tp := range e.subscribeItems { + items = append(items, &proto.Heartbeat_HeartbeatItem{ + Topic: tp.Topic, + }) + } + return items + }(), + } + resp, err := cli.Heartbeat(cancelCtx, msg) + if err != nil { + log.Warnf("failed to send heartbeat msg, err:%v", err) + return err + } + if resp.RespCode != Success { + log.Warnf("heartbeat msg return err, resp:%s", resp.String()) + return ErrHeartbeatResp + } + log.Debugf("success send heartbeat to server resp:%s", resp.String()) + return nil +} + +// addHeartbeat add heartbeat for topic +func (e *eventMeshHeartbeat) addHeartbeat(item *proto.Subscription_SubscriptionItem) { + e.subscribeItemsLock.Lock() + defer e.subscribeItemsLock.Unlock() + e.subscribeItems = append(e.subscribeItems, item) +} + +// removeHeartbeat remove heartbeat for topic +func (e *eventMeshHeartbeat) removeHeartbeat(item *proto.Subscription_SubscriptionItem) { + e.subscribeItemsLock.Lock() + defer e.subscribeItemsLock.Unlock() + var newSubscribeItems []*proto.Subscription_SubscriptionItem + for _, it := range e.subscribeItems { + if it.Topic == item.Topic { + continue + } + newSubscribeItems = append(newSubscribeItems, it) + } + e.subscribeItems = newSubscribeItems +} + +// close free the heartbeat resources +func (e *eventMeshHeartbeat) close() error { + log.Infof("close heartbeat") + return nil +} diff --git a/eventmesh-sdk-go/grpc/heartbeat_test.go b/eventmesh-sdk-go/grpc/heartbeat_test.go new file mode 100644 index 0000000000..45f6ed1610 --- /dev/null +++ b/eventmesh-sdk-go/grpc/heartbeat_test.go @@ -0,0 +1,76 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func Test_eventMeshHeartbeat_sendMsg(t *testing.T) { + // run fake server + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go runFakeServer(ctx) + cli, err := New(&conf.GRPCConfig{ + Host: "127.0.0.1", + Port: 8086, + ProducerConfig: conf.ProducerConfig{ + ProducerGroup: "test-publish-group", + LoadBalancerType: conf.Random, + }, + ConsumerConfig: conf.ConsumerConfig{ + Enabled: true, + ConsumerGroup: "fake-consumer", + PoolSize: 5, + }, + HeartbeatConfig: conf.HeartbeatConfig{ + Period: time.Second * 5, + Timeout: time.Second * 3, + }, + }) + topic := "fake-topic" + assert.NoError(t, cli.SubscribeStream(conf.SubscribeItem{ + SubscribeType: 1, + SubscribeMode: 1, + Topic: topic, + }, func(message *proto.SimpleMessage) interface{} { + t.Logf("receive sub msg:%v", message.String()) + return nil + })) + rcli := cli.(*eventMeshGRPCClient) + beat := rcli.heartbeat + assert.NoError(t, err, "create grpc client") + defer assert.NoError(t, cli.Close()) + tests := []struct { + name string + want error + }{ + { + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := beat.sendMsg(beat.client) + assert.NoError(t, err) + }) + } +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/README.md b/eventmesh-sdk-go/grpc/loadbalancer/README.md new file mode 100644 index 0000000000..7f1cbca01d --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/README.md @@ -0,0 +1,10 @@ +loadbalancer +=== +provide loadbalancer algorithms for multiple eventmesh grpc server + +support: +1. random, peek one grpc server randomly +2. roundrobin, peek one grpc server with roundrobin, no weight +3. iphash, peek one grpc server with iphash, need to provide the client on choose API + +https://github.com/lafikl/liblb/blob \ No newline at end of file diff --git a/eventmesh-sdk-go/grpc/loadbalancer/loadbalancer.go b/eventmesh-sdk-go/grpc/loadbalancer/loadbalancer.go new file mode 100644 index 0000000000..890162a5e1 --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/loadbalancer.go @@ -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 loadbalancer + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "go.uber.org/atomic" + "sync" +) + +// LoadBalancer interface to process all grpc client +type LoadBalancer interface { + // GetAllStatusServer return all status server in the lb + GetAllStatusServer() []*StatusServer + + // GetAvailableServer available servers which is ready for service + GetAvailableServer() []*StatusServer + + // AddServer add servers to LoadBalancer + AddServer([]*StatusServer) + + // Choose peek client with rule inside + Choose(input interface{}) (interface{}, error) +} + +// BaseLoadBalancer loadbalancer instance +type BaseLoadBalancer struct { + servers []*StatusServer + lock *sync.RWMutex + rule Rule +} + +// NewLoadBalancer create new loadbalancer with lb type and servers +func NewLoadBalancer(lbType conf.LoadBalancerType, srvs []*StatusServer) (LoadBalancer, error) { + lb := &BaseLoadBalancer{ + servers: srvs, + lock: new(sync.RWMutex), + } + switch lbType { + case conf.IPHash: + lb.rule = &IPHashRule{BaseRule{ + lb: lb, + }} + case conf.Random: + lb.rule = &RandomRule{BaseRule{ + lb: lb, + }} + case conf.RoundRobin: + lb.rule = &RoundRobinRule{ + cycleCounter: atomic.NewInt64(-1), + BaseRule: BaseRule{lb: lb}, + } + default: + return nil, fmt.Errorf("invalid load balancer rule:%v", lbType) + } + + return lb, nil +} + +// AddServer add servers to the lb +func (b *BaseLoadBalancer) AddServer(srvs []*StatusServer) { + b.lock.Lock() + defer b.lock.Unlock() + b.servers = append(b.servers, srvs...) +} + +// Choose choose server in current lb +func (b *BaseLoadBalancer) Choose(input interface{}) (interface{}, error) { + return b.rule.Choose(input) +} + +func (b *BaseLoadBalancer) GetAllStatusServer() []*StatusServer { + b.lock.RLock() + defer b.lock.RUnlock() + return b.servers +} + +func (b *BaseLoadBalancer) GetAvailableServer() []*StatusServer { + b.lock.RLock() + defer b.lock.RUnlock() + var asrvs []*StatusServer + for _, r := range b.servers { + if r.ReadyForService { + asrvs = append(asrvs, r) + } + } + return asrvs +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/loadbalancer_test.go b/eventmesh-sdk-go/grpc/loadbalancer/loadbalancer_test.go new file mode 100644 index 0000000000..b3eb916230 --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/loadbalancer_test.go @@ -0,0 +1,202 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadbalancer + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/stretchr/testify/assert" + "sync" + "testing" +) + +func TestNewLoadBalancer(t *testing.T) { + type args struct { + lbType conf.LoadBalancerType + srvs []*StatusServer + } + tests := []struct { + name string + args args + want LoadBalancer + wantErr bool + }{ + { + name: "lb with random", + args: args{ + srvs: []*StatusServer{}, + lbType: conf.Random, + }, + want: nil, + wantErr: false, + }, + { + name: "lb with roundrobin", + args: args{ + srvs: []*StatusServer{}, + lbType: conf.RoundRobin, + }, + want: nil, + wantErr: false, + }, + { + name: "lb with iphash", + args: args{ + srvs: []*StatusServer{}, + lbType: conf.IPHash, + }, + want: nil, + wantErr: false, + }, + { + name: "lb without type", + args: args{ + srvs: []*StatusServer{}, + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := NewLoadBalancer(tt.args.lbType, tt.args.srvs) + if (err != nil) != tt.wantErr { + t.Errorf("NewLoadBalancer() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} + +func TestBaseLoadBalancer_AddServer(t *testing.T) { + type fields struct { + servers []*StatusServer + lock *sync.RWMutex + rule Rule + } + type args struct { + srvs []*StatusServer + } + tests := []struct { + name string + fields fields + args args + }{ + { + name: "add srv", + fields: fields{ + servers: []*StatusServer{}, + lock: new(sync.RWMutex), + rule: &RoundRobinRule{}, + }, + args: args{ + srvs: []*StatusServer{{ + RealServer: "", + Host: "127.1.1.1", + ReadyForService: false, + }}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := &BaseLoadBalancer{ + servers: tt.fields.servers, + lock: tt.fields.lock, + rule: tt.fields.rule, + } + b.AddServer(tt.args.srvs) + assert.Equal(t, len(tt.args.srvs), len(b.GetAllStatusServer())) + }) + } +} + +func TestBaseLoadBalancer_GetAllStatusServer(t *testing.T) { + type fields struct { + servers []*StatusServer + lock *sync.RWMutex + rule Rule + } + tests := []struct { + name string + fields fields + want int + }{ + { + name: "", + fields: fields{ + servers: []*StatusServer{{ + RealServer: "1", + ReadyForService: true, + Host: "127.0.0.1", + }}, + lock: new(sync.RWMutex), + rule: &RoundRobinRule{}, + }, + want: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := &BaseLoadBalancer{ + servers: tt.fields.servers, + lock: tt.fields.lock, + rule: tt.fields.rule, + } + assert.Equalf(t, tt.want, len(b.GetAllStatusServer()), "GetAllStatusServer()") + }) + } +} + +func TestBaseLoadBalancer_GetAvailableServer(t *testing.T) { + type fields struct { + servers []*StatusServer + lock *sync.RWMutex + rule Rule + } + tests := []struct { + name string + fields fields + want int + }{ + { + name: "1 ok", + fields: fields{ + servers: []*StatusServer{{ + RealServer: "1", + ReadyForService: true, + Host: "127.0.0.1", + }, { + RealServer: "2", + ReadyForService: false, + Host: "127.0.0.2", + }}, + lock: new(sync.RWMutex), + rule: &RoundRobinRule{}, + }, + want: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := &BaseLoadBalancer{ + servers: tt.fields.servers, + lock: tt.fields.lock, + rule: tt.fields.rule, + } + assert.Equalf(t, tt.want, len(b.GetAvailableServer()), "GetAvailableServer()") + }) + } +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/rule.go b/eventmesh-sdk-go/grpc/loadbalancer/rule.go new file mode 100644 index 0000000000..3748f29983 --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/rule.go @@ -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 loadbalancer + +import "fmt" + +var ( + ErrNoServerFound = fmt.Errorf("no server found") + ErrInvalidInput = fmt.Errorf("invalidate input") +) + +// Rule for loadbalancer algorithms +type Rule interface { + // Choose return the instance by rule + Choose(interface{}) (interface{}, error) +} + +// BaseRule base rule for all implements, holds the lb to +// fetch the latest server lists +type BaseRule struct { + lb LoadBalancer +} + +// SetLoadBalancer set the lb for current rule +func (b *BaseRule) SetLoadBalancer(balancer LoadBalancer) { + b.lb = balancer +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/rule_iphash.go b/eventmesh-sdk-go/grpc/loadbalancer/rule_iphash.go new file mode 100644 index 0000000000..dfde0e735f --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/rule_iphash.go @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadbalancer + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "github.com/cespare/xxhash" + "reflect" + "unsafe" +) + +// IPHashRule iphash rule +type IPHashRule struct { + BaseRule +} + +// Choose return the instance by ip hash +// the input must be ip +func (i *IPHashRule) Choose(ip interface{}) (interface{}, error) { + host, ok := ip.(string) + if !ok { + log.Warnf("provide host not a string type:%s", reflect.TypeOf(ip).String()) + return nil, ErrInvalidInput + } + srvs := i.lb.GetAvailableServer() + if len(srvs) == 0 { + log.Warnf("no available server found, load all server instead") + srvs = i.lb.GetAllStatusServer() + } + count := len(srvs) + hashN := xxhash.Sum64(*(*[]byte)(unsafe.Pointer(&host))) % uint64(count) + srv := srvs[hashN] + log.Debugf("success peek host:%s by iphash, input:%v", srv.Host, ip) + return srv, nil +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/rule_iphash_test.go b/eventmesh-sdk-go/grpc/loadbalancer/rule_iphash_test.go new file mode 100644 index 0000000000..7375c78f3e --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/rule_iphash_test.go @@ -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 loadbalancer + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestIPHashRule_Choose(t *testing.T) { + type fields struct { + BaseRule BaseRule + } + type args struct { + ip interface{} + } + fled := fields{ + BaseRule: func() BaseRule { + lb, _ := NewLoadBalancer(conf.IPHash, []*StatusServer{ + { + RealServer: "127.0.0.1", + ReadyForService: true, + Host: "127.0.0.1", + }, + { + RealServer: "127.0.0.2", + ReadyForService: true, + Host: "127.0.0.2", + }, + { + RealServer: "127.0.0.3", + ReadyForService: true, + Host: "127.0.0.3", + }, + }) + return BaseRule{ + lb: lb, + } + }(), + } + tests := []struct { + name string + fields fields + args args + want interface{} + wantErr assert.ErrorAssertionFunc + }{ + { + name: "iphash with 1", + fields: fled, + args: args{ + ip: "127.1.1.1", + }, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return false + }, + want: "127.0.0.1", + }, + { + name: "iphash with 2", + fields: fled, + args: args{ + ip: "168.1.1.2", + }, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return true + }, + want: "127.0.0.2", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i := &IPHashRule{ + BaseRule: tt.fields.BaseRule, + } + got, err := i.Choose(tt.args.ip) + if !tt.wantErr(t, err, fmt.Sprintf("Choose(%v)", tt.args.ip)) { + return + } + assert.Equalf(t, tt.want, got.(*StatusServer).Host, "Choose(%v)", tt.args.ip) + }) + } +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/rule_random.go b/eventmesh-sdk-go/grpc/loadbalancer/rule_random.go new file mode 100644 index 0000000000..03b8011986 --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/rule_random.go @@ -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 loadbalancer + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "math/rand" +) + +// RandomRule random rule by math.Random +type RandomRule struct { + BaseRule +} + +// Choose return the instance by random +// the input must be ip +func (r *RandomRule) Choose(interface{}) (interface{}, error) { + count := 0 + for { + if count == 64 { + log.Warnf("failed to peek server by roundrobin after try 64 times") + return nil, ErrNoServerFound + } + srvs := r.lb.GetAvailableServer() + if len(srvs) == 0 { + log.Warnf("no available server found, load all server instead") + srvs = r.lb.GetAllStatusServer() + } + serverCount := len(srvs) + rdi := rand.Int63n(int64(serverCount)) + srv := srvs[rdi] + if !srv.ReadyForService { + count++ + continue + } + + log.Debugf("success peek server:%s by random", srv.Host) + return srv, nil + } +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/rule_random_test.go b/eventmesh-sdk-go/grpc/loadbalancer/rule_random_test.go new file mode 100644 index 0000000000..9eaec0b6dd --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/rule_random_test.go @@ -0,0 +1,87 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadbalancer + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestRandomRule_Choose(t *testing.T) { + type fields struct { + BaseRule BaseRule + } + type args struct { + in0 interface{} + } + fled := fields{ + BaseRule: func() BaseRule { + lb, _ := NewLoadBalancer(conf.Random, []*StatusServer{ + { + RealServer: "127.0.0.1", + ReadyForService: true, + Host: "127.0.0.1", + }, + { + RealServer: "127.0.0.2", + ReadyForService: true, + Host: "127.0.0.2", + }, + { + RealServer: "127.0.0.3", + ReadyForService: true, + Host: "127.0.0.3", + }, + }) + return BaseRule{ + lb: lb, + } + }(), + } + tests := []struct { + name string + fields fields + args args + want interface{} + wantErr assert.ErrorAssertionFunc + }{ + { + name: "random one", + fields: fled, + args: args{ + in0: "", + }, + want: "", + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return true + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &RandomRule{ + BaseRule: tt.fields.BaseRule, + } + got, err := r.Choose(tt.args.in0) + if !tt.wantErr(t, err, fmt.Sprintf("Choose(%v)", tt.args.in0)) { + return + } + assert.NotEmpty(t, got, "Choose(%v)", tt.args.in0) + }) + } +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/rule_roundrobin.go b/eventmesh-sdk-go/grpc/loadbalancer/rule_roundrobin.go new file mode 100644 index 0000000000..bf12d1847c --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/rule_roundrobin.go @@ -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 loadbalancer + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "go.uber.org/atomic" +) + +// RoundRobinRule rule with roundrobin algorithm +type RoundRobinRule struct { + BaseRule + cycleCounter *atomic.Int64 +} + +// Choose return the instance by roundrobin +// the input must be ip +func (r *RoundRobinRule) Choose(interface{}) (interface{}, error) { + count := 0 + for { + if count == 64 { + log.Warnf("failed to peek server by roundrobin after try 64 times") + return nil, ErrNoServerFound + } + srvs := r.lb.GetAvailableServer() + if len(srvs) == 0 { + log.Warnf("no available server found, load all server instead") + srvs = r.lb.GetAllStatusServer() + } + serverCount := len(srvs) + nextIndex := r.incrementAndGetModulo(int64(serverCount)) + srv := srvs[nextIndex] + if !srv.ReadyForService { + continue + count++ + } + log.Debugf("success peek server:%s by roundrobin", srv.Host) + return srv, nil + } +} + +// incrementAndGetModulo calculate to get the next modulo +func (r *RoundRobinRule) incrementAndGetModulo(modulo int64) int64 { + for { + current := r.cycleCounter.Load() + next := (current + 1) % modulo + if r.cycleCounter.CAS(current, next) { + return next + } + } +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/rule_roundrobin_test.go b/eventmesh-sdk-go/grpc/loadbalancer/rule_roundrobin_test.go new file mode 100644 index 0000000000..986f163268 --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/rule_roundrobin_test.go @@ -0,0 +1,93 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadbalancer + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/stretchr/testify/assert" + "go.uber.org/atomic" + "testing" +) + +func TestRoundRobinRule_Choose(t *testing.T) { + type fields struct { + BaseRule BaseRule + cycleCounter *atomic.Int64 + } + type args struct { + in0 interface{} + } + fid := fields{ + BaseRule: func() BaseRule { + lb, _ := NewLoadBalancer(conf.RoundRobin, []*StatusServer{ + { + RealServer: "127.0.0.1", + ReadyForService: true, + Host: "127.0.0.1", + }, + { + RealServer: "127.0.0.2", + ReadyForService: true, + Host: "127.0.0.2", + }, + { + RealServer: "127.0.0.3", + ReadyForService: true, + Host: "127.0.0.3", + }, + }) + return BaseRule{ + lb: lb, + } + }(), + cycleCounter: atomic.NewInt64(-1), + } + tests := []struct { + name string + fields fields + args args + want interface{} + wantErr assert.ErrorAssertionFunc + }{ + { + name: "round1 always be first", + fields: fid, + args: args{ + in0: "", + }, + want: "127.0.0.1", + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return true + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &RoundRobinRule{ + BaseRule: tt.fields.BaseRule, + cycleCounter: tt.fields.cycleCounter, + } + for _, v := range []string{"127.0.0.1", "127.0.0.2", "127.0.0.3", "127.0.0.1", "127.0.0.2"} { + got, err := r.Choose(tt.args.in0) + if !tt.wantErr(t, err, fmt.Sprintf("Choose(%v)", tt.args.in0)) { + return + } + assert.Equalf(t, v, got.(*StatusServer).Host, "Choose(%v)", tt.args.in0) + } + }) + } +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/status_server.go b/eventmesh-sdk-go/grpc/loadbalancer/status_server.go new file mode 100644 index 0000000000..d43d419ac7 --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/status_server.go @@ -0,0 +1,43 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadbalancer + +import "fmt" + +// StatusServer server with status check +type StatusServer struct { + // ReadyForService indicate the remote is connected + // and ready for service for client + ReadyForService bool + // Host holds the eventmesh server host + Host string + // RealServer holds the grpc client, producer/consumer/heartbeat + RealServer interface{} +} + +// NewStatusServer create new status server +func NewStatusServer(in interface{}, host string) *StatusServer { + return &StatusServer{ + RealServer: in, + Host: host, + ReadyForService: true, + } +} + +// String return the description about the server +func (s *StatusServer) String() string { + return fmt.Sprintf("removeAddr:%s, readyForService:%v", s.Host, s.ReadyForService) +} diff --git a/eventmesh-sdk-go/grpc/loadbalancer/status_server_test.go b/eventmesh-sdk-go/grpc/loadbalancer/status_server_test.go new file mode 100644 index 0000000000..fa78212cea --- /dev/null +++ b/eventmesh-sdk-go/grpc/loadbalancer/status_server_test.go @@ -0,0 +1,55 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loadbalancer + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestStatusServer_String(t *testing.T) { + type fields struct { + ReadyForService bool + Host string + RealServer interface{} + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "test string", + fields: fields{ + RealServer: "srv", + ReadyForService: true, + Host: "127.0.0.1", + }, + want: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := &StatusServer{ + ReadyForService: tt.fields.ReadyForService, + Host: tt.fields.Host, + RealServer: tt.fields.RealServer, + } + assert.NotEmpty(t, s.String(), "String()") + t.Logf(s.String()) + }) + } +} diff --git a/eventmesh-sdk-go/grpc/msg.go b/eventmesh-sdk-go/grpc/msg.go new file mode 100644 index 0000000000..08bc8492ab --- /dev/null +++ b/eventmesh-sdk-go/grpc/msg.go @@ -0,0 +1,123 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "time" +) + +// SimpleMessageBuilder used to build the simple message +type SimpleMessageBuilder struct { + *proto.SimpleMessage +} + +// NewMessageBuilder +func NewMessageBuilder() *SimpleMessageBuilder { + return &SimpleMessageBuilder{SimpleMessage: &proto.SimpleMessage{}} +} + +// WithHeader set the header for message +func (m *SimpleMessageBuilder) WithHeader(h *proto.RequestHeader) *SimpleMessageBuilder { + m.Header = h + return m +} + +// WithProducerGroup set the message producer group +func (m *SimpleMessageBuilder) WithProducerGroup(grp string) *SimpleMessageBuilder { + m.ProducerGroup = grp + return m +} + +// WithTopic set the topic +func (m *SimpleMessageBuilder) WithTopic(topic string) *SimpleMessageBuilder { + m.Topic = topic + return m +} + +// WithContent set the content to message +func (m *SimpleMessageBuilder) WithContent(content string) *SimpleMessageBuilder { + m.Content = content + return m +} + +// WithTTL set the message ttl +func (m *SimpleMessageBuilder) WithTTL(ttl time.Duration) *SimpleMessageBuilder { + m.Ttl = fmt.Sprintf("%v", ttl.Seconds()) + return m +} + +// WithTag set the tag for message +func (m *SimpleMessageBuilder) WithTag(tag string) *SimpleMessageBuilder { + m.Tag = tag + return m +} + +// WithUniqueID set the uniq id for message +func (m *SimpleMessageBuilder) WithUniqueID(id string) *SimpleMessageBuilder { + m.UniqueId = id + return m +} + +// WithSeqNO set the sequence no for message +func (m *SimpleMessageBuilder) WithSeqNO(no string) *SimpleMessageBuilder { + m.SeqNum = no + return m +} + +// WithProperties set the properties for message +func (m *SimpleMessageBuilder) WithProperties(props map[string]string) *SimpleMessageBuilder { + m.Properties = props + return m +} + +// CreateHeader create msg header +func CreateHeader(cfg *conf.GRPCConfig) *proto.RequestHeader { + return &proto.RequestHeader{ + Env: cfg.ENV, + Region: cfg.Region, + Idc: cfg.IDC, + Ip: utils.HostIPV4(), + Pid: utils.CurrentPID(), + Sys: cfg.SYS, + Username: cfg.Username, + Password: cfg.Password, + Language: conf.Language, + ProtocolType: EventmeshMessage, + ProtocolDesc: conf.ProtocolDesc, + ProtocolVersion: conf.ProtocolVersion, + } +} + +// GetTTLWithDefault return the ttl for the given msg, if err occurred return default +func GetTTLWithDefault(msg *proto.SimpleMessage, def time.Duration) time.Duration { + if msg == nil { + return def + } + val, ok := msg.Properties[EVENTMESH_MESSAGE_CONST_TTL] + if !ok { + return def + } + + tm, err := time.ParseDuration(val) + if err != nil { + return def + } + return tm +} diff --git a/eventmesh-sdk-go/grpc/option.go b/eventmesh-sdk-go/grpc/option.go new file mode 100644 index 0000000000..c5942f1b3a --- /dev/null +++ b/eventmesh-sdk-go/grpc/option.go @@ -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 grpc + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/id" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/seq" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" +) + +// GRPCOption option to set up the option for grpc client +type GRPCOption func(*eventMeshGRPCClient) + +// WithLogger set the logger for client, replace with the default +func WithLogger(l log.Logger) GRPCOption { + return func(client *eventMeshGRPCClient) { + log.SetLogger(l) + } +} + +// WithIDG setup the id generate api +func WithIDG(i id.Interface) GRPCOption { + return func(client *eventMeshGRPCClient) { + client.idg = i + } +} + +func WithSeq(i seq.Interface) GRPCOption { + return func(client *eventMeshGRPCClient) { + client.seqg = i + } +} diff --git a/eventmesh-sdk-go/grpc/producer.go b/eventmesh-sdk-go/grpc/producer.go new file mode 100644 index 0000000000..f4d77a5616 --- /dev/null +++ b/eventmesh-sdk-go/grpc/producer.go @@ -0,0 +1,92 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + "fmt" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/grpc/proto" + "google.golang.org/grpc" +) + +var ( + ErrNoMeshServer = fmt.Errorf("no event mesh server provided") + ErrLoadBalancer = fmt.Errorf("can not peek status server from loadbalancer") + + // LoadBalancerInput key set in the context, used to store the parameter + // into context, such as clientIP in IPHash + LoadBalancerInput = "LoadBalancerInput" +) + +// eventMeshProducer producer for eventmesh +type eventMeshProducer struct { + // client grpc producer client + client proto.PublisherServiceClient +} + +// newProducer create new producer instance to send events +func newProducer(grpcConn *grpc.ClientConn) (*eventMeshProducer, error) { + return &eventMeshProducer{ + client: proto.NewPublisherServiceClient(grpcConn), + }, nil +} + +// Close recover all resource hold in the producer +func (e *eventMeshProducer) Close() error { + log.Infof("close eventmesh producer") + return nil +} + +// Publish Async event publish +func (e *eventMeshProducer) Publish(ctx context.Context, msg *proto.SimpleMessage, opts ...grpc.CallOption) (*proto.Response, error) { + log.Infof("publish event:%v", msg.String()) + resp, err := e.client.Publish(ctx, msg, opts...) + if err != nil { + log.Warnf("failed to publish msg, err:%v", err) + return nil, err + } + + log.Infof("success publish msg:%s", msg.String()) + return resp, nil +} + +// RequestReply Sync event publish +func (e *eventMeshProducer) RequestReply(ctx context.Context, msg *proto.SimpleMessage, opts ...grpc.CallOption) (*proto.SimpleMessage, error) { + log.Infof("request reply event:%v", msg.String()) + resp, err := e.client.RequestReply(ctx, msg, opts...) + if err != nil { + log.Warnf("failed to request reply msg, err:%v", err) + return nil, err + } + + log.Infof("success request reply event") + return resp, nil +} + +// BatchPublish Async batch event publish +func (e *eventMeshProducer) BatchPublish(ctx context.Context, msg *proto.BatchMessage, opts ...grpc.CallOption) (*proto.Response, error) { + log.Infof("request batch publish event:%v", msg.String()) + resp, err := e.client.BatchPublish(ctx, msg, opts...) + if err != nil { + log.Warnf("failed to batch publish msg, err:%v", err) + return nil, err + } + + log.Infof("success batch publish event") + return resp, nil +} diff --git a/eventmesh-sdk-go/grpc/proto/README.md b/eventmesh-sdk-go/grpc/proto/README.md new file mode 100644 index 0000000000..8210f63c86 --- /dev/null +++ b/eventmesh-sdk-go/grpc/proto/README.md @@ -0,0 +1,20 @@ +how to generate proto go files +--- +generate go files by the protoc-gen-go owned by Google + +1. install the latest protoc-gen-go and protoc-gen-go-grpc +``` +go install google.golang.org/protobuf/cmd/protoc-gen-go +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc +``` +2. run command +``` +protoc --go_out=. eventmesh-client.proto +protoc --go-grpc_out=. eventmesh-client.proto +``` + +if you use the latest version protoc-gen-go, and generate by the old command, you will got these error: +``` +--go_out: protoc-gen-go: plugins are not supported; use 'protoc --go-grpc_out=...' to generate gRPC +``` + diff --git a/eventmesh-sdk-go/grpc/proto/eventmesh-client.pb.go b/eventmesh-sdk-go/grpc/proto/eventmesh-client.pb.go new file mode 100644 index 0000000000..a3e79e4f29 --- /dev/null +++ b/eventmesh-sdk-go/grpc/proto/eventmesh-client.pb.go @@ -0,0 +1,1485 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.19.4 +// source: eventmesh-client.proto + +//package eventmesh.common.protocol.grpc; +// +//option java_multiple_files = true; +//option java_package = "org.apache.eventmesh.common.protocol.grpc.protos"; +//option java_outer_classname = "EventmeshGrpc"; + +// make sure the protoc and protoc-gen-go is installed on your machine, and has set +// its directory into path +// download protoc: https://github.com/protocolbuffers/protobuf/releases +// install protoc-gen-go: go install google.golang.org/protobuf/cmd/protoc-gen-go +// generate go code by protoc: protoc --go_out=. eventmesh-client.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Subscription_SubscriptionItem_SubscriptionMode int32 + +const ( + Subscription_SubscriptionItem_CLUSTERING Subscription_SubscriptionItem_SubscriptionMode = 0 + Subscription_SubscriptionItem_BROADCASTING Subscription_SubscriptionItem_SubscriptionMode = 1 +) + +// Enum value maps for Subscription_SubscriptionItem_SubscriptionMode. +var ( + Subscription_SubscriptionItem_SubscriptionMode_name = map[int32]string{ + 0: "CLUSTERING", + 1: "BROADCASTING", + } + Subscription_SubscriptionItem_SubscriptionMode_value = map[string]int32{ + "CLUSTERING": 0, + "BROADCASTING": 1, + } +) + +func (x Subscription_SubscriptionItem_SubscriptionMode) Enum() *Subscription_SubscriptionItem_SubscriptionMode { + p := new(Subscription_SubscriptionItem_SubscriptionMode) + *p = x + return p +} + +func (x Subscription_SubscriptionItem_SubscriptionMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Subscription_SubscriptionItem_SubscriptionMode) Descriptor() protoreflect.EnumDescriptor { + return file_eventmesh_client_proto_enumTypes[0].Descriptor() +} + +func (Subscription_SubscriptionItem_SubscriptionMode) Type() protoreflect.EnumType { + return &file_eventmesh_client_proto_enumTypes[0] +} + +func (x Subscription_SubscriptionItem_SubscriptionMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Subscription_SubscriptionItem_SubscriptionMode.Descriptor instead. +func (Subscription_SubscriptionItem_SubscriptionMode) EnumDescriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{4, 0, 0} +} + +type Subscription_SubscriptionItem_SubscriptionType int32 + +const ( + Subscription_SubscriptionItem_ASYNC Subscription_SubscriptionItem_SubscriptionType = 0 + Subscription_SubscriptionItem_SYNC Subscription_SubscriptionItem_SubscriptionType = 1 +) + +// Enum value maps for Subscription_SubscriptionItem_SubscriptionType. +var ( + Subscription_SubscriptionItem_SubscriptionType_name = map[int32]string{ + 0: "ASYNC", + 1: "SYNC", + } + Subscription_SubscriptionItem_SubscriptionType_value = map[string]int32{ + "ASYNC": 0, + "SYNC": 1, + } +) + +func (x Subscription_SubscriptionItem_SubscriptionType) Enum() *Subscription_SubscriptionItem_SubscriptionType { + p := new(Subscription_SubscriptionItem_SubscriptionType) + *p = x + return p +} + +func (x Subscription_SubscriptionItem_SubscriptionType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Subscription_SubscriptionItem_SubscriptionType) Descriptor() protoreflect.EnumDescriptor { + return file_eventmesh_client_proto_enumTypes[1].Descriptor() +} + +func (Subscription_SubscriptionItem_SubscriptionType) Type() protoreflect.EnumType { + return &file_eventmesh_client_proto_enumTypes[1] +} + +func (x Subscription_SubscriptionItem_SubscriptionType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Subscription_SubscriptionItem_SubscriptionType.Descriptor instead. +func (Subscription_SubscriptionItem_SubscriptionType) EnumDescriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{4, 0, 1} +} + +type Heartbeat_ClientType int32 + +const ( + Heartbeat_PUB Heartbeat_ClientType = 0 + Heartbeat_SUB Heartbeat_ClientType = 1 +) + +// Enum value maps for Heartbeat_ClientType. +var ( + Heartbeat_ClientType_name = map[int32]string{ + 0: "PUB", + 1: "SUB", + } + Heartbeat_ClientType_value = map[string]int32{ + "PUB": 0, + "SUB": 1, + } +) + +func (x Heartbeat_ClientType) Enum() *Heartbeat_ClientType { + p := new(Heartbeat_ClientType) + *p = x + return p +} + +func (x Heartbeat_ClientType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Heartbeat_ClientType) Descriptor() protoreflect.EnumDescriptor { + return file_eventmesh_client_proto_enumTypes[2].Descriptor() +} + +func (Heartbeat_ClientType) Type() protoreflect.EnumType { + return &file_eventmesh_client_proto_enumTypes[2] +} + +func (x Heartbeat_ClientType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Heartbeat_ClientType.Descriptor instead. +func (Heartbeat_ClientType) EnumDescriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{5, 0} +} + +type RequestHeader struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Env string `protobuf:"bytes,1,opt,name=env,proto3" json:"env,omitempty"` + Region string `protobuf:"bytes,2,opt,name=region,proto3" json:"region,omitempty"` + Idc string `protobuf:"bytes,3,opt,name=idc,proto3" json:"idc,omitempty"` + Ip string `protobuf:"bytes,4,opt,name=ip,proto3" json:"ip,omitempty"` + Pid string `protobuf:"bytes,5,opt,name=pid,proto3" json:"pid,omitempty"` + Sys string `protobuf:"bytes,6,opt,name=sys,proto3" json:"sys,omitempty"` + Username string `protobuf:"bytes,7,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,8,opt,name=password,proto3" json:"password,omitempty"` + Language string `protobuf:"bytes,9,opt,name=language,proto3" json:"language,omitempty"` + ProtocolType string `protobuf:"bytes,10,opt,name=protocolType,proto3" json:"protocolType,omitempty"` + ProtocolVersion string `protobuf:"bytes,11,opt,name=protocolVersion,proto3" json:"protocolVersion,omitempty"` + ProtocolDesc string `protobuf:"bytes,12,opt,name=protocolDesc,proto3" json:"protocolDesc,omitempty"` +} + +func (x *RequestHeader) Reset() { + *x = RequestHeader{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestHeader) ProtoMessage() {} + +func (x *RequestHeader) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestHeader.ProtoReflect.Descriptor instead. +func (*RequestHeader) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{0} +} + +func (x *RequestHeader) GetEnv() string { + if x != nil { + return x.Env + } + return "" +} + +func (x *RequestHeader) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +func (x *RequestHeader) GetIdc() string { + if x != nil { + return x.Idc + } + return "" +} + +func (x *RequestHeader) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *RequestHeader) GetPid() string { + if x != nil { + return x.Pid + } + return "" +} + +func (x *RequestHeader) GetSys() string { + if x != nil { + return x.Sys + } + return "" +} + +func (x *RequestHeader) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *RequestHeader) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *RequestHeader) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +func (x *RequestHeader) GetProtocolType() string { + if x != nil { + return x.ProtocolType + } + return "" +} + +func (x *RequestHeader) GetProtocolVersion() string { + if x != nil { + return x.ProtocolVersion + } + return "" +} + +func (x *RequestHeader) GetProtocolDesc() string { + if x != nil { + return x.ProtocolDesc + } + return "" +} + +type SimpleMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header *RequestHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + ProducerGroup string `protobuf:"bytes,2,opt,name=producerGroup,proto3" json:"producerGroup,omitempty"` + Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"` + Content string `protobuf:"bytes,4,opt,name=content,proto3" json:"content,omitempty"` + Ttl string `protobuf:"bytes,5,opt,name=ttl,proto3" json:"ttl,omitempty"` + UniqueId string `protobuf:"bytes,6,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"` + SeqNum string `protobuf:"bytes,7,opt,name=seqNum,proto3" json:"seqNum,omitempty"` + Tag string `protobuf:"bytes,8,opt,name=tag,proto3" json:"tag,omitempty"` + Properties map[string]string `protobuf:"bytes,9,rep,name=properties,proto3" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SimpleMessage) Reset() { + *x = SimpleMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SimpleMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SimpleMessage) ProtoMessage() {} + +func (x *SimpleMessage) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SimpleMessage.ProtoReflect.Descriptor instead. +func (*SimpleMessage) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{1} +} + +func (x *SimpleMessage) GetHeader() *RequestHeader { + if x != nil { + return x.Header + } + return nil +} + +func (x *SimpleMessage) GetProducerGroup() string { + if x != nil { + return x.ProducerGroup + } + return "" +} + +func (x *SimpleMessage) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *SimpleMessage) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *SimpleMessage) GetTtl() string { + if x != nil { + return x.Ttl + } + return "" +} + +func (x *SimpleMessage) GetUniqueId() string { + if x != nil { + return x.UniqueId + } + return "" +} + +func (x *SimpleMessage) GetSeqNum() string { + if x != nil { + return x.SeqNum + } + return "" +} + +func (x *SimpleMessage) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +func (x *SimpleMessage) GetProperties() map[string]string { + if x != nil { + return x.Properties + } + return nil +} + +type BatchMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header *RequestHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + ProducerGroup string `protobuf:"bytes,2,opt,name=producerGroup,proto3" json:"producerGroup,omitempty"` + Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"` + MessageItem []*BatchMessage_MessageItem `protobuf:"bytes,4,rep,name=messageItem,proto3" json:"messageItem,omitempty"` +} + +func (x *BatchMessage) Reset() { + *x = BatchMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchMessage) ProtoMessage() {} + +func (x *BatchMessage) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchMessage.ProtoReflect.Descriptor instead. +func (*BatchMessage) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{2} +} + +func (x *BatchMessage) GetHeader() *RequestHeader { + if x != nil { + return x.Header + } + return nil +} + +func (x *BatchMessage) GetProducerGroup() string { + if x != nil { + return x.ProducerGroup + } + return "" +} + +func (x *BatchMessage) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *BatchMessage) GetMessageItem() []*BatchMessage_MessageItem { + if x != nil { + return x.MessageItem + } + return nil +} + +type Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RespCode string `protobuf:"bytes,1,opt,name=respCode,proto3" json:"respCode,omitempty"` + RespMsg string `protobuf:"bytes,2,opt,name=respMsg,proto3" json:"respMsg,omitempty"` + RespTime string `protobuf:"bytes,3,opt,name=respTime,proto3" json:"respTime,omitempty"` +} + +func (x *Response) Reset() { + *x = Response{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Response) ProtoMessage() {} + +func (x *Response) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Response.ProtoReflect.Descriptor instead. +func (*Response) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{3} +} + +func (x *Response) GetRespCode() string { + if x != nil { + return x.RespCode + } + return "" +} + +func (x *Response) GetRespMsg() string { + if x != nil { + return x.RespMsg + } + return "" +} + +func (x *Response) GetRespTime() string { + if x != nil { + return x.RespTime + } + return "" +} + +type Subscription struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header *RequestHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + ConsumerGroup string `protobuf:"bytes,2,opt,name=consumerGroup,proto3" json:"consumerGroup,omitempty"` + SubscriptionItems []*Subscription_SubscriptionItem `protobuf:"bytes,3,rep,name=subscriptionItems,proto3" json:"subscriptionItems,omitempty"` + Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"` + Reply *Subscription_Reply `protobuf:"bytes,5,opt,name=reply,proto3" json:"reply,omitempty"` +} + +func (x *Subscription) Reset() { + *x = Subscription{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Subscription) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Subscription) ProtoMessage() {} + +func (x *Subscription) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Subscription.ProtoReflect.Descriptor instead. +func (*Subscription) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{4} +} + +func (x *Subscription) GetHeader() *RequestHeader { + if x != nil { + return x.Header + } + return nil +} + +func (x *Subscription) GetConsumerGroup() string { + if x != nil { + return x.ConsumerGroup + } + return "" +} + +func (x *Subscription) GetSubscriptionItems() []*Subscription_SubscriptionItem { + if x != nil { + return x.SubscriptionItems + } + return nil +} + +func (x *Subscription) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *Subscription) GetReply() *Subscription_Reply { + if x != nil { + return x.Reply + } + return nil +} + +type Heartbeat struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header *RequestHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + ClientType Heartbeat_ClientType `protobuf:"varint,2,opt,name=clientType,proto3,enum=eventmesh.common.protocol.grpc.Heartbeat_ClientType" json:"clientType,omitempty"` + ProducerGroup string `protobuf:"bytes,3,opt,name=producerGroup,proto3" json:"producerGroup,omitempty"` + ConsumerGroup string `protobuf:"bytes,4,opt,name=consumerGroup,proto3" json:"consumerGroup,omitempty"` + HeartbeatItems []*Heartbeat_HeartbeatItem `protobuf:"bytes,5,rep,name=heartbeatItems,proto3" json:"heartbeatItems,omitempty"` +} + +func (x *Heartbeat) Reset() { + *x = Heartbeat{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Heartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Heartbeat) ProtoMessage() {} + +func (x *Heartbeat) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Heartbeat.ProtoReflect.Descriptor instead. +func (*Heartbeat) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{5} +} + +func (x *Heartbeat) GetHeader() *RequestHeader { + if x != nil { + return x.Header + } + return nil +} + +func (x *Heartbeat) GetClientType() Heartbeat_ClientType { + if x != nil { + return x.ClientType + } + return Heartbeat_PUB +} + +func (x *Heartbeat) GetProducerGroup() string { + if x != nil { + return x.ProducerGroup + } + return "" +} + +func (x *Heartbeat) GetConsumerGroup() string { + if x != nil { + return x.ConsumerGroup + } + return "" +} + +func (x *Heartbeat) GetHeartbeatItems() []*Heartbeat_HeartbeatItem { + if x != nil { + return x.HeartbeatItems + } + return nil +} + +type BatchMessage_MessageItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + Ttl string `protobuf:"bytes,2,opt,name=ttl,proto3" json:"ttl,omitempty"` + UniqueId string `protobuf:"bytes,3,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"` + SeqNum string `protobuf:"bytes,4,opt,name=seqNum,proto3" json:"seqNum,omitempty"` + Tag string `protobuf:"bytes,5,opt,name=tag,proto3" json:"tag,omitempty"` + Properties map[string]string `protobuf:"bytes,6,rep,name=properties,proto3" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *BatchMessage_MessageItem) Reset() { + *x = BatchMessage_MessageItem{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchMessage_MessageItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchMessage_MessageItem) ProtoMessage() {} + +func (x *BatchMessage_MessageItem) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchMessage_MessageItem.ProtoReflect.Descriptor instead. +func (*BatchMessage_MessageItem) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *BatchMessage_MessageItem) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *BatchMessage_MessageItem) GetTtl() string { + if x != nil { + return x.Ttl + } + return "" +} + +func (x *BatchMessage_MessageItem) GetUniqueId() string { + if x != nil { + return x.UniqueId + } + return "" +} + +func (x *BatchMessage_MessageItem) GetSeqNum() string { + if x != nil { + return x.SeqNum + } + return "" +} + +func (x *BatchMessage_MessageItem) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +func (x *BatchMessage_MessageItem) GetProperties() map[string]string { + if x != nil { + return x.Properties + } + return nil +} + +type Subscription_SubscriptionItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` + Mode Subscription_SubscriptionItem_SubscriptionMode `protobuf:"varint,2,opt,name=mode,proto3,enum=eventmesh.common.protocol.grpc.Subscription_SubscriptionItem_SubscriptionMode" json:"mode,omitempty"` + Type Subscription_SubscriptionItem_SubscriptionType `protobuf:"varint,3,opt,name=type,proto3,enum=eventmesh.common.protocol.grpc.Subscription_SubscriptionItem_SubscriptionType" json:"type,omitempty"` +} + +func (x *Subscription_SubscriptionItem) Reset() { + *x = Subscription_SubscriptionItem{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Subscription_SubscriptionItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Subscription_SubscriptionItem) ProtoMessage() {} + +func (x *Subscription_SubscriptionItem) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Subscription_SubscriptionItem.ProtoReflect.Descriptor instead. +func (*Subscription_SubscriptionItem) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *Subscription_SubscriptionItem) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *Subscription_SubscriptionItem) GetMode() Subscription_SubscriptionItem_SubscriptionMode { + if x != nil { + return x.Mode + } + return Subscription_SubscriptionItem_CLUSTERING +} + +func (x *Subscription_SubscriptionItem) GetType() Subscription_SubscriptionItem_SubscriptionType { + if x != nil { + return x.Type + } + return Subscription_SubscriptionItem_ASYNC +} + +type Subscription_Reply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProducerGroup string `protobuf:"bytes,1,opt,name=producerGroup,proto3" json:"producerGroup,omitempty"` + Topic string `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"` + Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` + Ttl string `protobuf:"bytes,4,opt,name=ttl,proto3" json:"ttl,omitempty"` + UniqueId string `protobuf:"bytes,5,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"` + SeqNum string `protobuf:"bytes,6,opt,name=seqNum,proto3" json:"seqNum,omitempty"` + Tag string `protobuf:"bytes,7,opt,name=tag,proto3" json:"tag,omitempty"` + Properties map[string]string `protobuf:"bytes,8,rep,name=properties,proto3" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Subscription_Reply) Reset() { + *x = Subscription_Reply{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Subscription_Reply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Subscription_Reply) ProtoMessage() {} + +func (x *Subscription_Reply) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Subscription_Reply.ProtoReflect.Descriptor instead. +func (*Subscription_Reply) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{4, 1} +} + +func (x *Subscription_Reply) GetProducerGroup() string { + if x != nil { + return x.ProducerGroup + } + return "" +} + +func (x *Subscription_Reply) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *Subscription_Reply) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *Subscription_Reply) GetTtl() string { + if x != nil { + return x.Ttl + } + return "" +} + +func (x *Subscription_Reply) GetUniqueId() string { + if x != nil { + return x.UniqueId + } + return "" +} + +func (x *Subscription_Reply) GetSeqNum() string { + if x != nil { + return x.SeqNum + } + return "" +} + +func (x *Subscription_Reply) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +func (x *Subscription_Reply) GetProperties() map[string]string { + if x != nil { + return x.Properties + } + return nil +} + +type Heartbeat_HeartbeatItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *Heartbeat_HeartbeatItem) Reset() { + *x = Heartbeat_HeartbeatItem{} + if protoimpl.UnsafeEnabled { + mi := &file_eventmesh_client_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Heartbeat_HeartbeatItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Heartbeat_HeartbeatItem) ProtoMessage() {} + +func (x *Heartbeat_HeartbeatItem) ProtoReflect() protoreflect.Message { + mi := &file_eventmesh_client_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Heartbeat_HeartbeatItem.ProtoReflect.Descriptor instead. +func (*Heartbeat_HeartbeatItem) Descriptor() ([]byte, []int) { + return file_eventmesh_client_proto_rawDescGZIP(), []int{5, 0} +} + +func (x *Heartbeat_HeartbeatItem) GetTopic() string { + if x != nil { + return x.Topic + } + return "" +} + +func (x *Heartbeat_HeartbeatItem) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +var File_eventmesh_client_proto protoreflect.FileDescriptor + +var file_eventmesh_client_proto_rawDesc = []byte{ + 0x0a, 0x16, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2d, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x22, 0xc5, 0x02, 0x0a, 0x0d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, + 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x69, 0x64, 0x63, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x79, 0x73, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x79, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x22, + 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x44, 0x65, 0x73, 0x63, + 0x22, 0xa2, 0x03, 0x0a, 0x0d, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, + 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x74, + 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x65, 0x71, 0x4e, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x65, 0x71, 0x4e, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x5d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x98, 0x04, 0x0a, 0x0c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, + 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x24, 0x0a, + 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x5a, 0x0a, 0x0b, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x49, 0x74, 0x65, 0x6d, 0x1a, 0xa8, 0x02, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, + 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x74, + 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x65, 0x71, 0x4e, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x65, 0x71, 0x4e, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x68, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x5c, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x72, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x70, + 0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x73, 0x70, 0x4d, + 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xf1, + 0x07, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x45, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x6b, 0x0a, 0x11, + 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x11, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x48, 0x0a, 0x05, 0x72, + 0x65, 0x70, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x52, 0x05, + 0x72, 0x65, 0x70, 0x6c, 0x79, 0x1a, 0xcf, 0x02, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, + 0x12, 0x62, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x4e, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x62, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x4e, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, + 0x6d, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x34, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x0a, + 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, + 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x22, 0x27, + 0x0a, 0x10, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x01, 0x1a, 0xd8, 0x02, 0x0a, 0x05, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, + 0x71, 0x75, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x6e, 0x69, + 0x71, 0x75, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x4e, 0x75, 0x6d, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x71, 0x4e, 0x75, 0x6d, 0x12, 0x10, 0x0a, + 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, + 0x62, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0xae, 0x03, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, + 0x12, 0x45, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2d, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, + 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x65, 0x61, + 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, + 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6d, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5f, 0x0a, 0x0e, 0x68, 0x65, 0x61, + 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x37, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x2e, 0x48, 0x65, 0x61, + 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x0e, 0x68, 0x65, 0x61, 0x72, + 0x74, 0x62, 0x65, 0x61, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x1a, 0x37, 0x0a, 0x0d, 0x48, 0x65, + 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x70, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, + 0x63, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x22, 0x1e, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x42, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x55, + 0x42, 0x10, 0x01, 0x32, 0xcc, 0x02, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, + 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x07, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x12, 0x2d, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x1a, 0x28, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x0c, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2d, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x2d, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x66, 0x0a, 0x0c, 0x62, 0x61, + 0x74, 0x63, 0x68, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x2c, 0x2e, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x28, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x32, 0xd1, 0x02, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x12, 0x2c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x1a, 0x28, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0f, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x2c, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x2d, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, + 0x65, 0x0a, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x2c, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x28, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x74, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, + 0x65, 0x61, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x60, 0x0a, 0x09, 0x68, 0x65, + 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x29, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, + 0x61, 0x74, 0x1a, 0x28, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x5a, 0x07, + 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_eventmesh_client_proto_rawDescOnce sync.Once + file_eventmesh_client_proto_rawDescData = file_eventmesh_client_proto_rawDesc +) + +func file_eventmesh_client_proto_rawDescGZIP() []byte { + file_eventmesh_client_proto_rawDescOnce.Do(func() { + file_eventmesh_client_proto_rawDescData = protoimpl.X.CompressGZIP(file_eventmesh_client_proto_rawDescData) + }) + return file_eventmesh_client_proto_rawDescData +} + +var file_eventmesh_client_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_eventmesh_client_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_eventmesh_client_proto_goTypes = []interface{}{ + (Subscription_SubscriptionItem_SubscriptionMode)(0), // 0: eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode + (Subscription_SubscriptionItem_SubscriptionType)(0), // 1: eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType + (Heartbeat_ClientType)(0), // 2: eventmesh.common.protocol.grpc.Heartbeat.ClientType + (*RequestHeader)(nil), // 3: eventmesh.common.protocol.grpc.RequestHeader + (*SimpleMessage)(nil), // 4: eventmesh.common.protocol.grpc.SimpleMessage + (*BatchMessage)(nil), // 5: eventmesh.common.protocol.grpc.BatchMessage + (*Response)(nil), // 6: eventmesh.common.protocol.grpc.Response + (*Subscription)(nil), // 7: eventmesh.common.protocol.grpc.Subscription + (*Heartbeat)(nil), // 8: eventmesh.common.protocol.grpc.Heartbeat + nil, // 9: eventmesh.common.protocol.grpc.SimpleMessage.PropertiesEntry + (*BatchMessage_MessageItem)(nil), // 10: eventmesh.common.protocol.grpc.BatchMessage.MessageItem + nil, // 11: eventmesh.common.protocol.grpc.BatchMessage.MessageItem.PropertiesEntry + (*Subscription_SubscriptionItem)(nil), // 12: eventmesh.common.protocol.grpc.Subscription.SubscriptionItem + (*Subscription_Reply)(nil), // 13: eventmesh.common.protocol.grpc.Subscription.Reply + nil, // 14: eventmesh.common.protocol.grpc.Subscription.Reply.PropertiesEntry + (*Heartbeat_HeartbeatItem)(nil), // 15: eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem +} +var file_eventmesh_client_proto_depIdxs = []int32{ + 3, // 0: eventmesh.common.protocol.grpc.SimpleMessage.header:type_name -> eventmesh.common.protocol.grpc.RequestHeader + 9, // 1: eventmesh.common.protocol.grpc.SimpleMessage.properties:type_name -> eventmesh.common.protocol.grpc.SimpleMessage.PropertiesEntry + 3, // 2: eventmesh.common.protocol.grpc.BatchMessage.header:type_name -> eventmesh.common.protocol.grpc.RequestHeader + 10, // 3: eventmesh.common.protocol.grpc.BatchMessage.messageItem:type_name -> eventmesh.common.protocol.grpc.BatchMessage.MessageItem + 3, // 4: eventmesh.common.protocol.grpc.Subscription.header:type_name -> eventmesh.common.protocol.grpc.RequestHeader + 12, // 5: eventmesh.common.protocol.grpc.Subscription.subscriptionItems:type_name -> eventmesh.common.protocol.grpc.Subscription.SubscriptionItem + 13, // 6: eventmesh.common.protocol.grpc.Subscription.reply:type_name -> eventmesh.common.protocol.grpc.Subscription.Reply + 3, // 7: eventmesh.common.protocol.grpc.Heartbeat.header:type_name -> eventmesh.common.protocol.grpc.RequestHeader + 2, // 8: eventmesh.common.protocol.grpc.Heartbeat.clientType:type_name -> eventmesh.common.protocol.grpc.Heartbeat.ClientType + 15, // 9: eventmesh.common.protocol.grpc.Heartbeat.heartbeatItems:type_name -> eventmesh.common.protocol.grpc.Heartbeat.HeartbeatItem + 11, // 10: eventmesh.common.protocol.grpc.BatchMessage.MessageItem.properties:type_name -> eventmesh.common.protocol.grpc.BatchMessage.MessageItem.PropertiesEntry + 0, // 11: eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.mode:type_name -> eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionMode + 1, // 12: eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.type:type_name -> eventmesh.common.protocol.grpc.Subscription.SubscriptionItem.SubscriptionType + 14, // 13: eventmesh.common.protocol.grpc.Subscription.Reply.properties:type_name -> eventmesh.common.protocol.grpc.Subscription.Reply.PropertiesEntry + 4, // 14: eventmesh.common.protocol.grpc.PublisherService.publish:input_type -> eventmesh.common.protocol.grpc.SimpleMessage + 4, // 15: eventmesh.common.protocol.grpc.PublisherService.requestReply:input_type -> eventmesh.common.protocol.grpc.SimpleMessage + 5, // 16: eventmesh.common.protocol.grpc.PublisherService.batchPublish:input_type -> eventmesh.common.protocol.grpc.BatchMessage + 7, // 17: eventmesh.common.protocol.grpc.ConsumerService.subscribe:input_type -> eventmesh.common.protocol.grpc.Subscription + 7, // 18: eventmesh.common.protocol.grpc.ConsumerService.subscribeStream:input_type -> eventmesh.common.protocol.grpc.Subscription + 7, // 19: eventmesh.common.protocol.grpc.ConsumerService.unsubscribe:input_type -> eventmesh.common.protocol.grpc.Subscription + 8, // 20: eventmesh.common.protocol.grpc.HeartbeatService.heartbeat:input_type -> eventmesh.common.protocol.grpc.Heartbeat + 6, // 21: eventmesh.common.protocol.grpc.PublisherService.publish:output_type -> eventmesh.common.protocol.grpc.Response + 4, // 22: eventmesh.common.protocol.grpc.PublisherService.requestReply:output_type -> eventmesh.common.protocol.grpc.SimpleMessage + 6, // 23: eventmesh.common.protocol.grpc.PublisherService.batchPublish:output_type -> eventmesh.common.protocol.grpc.Response + 6, // 24: eventmesh.common.protocol.grpc.ConsumerService.subscribe:output_type -> eventmesh.common.protocol.grpc.Response + 4, // 25: eventmesh.common.protocol.grpc.ConsumerService.subscribeStream:output_type -> eventmesh.common.protocol.grpc.SimpleMessage + 6, // 26: eventmesh.common.protocol.grpc.ConsumerService.unsubscribe:output_type -> eventmesh.common.protocol.grpc.Response + 6, // 27: eventmesh.common.protocol.grpc.HeartbeatService.heartbeat:output_type -> eventmesh.common.protocol.grpc.Response + 21, // [21:28] is the sub-list for method output_type + 14, // [14:21] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name +} + +func init() { file_eventmesh_client_proto_init() } +func file_eventmesh_client_proto_init() { + if File_eventmesh_client_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_eventmesh_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestHeader); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SimpleMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Subscription); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Heartbeat); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchMessage_MessageItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Subscription_SubscriptionItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Subscription_Reply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_eventmesh_client_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Heartbeat_HeartbeatItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_eventmesh_client_proto_rawDesc, + NumEnums: 3, + NumMessages: 13, + NumExtensions: 0, + NumServices: 3, + }, + GoTypes: file_eventmesh_client_proto_goTypes, + DependencyIndexes: file_eventmesh_client_proto_depIdxs, + EnumInfos: file_eventmesh_client_proto_enumTypes, + MessageInfos: file_eventmesh_client_proto_msgTypes, + }.Build() + File_eventmesh_client_proto = out.File + file_eventmesh_client_proto_rawDesc = nil + file_eventmesh_client_proto_goTypes = nil + file_eventmesh_client_proto_depIdxs = nil +} diff --git a/eventmesh-sdk-go/grpc/proto/eventmesh-client.proto b/eventmesh-sdk-go/grpc/proto/eventmesh-client.proto new file mode 100644 index 0000000000..349e8c1dc0 --- /dev/null +++ b/eventmesh-sdk-go/grpc/proto/eventmesh-client.proto @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; + +//package eventmesh.common.protocol.grpc; +// +//option java_multiple_files = true; +//option java_package = "org.apache.eventmesh.common.protocol.grpc.protos"; +//option java_outer_classname = "EventmeshGrpc"; + +// make sure the protoc and protoc-gen-go is installed on your machine, and has set +// its directory into path +// download protoc: https://github.com/protocolbuffers/protobuf/releases +// install protoc-gen-go: go install google.golang.org/protobuf/cmd/protoc-gen-go +// generate go code by protoc: protoc --go_out=. eventmesh-client.proto + +package eventmesh.common.protocol.grpc; + +option go_package= ".;proto"; + +message RequestHeader { + string env = 1; + string region = 2; + string idc = 3; + string ip = 4; + string pid = 5; + string sys = 6; + string username = 7; + string password = 8; + string language = 9; + string protocolType = 10; + string protocolVersion = 11; + string protocolDesc = 12; +} + +message SimpleMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + string content = 4; + string ttl = 5; + string uniqueId = 6; + string seqNum = 7; + string tag = 8; + map properties = 9; +} + +message BatchMessage { + RequestHeader header = 1; + string producerGroup = 2; + string topic = 3; + + message MessageItem { + string content = 1; + string ttl = 2; + string uniqueId = 3; + string seqNum = 4; + string tag = 5; + map properties = 6; + } + + repeated MessageItem messageItem = 4; +} + +message Response { + string respCode = 1; + string respMsg = 2; + string respTime = 3; +} + +message Subscription { + RequestHeader header = 1; + string consumerGroup = 2; + + message SubscriptionItem { + enum SubscriptionMode { + CLUSTERING = 0; + BROADCASTING = 1; + } + + enum SubscriptionType { + ASYNC = 0; + SYNC = 1; + } + + string topic = 1; + SubscriptionMode mode = 2; + SubscriptionType type = 3; + } + + repeated SubscriptionItem subscriptionItems = 3; + string url = 4; + + message Reply { + string producerGroup = 1; + string topic = 2; + string content = 3; + string ttl = 4; + string uniqueId = 5; + string seqNum = 6; + string tag = 7; + map properties = 8; + } + + Reply reply = 5; +} + +message Heartbeat { + enum ClientType { + PUB = 0; + SUB = 1; + } + + RequestHeader header = 1; + ClientType clientType = 2; + string producerGroup = 3; + string consumerGroup = 4; + + message HeartbeatItem { + string topic = 1; + string url = 2; + } + + repeated HeartbeatItem heartbeatItems = 5; +} + +service PublisherService { + // Async event publish + rpc publish(SimpleMessage) returns (Response); + + // Sync event publish + rpc requestReply(SimpleMessage) returns (SimpleMessage); + + // Async batch event publish + rpc batchPublish(BatchMessage) returns (Response); +} + +service ConsumerService { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + rpc subscribe(Subscription) returns (Response); + + // The subscribed event will be delivered through stream of Message + rpc subscribeStream(stream Subscription) returns (stream SimpleMessage); + + rpc unsubscribe(Subscription) returns (Response); +} + +service HeartbeatService { + rpc heartbeat(Heartbeat) returns (Response); +} \ No newline at end of file diff --git a/eventmesh-sdk-go/grpc/proto/eventmesh-client_grpc.pb.go b/eventmesh-sdk-go/grpc/proto/eventmesh-client_grpc.pb.go new file mode 100644 index 0000000000..a61a9115eb --- /dev/null +++ b/eventmesh-sdk-go/grpc/proto/eventmesh-client_grpc.pb.go @@ -0,0 +1,479 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.19.4 +// source: eventmesh-client.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// PublisherServiceClient is the client API for PublisherService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PublisherServiceClient interface { + // Async event publish + Publish(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*Response, error) + // Sync event publish + RequestReply(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) + // Async batch event publish + BatchPublish(ctx context.Context, in *BatchMessage, opts ...grpc.CallOption) (*Response, error) +} + +type publisherServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPublisherServiceClient(cc grpc.ClientConnInterface) PublisherServiceClient { + return &publisherServiceClient{cc} +} + +func (c *publisherServiceClient) Publish(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*Response, error) { + out := new(Response) + err := c.cc.Invoke(ctx, "/eventmesh.common.protocol.grpc.PublisherService/publish", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *publisherServiceClient) RequestReply(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) { + out := new(SimpleMessage) + err := c.cc.Invoke(ctx, "/eventmesh.common.protocol.grpc.PublisherService/requestReply", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *publisherServiceClient) BatchPublish(ctx context.Context, in *BatchMessage, opts ...grpc.CallOption) (*Response, error) { + out := new(Response) + err := c.cc.Invoke(ctx, "/eventmesh.common.protocol.grpc.PublisherService/batchPublish", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PublisherServiceServer is the server API for PublisherService service. +// All implementations must embed UnimplementedPublisherServiceServer +// for forward compatibility +type PublisherServiceServer interface { + // Async event publish + Publish(context.Context, *SimpleMessage) (*Response, error) + // Sync event publish + RequestReply(context.Context, *SimpleMessage) (*SimpleMessage, error) + // Async batch event publish + BatchPublish(context.Context, *BatchMessage) (*Response, error) + mustEmbedUnimplementedPublisherServiceServer() +} + +// UnimplementedPublisherServiceServer must be embedded to have forward compatible implementations. +type UnimplementedPublisherServiceServer struct { +} + +func (UnimplementedPublisherServiceServer) Publish(context.Context, *SimpleMessage) (*Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method Publish not implemented") +} +func (UnimplementedPublisherServiceServer) RequestReply(context.Context, *SimpleMessage) (*SimpleMessage, error) { + return nil, status.Errorf(codes.Unimplemented, "method RequestReply not implemented") +} +func (UnimplementedPublisherServiceServer) BatchPublish(context.Context, *BatchMessage) (*Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method BatchPublish not implemented") +} +func (UnimplementedPublisherServiceServer) mustEmbedUnimplementedPublisherServiceServer() {} + +// UnsafePublisherServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PublisherServiceServer will +// result in compilation errors. +type UnsafePublisherServiceServer interface { + mustEmbedUnimplementedPublisherServiceServer() +} + +func RegisterPublisherServiceServer(s grpc.ServiceRegistrar, srv PublisherServiceServer) { + s.RegisterService(&PublisherService_ServiceDesc, srv) +} + +func _PublisherService_Publish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SimpleMessage) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PublisherServiceServer).Publish(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/eventmesh.common.protocol.grpc.PublisherService/publish", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublisherServiceServer).Publish(ctx, req.(*SimpleMessage)) + } + return interceptor(ctx, in, info, handler) +} + +func _PublisherService_RequestReply_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SimpleMessage) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PublisherServiceServer).RequestReply(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/eventmesh.common.protocol.grpc.PublisherService/requestReply", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublisherServiceServer).RequestReply(ctx, req.(*SimpleMessage)) + } + return interceptor(ctx, in, info, handler) +} + +func _PublisherService_BatchPublish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BatchMessage) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PublisherServiceServer).BatchPublish(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/eventmesh.common.protocol.grpc.PublisherService/batchPublish", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublisherServiceServer).BatchPublish(ctx, req.(*BatchMessage)) + } + return interceptor(ctx, in, info, handler) +} + +// PublisherService_ServiceDesc is the grpc.ServiceDesc for PublisherService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PublisherService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "eventmesh.common.protocol.grpc.PublisherService", + HandlerType: (*PublisherServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "publish", + Handler: _PublisherService_Publish_Handler, + }, + { + MethodName: "requestReply", + Handler: _PublisherService_RequestReply_Handler, + }, + { + MethodName: "batchPublish", + Handler: _PublisherService_BatchPublish_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "eventmesh-client.proto", +} + +// ConsumerServiceClient is the client API for ConsumerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ConsumerServiceClient interface { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + Subscribe(ctx context.Context, in *Subscription, opts ...grpc.CallOption) (*Response, error) + // The subscribed event will be delivered through stream of Message + SubscribeStream(ctx context.Context, opts ...grpc.CallOption) (ConsumerService_SubscribeStreamClient, error) + Unsubscribe(ctx context.Context, in *Subscription, opts ...grpc.CallOption) (*Response, error) +} + +type consumerServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewConsumerServiceClient(cc grpc.ClientConnInterface) ConsumerServiceClient { + return &consumerServiceClient{cc} +} + +func (c *consumerServiceClient) Subscribe(ctx context.Context, in *Subscription, opts ...grpc.CallOption) (*Response, error) { + out := new(Response) + err := c.cc.Invoke(ctx, "/eventmesh.common.protocol.grpc.ConsumerService/subscribe", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *consumerServiceClient) SubscribeStream(ctx context.Context, opts ...grpc.CallOption) (ConsumerService_SubscribeStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &ConsumerService_ServiceDesc.Streams[0], "/eventmesh.common.protocol.grpc.ConsumerService/subscribeStream", opts...) + if err != nil { + return nil, err + } + x := &consumerServiceSubscribeStreamClient{stream} + return x, nil +} + +type ConsumerService_SubscribeStreamClient interface { + Send(*Subscription) error + Recv() (*SimpleMessage, error) + grpc.ClientStream +} + +type consumerServiceSubscribeStreamClient struct { + grpc.ClientStream +} + +func (x *consumerServiceSubscribeStreamClient) Send(m *Subscription) error { + return x.ClientStream.SendMsg(m) +} + +func (x *consumerServiceSubscribeStreamClient) Recv() (*SimpleMessage, error) { + m := new(SimpleMessage) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *consumerServiceClient) Unsubscribe(ctx context.Context, in *Subscription, opts ...grpc.CallOption) (*Response, error) { + out := new(Response) + err := c.cc.Invoke(ctx, "/eventmesh.common.protocol.grpc.ConsumerService/unsubscribe", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ConsumerServiceServer is the server API for ConsumerService service. +// All implementations must embed UnimplementedConsumerServiceServer +// for forward compatibility +type ConsumerServiceServer interface { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + Subscribe(context.Context, *Subscription) (*Response, error) + // The subscribed event will be delivered through stream of Message + SubscribeStream(ConsumerService_SubscribeStreamServer) error + Unsubscribe(context.Context, *Subscription) (*Response, error) + mustEmbedUnimplementedConsumerServiceServer() +} + +// UnimplementedConsumerServiceServer must be embedded to have forward compatible implementations. +type UnimplementedConsumerServiceServer struct { +} + +func (UnimplementedConsumerServiceServer) Subscribe(context.Context, *Subscription) (*Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method Subscribe not implemented") +} +func (UnimplementedConsumerServiceServer) SubscribeStream(ConsumerService_SubscribeStreamServer) error { + return status.Errorf(codes.Unimplemented, "method SubscribeStream not implemented") +} +func (UnimplementedConsumerServiceServer) Unsubscribe(context.Context, *Subscription) (*Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method Unsubscribe not implemented") +} +func (UnimplementedConsumerServiceServer) mustEmbedUnimplementedConsumerServiceServer() {} + +// UnsafeConsumerServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ConsumerServiceServer will +// result in compilation errors. +type UnsafeConsumerServiceServer interface { + mustEmbedUnimplementedConsumerServiceServer() +} + +func RegisterConsumerServiceServer(s grpc.ServiceRegistrar, srv ConsumerServiceServer) { + s.RegisterService(&ConsumerService_ServiceDesc, srv) +} + +func _ConsumerService_Subscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Subscription) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConsumerServiceServer).Subscribe(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/eventmesh.common.protocol.grpc.ConsumerService/subscribe", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConsumerServiceServer).Subscribe(ctx, req.(*Subscription)) + } + return interceptor(ctx, in, info, handler) +} + +func _ConsumerService_SubscribeStream_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ConsumerServiceServer).SubscribeStream(&consumerServiceSubscribeStreamServer{stream}) +} + +type ConsumerService_SubscribeStreamServer interface { + Send(*SimpleMessage) error + Recv() (*Subscription, error) + grpc.ServerStream +} + +type consumerServiceSubscribeStreamServer struct { + grpc.ServerStream +} + +func (x *consumerServiceSubscribeStreamServer) Send(m *SimpleMessage) error { + return x.ServerStream.SendMsg(m) +} + +func (x *consumerServiceSubscribeStreamServer) Recv() (*Subscription, error) { + m := new(Subscription) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _ConsumerService_Unsubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Subscription) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConsumerServiceServer).Unsubscribe(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/eventmesh.common.protocol.grpc.ConsumerService/unsubscribe", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConsumerServiceServer).Unsubscribe(ctx, req.(*Subscription)) + } + return interceptor(ctx, in, info, handler) +} + +// ConsumerService_ServiceDesc is the grpc.ServiceDesc for ConsumerService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ConsumerService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "eventmesh.common.protocol.grpc.ConsumerService", + HandlerType: (*ConsumerServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "subscribe", + Handler: _ConsumerService_Subscribe_Handler, + }, + { + MethodName: "unsubscribe", + Handler: _ConsumerService_Unsubscribe_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "subscribeStream", + Handler: _ConsumerService_SubscribeStream_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "eventmesh-client.proto", +} + +// HeartbeatServiceClient is the client API for HeartbeatService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type HeartbeatServiceClient interface { + Heartbeat(ctx context.Context, in *Heartbeat, opts ...grpc.CallOption) (*Response, error) +} + +type heartbeatServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHeartbeatServiceClient(cc grpc.ClientConnInterface) HeartbeatServiceClient { + return &heartbeatServiceClient{cc} +} + +func (c *heartbeatServiceClient) Heartbeat(ctx context.Context, in *Heartbeat, opts ...grpc.CallOption) (*Response, error) { + out := new(Response) + err := c.cc.Invoke(ctx, "/eventmesh.common.protocol.grpc.HeartbeatService/heartbeat", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HeartbeatServiceServer is the server API for HeartbeatService service. +// All implementations must embed UnimplementedHeartbeatServiceServer +// for forward compatibility +type HeartbeatServiceServer interface { + Heartbeat(context.Context, *Heartbeat) (*Response, error) + mustEmbedUnimplementedHeartbeatServiceServer() +} + +// UnimplementedHeartbeatServiceServer must be embedded to have forward compatible implementations. +type UnimplementedHeartbeatServiceServer struct { +} + +func (UnimplementedHeartbeatServiceServer) Heartbeat(context.Context, *Heartbeat) (*Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method Heartbeat not implemented") +} +func (UnimplementedHeartbeatServiceServer) mustEmbedUnimplementedHeartbeatServiceServer() {} + +// UnsafeHeartbeatServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HeartbeatServiceServer will +// result in compilation errors. +type UnsafeHeartbeatServiceServer interface { + mustEmbedUnimplementedHeartbeatServiceServer() +} + +func RegisterHeartbeatServiceServer(s grpc.ServiceRegistrar, srv HeartbeatServiceServer) { + s.RegisterService(&HeartbeatService_ServiceDesc, srv) +} + +func _HeartbeatService_Heartbeat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Heartbeat) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HeartbeatServiceServer).Heartbeat(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/eventmesh.common.protocol.grpc.HeartbeatService/heartbeat", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HeartbeatServiceServer).Heartbeat(ctx, req.(*Heartbeat)) + } + return interceptor(ctx, in, info, handler) +} + +// HeartbeatService_ServiceDesc is the grpc.ServiceDesc for HeartbeatService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HeartbeatService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "eventmesh.common.protocol.grpc.HeartbeatService", + HandlerType: (*HeartbeatServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "heartbeat", + Handler: _HeartbeatService_Heartbeat_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "eventmesh-client.proto", +} diff --git a/eventmesh-sdk-go/grpc/protocol_type.go b/eventmesh-sdk-go/grpc/protocol_type.go new file mode 100644 index 0000000000..636d4cdb74 --- /dev/null +++ b/eventmesh-sdk-go/grpc/protocol_type.go @@ -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 grpc + +var ( + // EventmeshMessage eventmesh message protocol type + EventmeshMessage = "eventmeshmessage" + // cloudeventsMessage support later + cloudeventsMessage = "cloudevents" + // OpenMessage open message support later + OpenMessage = "openmessage" +) diff --git a/eventmesh-sdk-go/http/abstract_http_client.go b/eventmesh-sdk-go/http/abstract_http_client.go new file mode 100644 index 0000000000..2232d31130 --- /dev/null +++ b/eventmesh-sdk-go/http/abstract_http_client.go @@ -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 http + +import ( + gcommon "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/conf" + nethttp "net/http" + "time" +) + +type AbstractHttpClient struct { + EventMeshHttpClientConfig conf.EventMeshHttpClientConfig + HttpClient *nethttp.Client +} + +func NewAbstractHttpClient(eventMeshHttpClientConfig conf.EventMeshHttpClientConfig) *AbstractHttpClient { + c := &AbstractHttpClient{EventMeshHttpClientConfig: eventMeshHttpClientConfig} + c.HttpClient = c.SetHttpClient() + return c +} + +func (c *AbstractHttpClient) Close() { + // Http Client does not need to close explicitly +} + +func (c *AbstractHttpClient) SetHttpClient() *nethttp.Client { + if !c.EventMeshHttpClientConfig.UseTls() { + return &nethttp.Client{Timeout: 100 * time.Second} + } + + // Use TLS + return &nethttp.Client{Timeout: 100 * time.Second} +} + +func (c *AbstractHttpClient) SelectEventMesh() string { + // FIXME Add load balance support + uri := c.EventMeshHttpClientConfig.LiteEventMeshAddr() + + if c.EventMeshHttpClientConfig.UseTls() { + return gcommon.Constants.HTTPS_PROTOCOL_PREFIX + uri + } + + return gcommon.Constants.HTTP_PROTOCOL_PREFIX + uri +} diff --git a/eventmesh-sdk-go/http/conf/eventmesh_http_client_config.go b/eventmesh-sdk-go/http/conf/eventmesh_http_client_config.go new file mode 100644 index 0000000000..d0a232a103 --- /dev/null +++ b/eventmesh-sdk-go/http/conf/eventmesh_http_client_config.go @@ -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 conf + +type EventMeshHttpClientConfig struct { + //The event server address list + // If it's a cluster, please use ; to split, and the address format is related to loadBalanceType. + // E.g. + // If you use Random strategy, the format like: 127.0.0.1:10105;127.0.0.2:10105 + // If you use weighted round robin or weighted random strategy, the format like: 127.0.0.1:10105:1;127.0.0.2:10105:2 + liteEventMeshAddr string + // TODO support load balance + //loadBalanceType string + consumeThreadCore int + consumeThreadMax int + env string + consumerGroup string + producerGroup string + idc string + ip string + pid string + sys string + userName string + password string + useTls bool +} + +func (e *EventMeshHttpClientConfig) LiteEventMeshAddr() string { + return e.liteEventMeshAddr +} + +func (e *EventMeshHttpClientConfig) SetLiteEventMeshAddr(liteEventMeshAddr string) { + e.liteEventMeshAddr = liteEventMeshAddr +} + +func (e *EventMeshHttpClientConfig) ConsumeThreadCore() int { + return e.consumeThreadCore +} + +func (e *EventMeshHttpClientConfig) SetConsumeThreadCore(consumeThreadCore int) { + e.consumeThreadCore = consumeThreadCore +} + +func (e *EventMeshHttpClientConfig) ConsumeThreadMax() int { + return e.consumeThreadMax +} + +func (e *EventMeshHttpClientConfig) SetConsumeThreadMax(consumeThreadMax int) { + e.consumeThreadMax = consumeThreadMax +} + +func (e *EventMeshHttpClientConfig) Env() string { + return e.env +} + +func (e *EventMeshHttpClientConfig) SetEnv(env string) { + e.env = env +} + +func (e *EventMeshHttpClientConfig) ConsumerGroup() string { + return e.consumerGroup +} + +func (e *EventMeshHttpClientConfig) SetConsumerGroup(consumerGroup string) { + e.consumerGroup = consumerGroup +} + +func (e *EventMeshHttpClientConfig) ProducerGroup() string { + return e.producerGroup +} + +func (e *EventMeshHttpClientConfig) SetProducerGroup(producerGroup string) { + e.producerGroup = producerGroup +} + +func (e *EventMeshHttpClientConfig) Idc() string { + return e.idc +} + +func (e *EventMeshHttpClientConfig) SetIdc(idc string) { + e.idc = idc +} + +func (e *EventMeshHttpClientConfig) Ip() string { + return e.ip +} + +func (e *EventMeshHttpClientConfig) SetIp(ip string) { + e.ip = ip +} + +func (e *EventMeshHttpClientConfig) Pid() string { + return e.pid +} + +func (e *EventMeshHttpClientConfig) SetPid(pid string) { + e.pid = pid +} + +func (e *EventMeshHttpClientConfig) Sys() string { + return e.sys +} + +func (e *EventMeshHttpClientConfig) SetSys(sys string) { + e.sys = sys +} + +func (e *EventMeshHttpClientConfig) UserName() string { + return e.userName +} + +func (e *EventMeshHttpClientConfig) SetUserName(userName string) { + e.userName = userName +} + +func (e *EventMeshHttpClientConfig) Password() string { + return e.password +} + +func (e *EventMeshHttpClientConfig) SetPassword(password string) { + e.password = password +} + +func (e *EventMeshHttpClientConfig) UseTls() bool { + return e.useTls +} + +func (e *EventMeshHttpClientConfig) SetUseTls(useTls bool) { + e.useTls = useTls +} + +var DefaultEventMeshHttpClientConfig = EventMeshHttpClientConfig{ + liteEventMeshAddr: "127.0.0.1:10105", + consumeThreadCore: 2, + consumeThreadMax: 5, + env: "", + consumerGroup: "DefaultConsumerGroup", + producerGroup: "DefaultProducerGroup", + idc: "", + ip: "", + pid: "", + sys: "", + userName: "", + password: "", + useTls: false, +} diff --git a/eventmesh-sdk-go/http/consumer/eventmesh_http_consumer.go b/eventmesh-sdk-go/http/consumer/eventmesh_http_consumer.go new file mode 100644 index 0000000000..cbb26df6f6 --- /dev/null +++ b/eventmesh-sdk-go/http/consumer/eventmesh_http_consumer.go @@ -0,0 +1,110 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package consumer + +import ( + gcommon "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/http/body/client" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/http/common" + gutils "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/model" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + nethttp "net/http" + "strconv" + "time" +) + +type EventMeshHttpConsumer struct { + *http.AbstractHttpClient + subscriptions []protocol.SubscriptionItem +} + +func NewEventMeshHttpConsumer(eventMeshHttpClientConfig conf.EventMeshHttpClientConfig) *EventMeshHttpConsumer { + c := &EventMeshHttpConsumer{AbstractHttpClient: http.NewAbstractHttpClient(eventMeshHttpClientConfig)} + c.subscriptions = make([]protocol.SubscriptionItem, 1000) + return c +} + +func (e *EventMeshHttpConsumer) HeartBeat(topicList []protocol.SubscriptionItem, subscribeUrl string) { + + // FIXME check topicList, subscribeUrl is not blank + + for range time.Tick(time.Duration(gcommon.Constants.HEARTBEAT) * time.Millisecond) { + + var heartbeatEntities []client.HeartbeatEntity + for _, item := range topicList { + entity := client.HeartbeatEntity{Topic: item.Topic, Url: subscribeUrl} + heartbeatEntities = append(heartbeatEntities, entity) + } + + requestParam := e.buildCommonRequestParam() + requestParam.AddHeader(common.ProtocolKey.REQUEST_CODE, strconv.Itoa(common.DefaultRequestCode.HEARTBEAT.RequestCode)) + // FIXME Java is name of SUB name + //requestParam.AddBody(client.HeartbeatRequestBodyKey.CLIENTTYPE, common.DefaultClientType.SUB.name()) + requestParam.AddBody(client.HeartbeatRequestBodyKey.CLIENTTYPE, "SUB") + requestParam.AddBody(client.HeartbeatRequestBodyKey.HEARTBEATENTITIES, gutils.MarshalJsonString(heartbeatEntities)) + + target := e.SelectEventMesh() + resp := utils.HttpPost(e.HttpClient, target, requestParam) + var ret http.EventMeshRetObj + gutils.UnMarshalJsonString(resp, &ret) + if ret.RetCode != common.DefaultEventMeshRetCode.SUCCESS.RetCode { + log.Fatalf("Request failed, error code: %d", ret.RetCode) + } + + } + +} + +func (e *EventMeshHttpConsumer) Subscribe(topicList []protocol.SubscriptionItem, subscribeUrl string) { + + // FIXME check topicList, subscribeUrl is not blank + + requestParam := e.buildCommonRequestParam() + requestParam.AddHeader(common.ProtocolKey.REQUEST_CODE, strconv.Itoa(common.DefaultRequestCode.SUBSCRIBE.RequestCode)) + requestParam.AddBody(client.SubscribeRequestBodyKey.TOPIC, gutils.MarshalJsonString(topicList)) + requestParam.AddBody(client.SubscribeRequestBodyKey.URL, subscribeUrl) + requestParam.AddBody(client.SubscribeRequestBodyKey.CONSUMERGROUP, e.EventMeshHttpClientConfig.ConsumerGroup()) + + target := e.SelectEventMesh() + resp := utils.HttpPost(e.HttpClient, target, requestParam) + var ret http.EventMeshRetObj + gutils.UnMarshalJsonString(resp, &ret) + if ret.RetCode != common.DefaultEventMeshRetCode.SUCCESS.RetCode { + log.Fatalf("Request failed, error code: %d", ret.RetCode) + } + e.subscriptions = append(e.subscriptions, topicList...) +} + +func (e *EventMeshHttpConsumer) buildCommonRequestParam() *model.RequestParam { + param := model.NewRequestParam(nethttp.MethodPost) + param.AddHeader(common.ProtocolKey.ClientInstanceKey.ENV, e.EventMeshHttpClientConfig.Env()) + param.AddHeader(common.ProtocolKey.ClientInstanceKey.IDC, e.EventMeshHttpClientConfig.Idc()) + param.AddHeader(common.ProtocolKey.ClientInstanceKey.IP, e.EventMeshHttpClientConfig.Ip()) + param.AddHeader(common.ProtocolKey.ClientInstanceKey.PID, e.EventMeshHttpClientConfig.Pid()) + param.AddHeader(common.ProtocolKey.ClientInstanceKey.SYS, e.EventMeshHttpClientConfig.Sys()) + param.AddHeader(common.ProtocolKey.ClientInstanceKey.USERNAME, e.EventMeshHttpClientConfig.UserName()) + param.AddHeader(common.ProtocolKey.ClientInstanceKey.PASSWORD, e.EventMeshHttpClientConfig.Password()) + param.AddHeader(common.ProtocolKey.VERSION, common.DefaultProtocolVersion.V1.Version()) + param.AddHeader(common.ProtocolKey.LANGUAGE, gcommon.Constants.LANGUAGE_GO) + param.SetTimeout(gcommon.Constants.DEFAULT_HTTP_TIME_OUT) + param.AddBody(client.HeartbeatRequestBodyKey.CONSUMERGROUP, e.EventMeshHttpClientConfig.ConsumerGroup()) + return param +} diff --git a/eventmesh-sdk-go/http/eventmesh_ret_obj.go b/eventmesh-sdk-go/http/eventmesh_ret_obj.go new file mode 100644 index 0000000000..b92113cf0d --- /dev/null +++ b/eventmesh-sdk-go/http/eventmesh_ret_obj.go @@ -0,0 +1,22 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package http + +type EventMeshRetObj struct { + ResTime int64 `json:"resTime"` + RetCode int `json:"retCode"` + RetMsg string `json:"retMsg"` +} diff --git a/eventmesh-sdk-go/http/model/request_param.go b/eventmesh-sdk-go/http/model/request_param.go new file mode 100644 index 0000000000..1606aea9c5 --- /dev/null +++ b/eventmesh-sdk-go/http/model/request_param.go @@ -0,0 +1,68 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +type HttpMethod string + +type RequestParam struct { + queryParams map[string][]string + httpMethod HttpMethod + body map[string]string + headers map[string]string + timeout int64 +} + +func NewRequestParam(httpMethod HttpMethod) *RequestParam { + return &RequestParam{httpMethod: httpMethod} +} + +func (r *RequestParam) QueryParams() map[string][]string { + return r.queryParams +} + +func (r *RequestParam) SetQueryParams(queryParams map[string][]string) { + r.queryParams = queryParams +} + +func (r *RequestParam) Body() map[string]string { + return r.body +} + +func (r *RequestParam) AddBody(key, value string) { + if r.body == nil { + r.body = make(map[string]string) + } + r.body[key] = value +} + +func (r *RequestParam) Headers() map[string]string { + return r.headers +} + +func (r *RequestParam) AddHeader(key string, object interface{}) { + if r.headers == nil { + r.headers = make(map[string]string) + } + r.headers[key] = object.(string) +} + +func (r *RequestParam) Timeout() int64 { + return r.timeout +} + +func (r *RequestParam) SetTimeout(timeout int64) { + r.timeout = timeout +} diff --git a/eventmesh-sdk-go/http/producer/cloudevent_producer.go b/eventmesh-sdk-go/http/producer/cloudevent_producer.go new file mode 100644 index 0000000000..815e665875 --- /dev/null +++ b/eventmesh-sdk-go/http/producer/cloudevent_producer.go @@ -0,0 +1,101 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package producer + +import ( + gcommon "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/http/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/http/message" + gutils "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/model" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/utils" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + cloudevents "github.com/cloudevents/sdk-go/v2" + + nethttp "net/http" + "strconv" +) + +type CloudEventProducer struct { + *http.AbstractHttpClient +} + +func NewCloudEventProducer(eventMeshHttpClientConfig conf.EventMeshHttpClientConfig) *CloudEventProducer { + c := &CloudEventProducer{AbstractHttpClient: http.NewAbstractHttpClient(eventMeshHttpClientConfig)} + return c +} + +func (c *CloudEventProducer) Publish(event cloudevents.Event) { + enhancedEvent := c.enhanceCloudEvent(event) + requestParam := c.buildCommonPostParam(enhancedEvent) + requestParam.AddHeader(common.ProtocolKey.REQUEST_CODE, strconv.Itoa(common.DefaultRequestCode.MSG_SEND_ASYNC.RequestCode)) + + target := c.SelectEventMesh() + resp := utils.HttpPost(c.HttpClient, target, requestParam) + var ret http.EventMeshRetObj + gutils.UnMarshalJsonString(resp, &ret) + if ret.RetCode != common.DefaultEventMeshRetCode.SUCCESS.RetCode { + log.Fatalf("Request failed, error code: %d", ret.RetCode) + } +} + +func (c *CloudEventProducer) buildCommonPostParam(event cloudevents.Event) *model.RequestParam { + + eventBytes, err := event.MarshalJSON() + if err != nil { + log.Fatalf("Failed to marshal cloudevent") + } + content := string(eventBytes) + + requestParam := model.NewRequestParam(nethttp.MethodPost) + requestParam.AddHeader(common.ProtocolKey.ClientInstanceKey.ENV, c.EventMeshHttpClientConfig.Env()) + requestParam.AddHeader(common.ProtocolKey.ClientInstanceKey.IDC, c.EventMeshHttpClientConfig.Idc()) + requestParam.AddHeader(common.ProtocolKey.ClientInstanceKey.IP, c.EventMeshHttpClientConfig.Ip()) + requestParam.AddHeader(common.ProtocolKey.ClientInstanceKey.PID, c.EventMeshHttpClientConfig.Pid()) + requestParam.AddHeader(common.ProtocolKey.ClientInstanceKey.SYS, c.EventMeshHttpClientConfig.Sys()) + requestParam.AddHeader(common.ProtocolKey.ClientInstanceKey.USERNAME, c.EventMeshHttpClientConfig.UserName()) + requestParam.AddHeader(common.ProtocolKey.ClientInstanceKey.PASSWORD, c.EventMeshHttpClientConfig.Password()) + requestParam.AddHeader(common.ProtocolKey.LANGUAGE, gcommon.Constants.LANGUAGE_GO) + // FIXME Improve constants + requestParam.AddHeader(common.ProtocolKey.PROTOCOL_TYPE, "cloudevents") + requestParam.AddHeader(common.ProtocolKey.PROTOCOL_DESC, "http") + requestParam.AddHeader(common.ProtocolKey.PROTOCOL_VERSION, event.SpecVersion()) + + // todo: move producerGroup tp header + requestParam.AddBody(message.SendMessageRequestBodyKey.PRODUCERGROUP, c.EventMeshHttpClientConfig.ProducerGroup()) + requestParam.AddBody(message.SendMessageRequestBodyKey.CONTENT, content) + + return requestParam +} + +func (c *CloudEventProducer) enhanceCloudEvent(event cloudevents.Event) cloudevents.Event { + event.SetExtension(common.ProtocolKey.ClientInstanceKey.ENV, c.EventMeshHttpClientConfig.Env()) + event.SetExtension(common.ProtocolKey.ClientInstanceKey.IDC, c.EventMeshHttpClientConfig.Idc()) + event.SetExtension(common.ProtocolKey.ClientInstanceKey.IP, c.EventMeshHttpClientConfig.Ip()) + event.SetExtension(common.ProtocolKey.ClientInstanceKey.PID, c.EventMeshHttpClientConfig.Pid()) + event.SetExtension(common.ProtocolKey.ClientInstanceKey.SYS, c.EventMeshHttpClientConfig.Sys()) + // FIXME Random string + event.SetExtension(common.ProtocolKey.ClientInstanceKey.BIZSEQNO, "333333") + event.SetExtension(common.ProtocolKey.ClientInstanceKey.UNIQUEID, "444444") + event.SetExtension(common.ProtocolKey.LANGUAGE, gcommon.Constants.LANGUAGE_GO) + // FIXME Java is name of spec version name + //event.SetExtension(common.ProtocolKey.PROTOCOL_DESC, event.SpecVersion()) + event.SetExtension(common.ProtocolKey.PROTOCOL_VERSION, event.SpecVersion()) + + return event +} diff --git a/eventmesh-sdk-go/http/producer/eventmesh_http_producer.go b/eventmesh-sdk-go/http/producer/eventmesh_http_producer.go new file mode 100644 index 0000000000..e4eb3c43dd --- /dev/null +++ b/eventmesh-sdk-go/http/producer/eventmesh_http_producer.go @@ -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 producer + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/conf" + cloudevents "github.com/cloudevents/sdk-go/v2" +) + +type EventMeshHttpProducer struct { + cloudEventProducer *CloudEventProducer +} + +func NewEventMeshHttpProducer(eventMeshHttpClientConfig conf.EventMeshHttpClientConfig) *EventMeshHttpProducer { + return &EventMeshHttpProducer{ + cloudEventProducer: NewCloudEventProducer(eventMeshHttpClientConfig), + } +} + +func (e *EventMeshHttpProducer) Publish(eventMeshMessage interface{}) { + + // FIXME Check eventMeshMessage is not nil + + // CloudEvent + if _, ok := eventMeshMessage.(cloudevents.Event); ok { + event := eventMeshMessage.(cloudevents.Event) + e.cloudEventProducer.Publish(event) + } +} diff --git a/eventmesh-sdk-go/http/producer/eventmesh_protocol_producer.go b/eventmesh-sdk-go/http/producer/eventmesh_protocol_producer.go new file mode 100644 index 0000000000..de56476b75 --- /dev/null +++ b/eventmesh-sdk-go/http/producer/eventmesh_protocol_producer.go @@ -0,0 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package producer + +type EventMeshProtocolProducer interface { + Publish(eventMeshMessage interface{}) +} diff --git a/eventmesh-sdk-go/http/utils/http_utils.go b/eventmesh-sdk-go/http/utils/http_utils.go new file mode 100644 index 0000000000..e11913271b --- /dev/null +++ b/eventmesh-sdk-go/http/utils/http_utils.go @@ -0,0 +1,56 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/http/model" + "io/ioutil" + nethttp "net/http" + "net/url" + "strings" +) + +func HttpPost(client *nethttp.Client, uri string, requestParam *model.RequestParam) string { + + data := url.Values{} + body := requestParam.Body() + for key := range body { + data.Set(key, body[key]) + } + + req, err := nethttp.NewRequest(nethttp.MethodPost, uri, strings.NewReader(data.Encode())) + if err != nil { + } + + req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") + + headers := requestParam.Headers() + for header := range headers { + req.Header[header] = []string{headers[header]} + } + + resp, err := client.Do(req) + if err != nil { + } + + defer resp.Body.Close() + + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + } + + return string(respBody) +} diff --git a/eventmesh-sdk-go/log/logger.go b/eventmesh-sdk-go/log/logger.go new file mode 100644 index 0000000000..e500511dcf --- /dev/null +++ b/eventmesh-sdk-go/log/logger.go @@ -0,0 +1,163 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package log + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "time" +) + +var ( + // _defaultLogger global log instance, default to zap.log + _defaultLogger Logger = &DefaultLogger{ + SugaredLogger: func() *zap.SugaredLogger { + encoder := zapcore.EncoderConfig{ + TimeKey: "ts", + LevelKey: "level", + NameKey: "logger", + CallerKey: "caller", + MessageKey: "msg", + StacktraceKey: "stacktrace", + LineEnding: zapcore.DefaultLineEnding, + EncodeLevel: zapcore.CapitalLevelEncoder, + EncodeTime: func(time time.Time, encoder zapcore.PrimitiveArrayEncoder) { + encoder.AppendString(time.Format("2006-01-02 15:04:05.000")) + }, + EncodeDuration: zapcore.SecondsDurationEncoder, + EncodeCaller: zapcore.ShortCallerEncoder, + } + l, _ := zap.Config{ + Level: zap.NewAtomicLevelAt(zap.InfoLevel), + Development: false, + Sampling: &zap.SamplingConfig{ + Initial: 100, + Thereafter: 100, + }, + Encoding: "console", + EncoderConfig: encoder, + OutputPaths: []string{"stderr"}, + ErrorOutputPaths: []string{"stderr"}, + }.Build([]zap.Option{zap.AddCallerSkip(2)}...) + return l.Sugar() + }(), + } +) + +// SetLogger set the log +func SetLogger(l Logger) { + _defaultLogger = l +} + +func Debugf(template string, args ...interface{}) { + _defaultLogger.Debugf(template, args...) +} + +func Infof(template string, args ...interface{}) { + _defaultLogger.Infof(template, args...) +} + +// Warnf uses fmt.Sprintf to log a templated message. +func Warnf(template string, args ...interface{}) { + _defaultLogger.Warnf(template, args...) +} + +// Errorf uses fmt.Sprintf to log a templated message. +func Errorf(template string, args ...interface{}) { + _defaultLogger.Errorf(template, args...) +} + +// DPanicf uses fmt.Sprintf to log a templated message. In development, the +// log then panics. (See DPanicLevel for details.) +func DPanicf(template string, args ...interface{}) { + _defaultLogger.DPanicf(template, args...) +} + +// Panicf uses fmt.Sprintf to log a templated message, then panics. +func Panicf(template string, args ...interface{}) { + _defaultLogger.Panicf(template, args...) +} + +// Fatalf uses fmt.Sprintf to log a templated message, then calls os.Exit. +func Fatalf(template string, args ...interface{}) { + _defaultLogger.Fatalf(template, args...) +} + +// Logger define the log api for eventmesh +type Logger interface { + // Debugf uses fmt.Sprintf to log a templated message. + // DebugLevel logs are typically voluminous, and are usually disabled in + // production. + Debugf(template string, args ...interface{}) + + // Infof uses fmt.Sprintf to log a templated message. + // InfoLevel is the default logging priority. + Infof(template string, args ...interface{}) + + // Warnf uses fmt.Sprintf to log a templated message. + // WarnLevel logs are more important than Info, but don't need individual + // human review. + Warnf(template string, args ...interface{}) + + // Errorf uses fmt.Sprintf to log a templated message. + // ErrorLevel logs are high-priority. If an application is running smoothly, + // it shouldn't generate any error-level logs. + Errorf(template string, args ...interface{}) + + // DPanicf uses fmt.Sprintf to log a templated message. In development, the + // DPanicLevel logs are particularly important errors. In development the + // log panics after writing the message. + DPanicf(template string, args ...interface{}) + + // Panicf uses fmt.Sprintf to log a templated message, then panics. + Panicf(template string, args ...interface{}) + + // Fatalf uses fmt.Sprintf to log a templated message, then calls os.Exit. + Fatalf(template string, args ...interface{}) +} + +// DefaultLogger write log by zap log +type DefaultLogger struct { + *zap.SugaredLogger +} + +func (s *DefaultLogger) Debugf(template string, args ...interface{}) { + s.SugaredLogger.Debugf(template, args...) +} + +func (s *DefaultLogger) Infof(template string, args ...interface{}) { + s.SugaredLogger.Infof(template, args...) +} + +func (s *DefaultLogger) Warnf(template string, args ...interface{}) { + s.SugaredLogger.Warnf(template, args...) +} + +func (s *DefaultLogger) Errorf(template string, args ...interface{}) { + s.SugaredLogger.Errorf(template, args...) +} + +func (s *DefaultLogger) DPanicf(template string, args ...interface{}) { + s.SugaredLogger.DPanicf(template, args...) +} + +func (s *DefaultLogger) Panicf(template string, args ...interface{}) { + s.SugaredLogger.Panicf(template, args...) +} + +func (s *DefaultLogger) Fatalf(template string, args ...interface{}) { + s.SugaredLogger.Fatalf(template, args...) +} diff --git a/eventmesh-sdk-go/tcp/cloudevent_tcp_client.go b/eventmesh-sdk-go/tcp/cloudevent_tcp_client.go new file mode 100644 index 0000000000..b868f04ecb --- /dev/null +++ b/eventmesh-sdk-go/tcp/cloudevent_tcp_client.go @@ -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 tcp + +import ( + gtcp "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/conf" +) + +type CloudEventTCPClient struct { + cloudEventTCPPubClient *CloudEventTCPPubClient + cloudEventTCPSubClient *CloudEventTCPSubClient +} + +func NewCloudEventTCPClient(eventMeshTcpClientConfig conf.EventMeshTCPClientConfig) *CloudEventTCPClient { + return &CloudEventTCPClient{ + cloudEventTCPPubClient: NewCloudEventTCPPubClient(eventMeshTcpClientConfig), + cloudEventTCPSubClient: NewCloudEventTCPSubClient(eventMeshTcpClientConfig), + } +} + +func (c *CloudEventTCPClient) Init() { + c.cloudEventTCPPubClient.init() + c.cloudEventTCPSubClient.init() +} + +func (c *CloudEventTCPClient) Publish(message interface{}, timeout int64) gtcp.Package { + return c.cloudEventTCPPubClient.publish(message, timeout) +} + +func (c *CloudEventTCPClient) GetPubClient() EventMeshTCPPubClient { + return c.cloudEventTCPPubClient +} + +func (c *CloudEventTCPClient) GetSubClient() EventMeshTCPSubClient { + return c.cloudEventTCPSubClient +} diff --git a/eventmesh-sdk-go/tcp/cloudevent_tcp_pub_client.go b/eventmesh-sdk-go/tcp/cloudevent_tcp_pub_client.go new file mode 100644 index 0000000000..b2a793a172 --- /dev/null +++ b/eventmesh-sdk-go/tcp/cloudevent_tcp_pub_client.go @@ -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 tcp + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/utils" +) + +type CloudEventTCPPubClient struct { + *BaseTCPClient +} + +func NewCloudEventTCPPubClient(eventMeshTcpClientConfig conf.EventMeshTCPClientConfig) *CloudEventTCPPubClient { + return &CloudEventTCPPubClient{BaseTCPClient: NewBaseTCPClient(eventMeshTcpClientConfig)} +} + +func (c CloudEventTCPPubClient) init() { + c.Open() + c.Hello() + c.Heartbeat() +} + +func (c CloudEventTCPPubClient) reconnect() { + c.Reconnect() + c.Heartbeat() +} + +func (c CloudEventTCPPubClient) publish(message interface{}, timeout int64) tcp.Package { + msg := utils.BuildPackage(message, tcp.DefaultCommand.ASYNC_MESSAGE_TO_SERVER) + return c.IO(msg, timeout) +} diff --git a/eventmesh-sdk-go/tcp/cloudevent_tcp_sub_client.go b/eventmesh-sdk-go/tcp/cloudevent_tcp_sub_client.go new file mode 100644 index 0000000000..813cb595db --- /dev/null +++ b/eventmesh-sdk-go/tcp/cloudevent_tcp_sub_client.go @@ -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 tcp + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/conf" +) + +type CloudEventTCPSubClient struct { + *BaseTCPClient +} + +func NewCloudEventTCPSubClient(eventMeshTcpClientConfig conf.EventMeshTCPClientConfig) *CloudEventTCPSubClient { + return &CloudEventTCPSubClient{BaseTCPClient: NewBaseTCPClient(eventMeshTcpClientConfig)} +} + +func (c CloudEventTCPSubClient) init() { + //panic("implement me") +} + +func (c CloudEventTCPSubClient) subscribe(topic string, subscriptionMode protocol.SubscriptionMode, subscriptionType protocol.SubscriptionType) { + panic("implement me") +} + +func (c CloudEventTCPSubClient) unsubscribe() { + panic("implement me") +} diff --git a/eventmesh-sdk-go/tcp/common/eventmesh_common.go b/eventmesh-sdk-go/tcp/common/eventmesh_common.go new file mode 100644 index 0000000000..39efb28864 --- /dev/null +++ b/eventmesh-sdk-go/tcp/common/eventmesh_common.go @@ -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 common + +var EventMeshCommon = struct { + // Timeout time shared by the server + DEFAULT_TIME_OUT_MILLS int + + // User agent + USER_AGENT_PURPOSE_PUB string + USER_AGENT_PURPOSE_SUB string + + // Protocol type + CLOUD_EVENTS_PROTOCOL_NAME string + EM_MESSAGE_PROTOCOL_NAME string + OPEN_MESSAGE_PROTOCOL_NAME string +}{ + DEFAULT_TIME_OUT_MILLS: 20 * 1000, + USER_AGENT_PURPOSE_PUB: "pub", + USER_AGENT_PURPOSE_SUB: "sub", + CLOUD_EVENTS_PROTOCOL_NAME: "cloudevents", + EM_MESSAGE_PROTOCOL_NAME: "eventmeshmessage", + OPEN_MESSAGE_PROTOCOL_NAME: "openmessage", +} diff --git a/eventmesh-sdk-go/tcp/common/request_context.go b/eventmesh-sdk-go/tcp/common/request_context.go new file mode 100644 index 0000000000..0b67ab26f6 --- /dev/null +++ b/eventmesh-sdk-go/tcp/common/request_context.go @@ -0,0 +1,75 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + "sync" +) + +type RequestContext struct { + key interface{} + request tcp.Package + response tcp.Package + wg sync.WaitGroup +} + +func (r *RequestContext) Key() interface{} { + return r.key +} + +func (r *RequestContext) SetKey(key interface{}) { + r.key = key +} + +func (r *RequestContext) Request() tcp.Package { + return r.request +} + +func (r *RequestContext) SetRequest(request tcp.Package) { + r.request = request +} + +func (r *RequestContext) Response() tcp.Package { + return r.response +} + +func (r *RequestContext) SetResponse(response tcp.Package) { + r.response = response +} + +func (r *RequestContext) Wg() sync.WaitGroup { + return r.wg +} + +func (r *RequestContext) SetWg(wg sync.WaitGroup) { + r.wg = wg +} + +func (r *RequestContext) Finish(message tcp.Package) { + r.response = message + //r.wg.Done() +} + +func GetRequestContextKey(request tcp.Package) interface{} { + return request.Header.Seq +} + +func NewRequestContext(key interface{}, request tcp.Package, latch int) *RequestContext { + ctx := &RequestContext{key: key, request: request} + //ctx.Wg().Add(latch) + return ctx +} diff --git a/eventmesh-sdk-go/tcp/conf/eventmesh_tcp_client_config.go b/eventmesh-sdk-go/tcp/conf/eventmesh_tcp_client_config.go new file mode 100644 index 0000000000..9cf5dd5a1f --- /dev/null +++ b/eventmesh-sdk-go/tcp/conf/eventmesh_tcp_client_config.go @@ -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 conf + +import "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + +type EventMeshTCPClientConfig struct { + host string + port int + userAgent tcp.UserAgent +} + +func NewEventMeshTCPClientConfig(host string, port int, userAgent tcp.UserAgent) *EventMeshTCPClientConfig { + return &EventMeshTCPClientConfig{host: host, port: port, userAgent: userAgent} +} + +func (e *EventMeshTCPClientConfig) Host() string { + return e.host +} + +func (e *EventMeshTCPClientConfig) SetHost(host string) { + e.host = host +} + +func (e *EventMeshTCPClientConfig) Port() int { + return e.port +} + +func (e *EventMeshTCPClientConfig) SetPort(port int) { + e.port = port +} + +func (e *EventMeshTCPClientConfig) UserAgent() tcp.UserAgent { + return e.userAgent +} + +func (e *EventMeshTCPClientConfig) SetUserAgent(userAgent tcp.UserAgent) { + e.userAgent = userAgent +} diff --git a/eventmesh-sdk-go/tcp/eventmesh_tcp_client.go b/eventmesh-sdk-go/tcp/eventmesh_tcp_client.go new file mode 100644 index 0000000000..0a7c589159 --- /dev/null +++ b/eventmesh-sdk-go/tcp/eventmesh_tcp_client.go @@ -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 tcp + +import gtcp "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + +type EventMeshTCPClient interface { + Init() + Publish(msg interface{}, timeout int64) gtcp.Package + GetPubClient() EventMeshTCPPubClient + GetSubClient() EventMeshTCPSubClient +} diff --git a/eventmesh-sdk-go/tcp/eventmesh_tcp_client_factory.go b/eventmesh-sdk-go/tcp/eventmesh_tcp_client_factory.go new file mode 100644 index 0000000000..7256c87f60 --- /dev/null +++ b/eventmesh-sdk-go/tcp/eventmesh_tcp_client_factory.go @@ -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 tcp + +import ( + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/conf" +) + +func CreateEventMeshTCPClient(eventMeshTcpClientConfig conf.EventMeshTCPClientConfig, messageType protocol.MessageType) EventMeshTCPClient { + + if messageType == protocol.DefaultMessageType.CloudEvent { + return NewCloudEventTCPClient(eventMeshTcpClientConfig) + } + + return nil +} diff --git a/eventmesh-sdk-go/tcp/eventmesh_tcp_pub_client.go b/eventmesh-sdk-go/tcp/eventmesh_tcp_pub_client.go new file mode 100644 index 0000000000..6dd0bc47a3 --- /dev/null +++ b/eventmesh-sdk-go/tcp/eventmesh_tcp_pub_client.go @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp + +import gtcp "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + +type EventMeshTCPPubClient interface { + init() + reconnect() + publish(message interface{}, timeout int64) gtcp.Package +} diff --git a/eventmesh-sdk-go/tcp/eventmesh_tcp_sub_client.go b/eventmesh-sdk-go/tcp/eventmesh_tcp_sub_client.go new file mode 100644 index 0000000000..98be7bba2f --- /dev/null +++ b/eventmesh-sdk-go/tcp/eventmesh_tcp_sub_client.go @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp + +import "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol" + +type EventMeshTCPSubClient interface { + init() + subscribe(topic string, subscriptionMode protocol.SubscriptionMode, subscriptionType protocol.SubscriptionType) + unsubscribe() +} diff --git a/eventmesh-sdk-go/tcp/tcp_client.go b/eventmesh-sdk-go/tcp/tcp_client.go new file mode 100644 index 0000000000..afd6342b2d --- /dev/null +++ b/eventmesh-sdk-go/tcp/tcp_client.go @@ -0,0 +1,145 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcp + +import ( + "bufio" + "bytes" + "io" + "math/rand" + "net" + "strconv" + + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp/codec" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/conf" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/utils" +) + +type BaseTCPClient struct { + clientNo int + host string + port int + useAgent tcp.UserAgent + conn net.Conn +} + +func NewBaseTCPClient(eventMeshTcpClientConfig conf.EventMeshTCPClientConfig) *BaseTCPClient { + return &BaseTCPClient{ + clientNo: rand.Intn(10000), + host: eventMeshTcpClientConfig.Host(), + port: eventMeshTcpClientConfig.Port(), + useAgent: eventMeshTcpClientConfig.UserAgent(), + } +} + +func (c *BaseTCPClient) Open() { + eventMeshIpAndPort := c.host + ":" + strconv.Itoa(c.port) + conn, err := net.Dial("tcp", eventMeshIpAndPort) + if err != nil { + log.Errorf("Failed to dial") + } + c.conn = conn + + go c.read() +} + +func (c *BaseTCPClient) Close() { + if c.conn != nil { + err := c.conn.Close() + if err != nil { + log.Errorf("Failed to close connection") + } + c.Goodbye() + } +} + +func (c *BaseTCPClient) Heartbeat() { + msg := utils.BuildHeartBeatPackage() + c.IO(msg, 1000) +} + +func (c *BaseTCPClient) Hello() { + msg := utils.BuildHelloPackage(c.useAgent) + c.IO(msg, 1000) +} + +func (c *BaseTCPClient) Reconnect() { + +} + +func (c *BaseTCPClient) Goodbye() { + +} + +func (c *BaseTCPClient) IsActive() { + +} + +func (c *BaseTCPClient) read() error { + for { + var buf bytes.Buffer + for { + reader := bufio.NewReader(c.conn) + msg, isPrefix, err := reader.ReadLine() + if err != nil { + if err == io.EOF { + break + } + return err + } + + buf.Write(msg) + if !isPrefix { + break + } + } + + go c.handleRead(&buf) + } +} + +func (c *BaseTCPClient) handleRead(in *bytes.Buffer) { + decoded := codec.DecodePackage(in) + log.Panicf("Read from server: %v", decoded) + // TODO Handle according to the command +} + +func (c *BaseTCPClient) write(message []byte) (int, error) { + writer := bufio.NewWriter(c.conn) + n, err := writer.Write(message) + if err == nil { + err = writer.Flush() + } + return n, err +} + +func (c *BaseTCPClient) Send(message tcp.Package) { + out := codec.EncodePackage(message) + _, err := c.write(out.Bytes()) + if err != nil { + log.Fatalf("Failed to write to peer") + } +} + +func (c *BaseTCPClient) IO(message tcp.Package, timeout int64) tcp.Package { + key := common.GetRequestContextKey(message) + ctx := common.NewRequestContext(key, message, 1) + c.Send(message) + return ctx.Response() +} diff --git a/eventmesh-sdk-go/tcp/utils/message_utils.go b/eventmesh-sdk-go/tcp/utils/message_utils.go new file mode 100644 index 0000000000..7a8a7cd098 --- /dev/null +++ b/eventmesh-sdk-go/tcp/utils/message_utils.go @@ -0,0 +1,60 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + gcommon "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/common/protocol/tcp" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/log" + "github.com/apache/incubator-eventmesh/eventmesh-sdk-go/tcp/common" + cloudevents "github.com/cloudevents/sdk-go/v2" +) + +func BuildPackage(message interface{}, command tcp.Command) tcp.Package { + // FIXME Support random sequence + header := tcp.NewHeader(command, 0, "", "22222") + pkg := tcp.NewPackage(header) + + if _, ok := message.(cloudevents.Event); ok { + event := message.(cloudevents.Event) + eventBytes, err := event.MarshalJSON() + if err != nil { + log.Fatalf("Failed to marshal cloud event") + } + + pkg.Header.PutProperty(gcommon.Constants.PROTOCOL_TYPE, common.EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + pkg.Header.PutProperty(gcommon.Constants.PROTOCOL_VERSION, event.SpecVersion()) + pkg.Header.PutProperty(gcommon.Constants.PROTOCOL_DESC, "tcp") + pkg.Body = eventBytes + } + + return pkg +} + +func BuildHelloPackage(agent tcp.UserAgent) tcp.Package { + // FIXME Support random sequence + header := tcp.NewHeader(tcp.DefaultCommand.HELLO_REQUEST, 0, "", "22222") + msg := tcp.NewPackage(header) + msg.Body = agent + return msg +} + +func BuildHeartBeatPackage() tcp.Package { + // FIXME Support random sequence + header := tcp.NewHeader(tcp.DefaultCommand.HEARTBEAT_REQUEST, 0, "", "22222") + msg := tcp.NewPackage(header) + return msg +} diff --git a/eventmesh-sdk-java/build.gradle b/eventmesh-sdk-java/build.gradle index e69de29bb2..ee9e2b1222 100644 --- a/eventmesh-sdk-java/build.gradle +++ b/eventmesh-sdk-java/build.gradle @@ -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. + */ + +def grpcVersion = '1.17.1' + +dependencies { + api project(":eventmesh-common") + + implementation "com.fasterxml.jackson.core:jackson-databind" + implementation "com.fasterxml.jackson.core:jackson-core" + implementation "com.fasterxml.jackson.core:jackson-annotations" + implementation "org.apache.commons:commons-collections4" + + implementation "io.netty:netty-all" + implementation "org.apache.httpcomponents:httpclient" + + implementation "io.grpc:grpc-protobuf:${grpcVersion}" + implementation "io.grpc:grpc-stub:${grpcVersion}" + implementation "io.grpc:grpc-netty:${grpcVersion}" + implementation "io.grpc:grpc-netty-shaded:${grpcVersion}" + + // protocol + api "io.cloudevents:cloudevents-core" + api "io.cloudevents:cloudevents-json-jackson" + api "io.openmessaging:openmessaging-api" + + testImplementation project(":eventmesh-common") + + testImplementation "com.fasterxml.jackson.core:jackson-databind" + testImplementation "com.fasterxml.jackson.core:jackson-core" + testImplementation "com.fasterxml.jackson.core:jackson-annotations" + + testImplementation "io.netty:netty-all" + testImplementation "org.apache.httpcomponents:httpclient" + + implementation "io.grpc:grpc-protobuf:1.17.1" + implementation "io.grpc:grpc-stub:1.17.1" + implementation "com.google.protobuf:protobuf-java-util:3.5.1" + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + + testImplementation "org.assertj:assertj-core" + + testImplementation "org.mockito:mockito-core" + testImplementation "org.powermock:powermock-module-junit4" + testImplementation "org.powermock:powermock-api-mockito2" +} diff --git a/eventmesh-sdk-java/gradle.properties b/eventmesh-sdk-java/gradle.properties new file mode 100644 index 0000000000..b1312a0905 --- /dev/null +++ b/eventmesh-sdk-java/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/config/EventMeshGrpcClientConfig.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/config/EventMeshGrpcClientConfig.java new file mode 100644 index 0000000000..79a67f55b4 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/config/EventMeshGrpcClientConfig.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.config; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class EventMeshGrpcClientConfig { + + @Builder.Default + private String serverAddr = "127.0.0.1"; + + @Builder.Default + private int serverPort = 10205; + + @Builder.Default + private String env = "env"; + + @Builder.Default + private String consumerGroup = "DefaultConsumerGroup"; + + @Builder.Default + private String producerGroup = "DefaultProducerGroup"; + + @Builder.Default + private String idc = "default"; + + @Builder.Default + private String sys = "sys123"; + + @Builder.Default + private String userName = "username"; + + @Builder.Default + private String password = "passwd"; + + @Builder.Default + private String language = "JAVA"; + + @Builder.Default + private boolean useTls = false; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("ClientConfig={") + .append("ServerAddr=").append(serverAddr).append(",") + .append("ServerPort=").append(serverPort).append(",") + .append("env=").append(env).append(",") + .append("idc=").append(idc).append(",") + .append("producerGroup=").append(producerGroup).append(",") + .append("consumerGroup=").append(consumerGroup).append(",") + .append("sys=").append(sys).append(",") + .append("userName=").append(userName).append(",") + .append("password=").append("***").append(",") + .append("useTls=").append(useTls).append("}"); + return sb.toString(); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumer.java new file mode 100644 index 0000000000..f181f6559b --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumer.java @@ -0,0 +1,264 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.consumer; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.util.EventMeshClientUtil; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.grpc.protos.ConsumerServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.protos.ConsumerServiceGrpc.ConsumerServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.ConsumerServiceGrpc.ConsumerServiceStub; +import org.apache.eventmesh.common.protocol.grpc.protos.Heartbeat; +import org.apache.eventmesh.common.protocol.grpc.protos.HeartbeatServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.protos.HeartbeatServiceGrpc.HeartbeatServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; + +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +public class EventMeshGrpcConsumer implements AutoCloseable { + + private static final Logger logger = LoggerFactory.getLogger(EventMeshGrpcConsumer.class); + + private static final String SDK_STREAM_URL = "grpc_stream"; + + private final EventMeshGrpcClientConfig clientConfig; + + private final Map subscriptionMap = new ConcurrentHashMap<>(); + private final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor( + Runtime.getRuntime().availableProcessors(), + new ThreadFactoryBuilder().setNameFormat("GRPCClientScheduler").setDaemon(true).build()); + + private ManagedChannel channel; + ConsumerServiceBlockingStub consumerClient; + ConsumerServiceStub consumerAsyncClient; + HeartbeatServiceBlockingStub heartbeatClient; + + private ReceiveMsgHook listener; + private SubStreamHandler subStreamHandler; + + public EventMeshGrpcConsumer(EventMeshGrpcClientConfig clientConfig) { + this.clientConfig = clientConfig; + } + + public void init() { + channel = ManagedChannelBuilder.forAddress(clientConfig.getServerAddr(), clientConfig.getServerPort()) + .usePlaintext().build(); + + consumerClient = ConsumerServiceGrpc.newBlockingStub(channel); + consumerAsyncClient = ConsumerServiceGrpc.newStub(channel); + heartbeatClient = HeartbeatServiceGrpc.newBlockingStub(channel); + + heartBeat(); + } + + public Response subscribe(List subscriptionItems, String url) { + logger.info("Create subscription: " + subscriptionItems + ", url: " + url); + + addSubscription(subscriptionItems, url); + + Subscription subscription = buildSubscription(subscriptionItems, url); + try { + Response response = consumerClient.subscribe(subscription); + logger.info("Received response " + response.toString()); + return response; + } catch (Exception e) { + logger.error("Error in subscribe. error {}", e.getMessage()); + return null; + } + } + + public void subscribe(List subscriptionItems) { + logger.info("Create streaming subscription: " + subscriptionItems); + + if (listener == null) { + logger.error("Error in subscriber, no Event Listener is registered."); + return; + } + + addSubscription(subscriptionItems, SDK_STREAM_URL); + + Subscription subscription = buildSubscription(subscriptionItems, null); + + synchronized (this) { + if (subStreamHandler == null) { + subStreamHandler = new SubStreamHandler<>(consumerAsyncClient, clientConfig, listener); + subStreamHandler.start(); + } + } + subStreamHandler.sendSubscription(subscription); + } + + private void addSubscription(List subscriptionItems, String url) { + for (SubscriptionItem item : subscriptionItems) { + subscriptionMap.put(item.getTopic(), url); + } + } + + private void removeSubscription(List subscriptionItems) { + for (SubscriptionItem item : subscriptionItems) { + subscriptionMap.remove(item.getTopic()); + } + } + + public Response unsubscribe(List subscriptionItems, String url) { + logger.info("Removing subscription: " + subscriptionItems + ", url: " + url); + + removeSubscription(subscriptionItems); + + Subscription subscription = buildSubscription(subscriptionItems, url); + + try { + Response response = consumerClient.unsubscribe(subscription); + logger.info("Received response " + response.toString()); + return response; + } catch (Exception e) { + logger.error("Error in unsubscribe. error {}", e.getMessage()); + return null; + } + } + + public Response unsubscribe(List subscriptionItems) { + logger.info("Removing subscription stream: " + subscriptionItems); + + removeSubscription(subscriptionItems); + + Subscription subscription = buildSubscription(subscriptionItems, null); + + try { + Response response = consumerClient.unsubscribe(subscription); + logger.info("Received response " + response.toString()); + + // there is no stream subscriptions, stop the subscription stream handler + synchronized (this) { + if (!subscriptionMap.containsValue(SDK_STREAM_URL) && subStreamHandler != null) { + subStreamHandler.close(); + subStreamHandler = null; + } + } + return response; + } catch (Exception e) { + logger.error("Error in unsubscribe. error {}", e.getMessage()); + return null; + } + } + + private Subscription buildSubscription(List subscriptionItems, String url) { + Subscription.Builder builder = Subscription.newBuilder() + .setHeader(EventMeshClientUtil.buildHeader(clientConfig, EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME)) + .setConsumerGroup(clientConfig.getConsumerGroup()); + + if (StringUtils.isNotEmpty(url)) { + builder.setUrl(url); + } + + for (SubscriptionItem subscriptionItem : subscriptionItems) { + Subscription.SubscriptionItem.SubscriptionMode mode; + if (SubscriptionMode.CLUSTERING.equals(subscriptionItem.getMode())) { + mode = Subscription.SubscriptionItem.SubscriptionMode.CLUSTERING; + } else if (SubscriptionMode.BROADCASTING.equals(subscriptionItem.getMode())) { + mode = Subscription.SubscriptionItem.SubscriptionMode.BROADCASTING; + } else { + mode = Subscription.SubscriptionItem.SubscriptionMode.UNRECOGNIZED; + } + + Subscription.SubscriptionItem.SubscriptionType type; + if (SubscriptionType.ASYNC.equals(subscriptionItem.getType())) { + type = Subscription.SubscriptionItem.SubscriptionType.ASYNC; + } else if (SubscriptionType.SYNC.equals(subscriptionItem.getType())) { + type = Subscription.SubscriptionItem.SubscriptionType.SYNC; + } else { + type = Subscription.SubscriptionItem.SubscriptionType.UNRECOGNIZED; + } + + Subscription.SubscriptionItem item = Subscription.SubscriptionItem.newBuilder() + .setTopic(subscriptionItem.getTopic()) + .setMode(mode) + .setType(type) + .build(); + builder.addSubscriptionItems(item); + } + return builder.build(); + } + + public synchronized void registerListener(ReceiveMsgHook listener) { + if (this.listener == null) { + this.listener = listener; + } + } + + private void heartBeat() { + RequestHeader header = EventMeshClientUtil.buildHeader(clientConfig, EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME); + scheduler.scheduleAtFixedRate(() -> { + if (subscriptionMap.isEmpty()) { + return; + } + Heartbeat.Builder heartbeatBuilder = Heartbeat.newBuilder() + .setHeader(header) + .setConsumerGroup(clientConfig.getConsumerGroup()) + .setClientType(Heartbeat.ClientType.SUB); + + for (Map.Entry entry : subscriptionMap.entrySet()) { + Heartbeat.HeartbeatItem heartbeatItem = Heartbeat.HeartbeatItem + .newBuilder() + .setTopic(entry.getKey()).setUrl(entry.getValue()) + .build(); + heartbeatBuilder.addHeartbeatItems(heartbeatItem); + } + Heartbeat heartbeat = heartbeatBuilder.build(); + + try { + Response response = heartbeatClient.heartbeat(heartbeat); + if (logger.isDebugEnabled()) { + logger.debug("Grpc Consumer Heartbeat response: {}", response); + } + } catch (Exception e) { + logger.error("Error in sending out heartbeat. error {}", e.getMessage()); + } + }, 10000, EventMeshCommon.HEARTBEAT, TimeUnit.MILLISECONDS); + + logger.info("Grpc Consumer Heartbeat started."); + } + + @Override + public void close() { + if (this.subStreamHandler != null) { + this.subStreamHandler.close(); + } + channel.shutdown(); + scheduler.shutdown(); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/ReceiveMsgHook.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/ReceiveMsgHook.java new file mode 100644 index 0000000000..905134c551 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/ReceiveMsgHook.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.consumer; + +import java.util.Optional; + +/** + * + * @param + */ +public interface ReceiveMsgHook { + + /** + * Handle the received message, return the response message. + * + * @param msg + * @return + */ + Optional handle(T msg) throws Throwable; + + String getProtocolType(); + +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/SubStreamHandler.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/SubStreamHandler.java new file mode 100644 index 0000000000..ed3654cc91 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/SubStreamHandler.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.consumer; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.util.EventMeshClientUtil; +import org.apache.eventmesh.common.protocol.grpc.protos.ConsumerServiceGrpc.ConsumerServiceStub; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; + +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CountDownLatch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.stub.StreamObserver; + +public class SubStreamHandler extends Thread { + + private static final Logger logger = LoggerFactory.getLogger(SubStreamHandler.class); + + private final CountDownLatch latch = new CountDownLatch(1); + + private final ConsumerServiceStub consumerAsyncClient; + + private final EventMeshGrpcClientConfig clientConfig; + + private StreamObserver sender; + + private final ReceiveMsgHook listener; + + public SubStreamHandler(ConsumerServiceStub consumerAsyncClient, EventMeshGrpcClientConfig clientConfig, + ReceiveMsgHook listener) { + this.consumerAsyncClient = consumerAsyncClient; + this.clientConfig = clientConfig; + this.listener = listener; + } + + public void sendSubscription(Subscription subscription) { + synchronized (this) { + if (this.sender == null) { + this.sender = consumerAsyncClient.subscribeStream(createReceiver()); + } + } + senderOnNext(subscription); + } + + private StreamObserver createReceiver() { + return new StreamObserver() { + @Override + public void onNext(SimpleMessage message) { + T msg = EventMeshClientUtil.buildMessage(message, listener.getProtocolType()); + + if (msg instanceof Map) { + logger.info("Received message from Server." + message); + } else { + logger.info("Received message from Server.|seq={}|uniqueId={}|", message.getSeqNum(), message.getUniqueId()); + Subscription streamReply = null; + try { + Optional reply = listener.handle(msg); + if (reply.isPresent()) { + streamReply = buildReplyMessage(message, reply.get()); + } + } catch (Throwable t) { + logger.error("Error in handling reply message.|seq={}|uniqueId={}|", message.getSeqNum(), message.getUniqueId(), t); + } + if (streamReply != null) { + logger.info("Sending reply message to Server.|seq={}|uniqueId={}|", streamReply.getReply().getSeqNum(), + streamReply.getReply().getUniqueId()); + senderOnNext(streamReply); + } + } + } + + @Override + public void onError(Throwable t) { + logger.error("Received Server side error: " + t.getMessage()); + close(); + } + + @Override + public void onCompleted() { + logger.info("Finished receiving messages from server."); + close(); + } + }; + } + + private Subscription buildReplyMessage(SimpleMessage reqMessage, T replyMessage) { + SimpleMessage simpleMessage = EventMeshClientUtil.buildSimpleMessage(replyMessage, clientConfig, listener.getProtocolType()); + + Subscription.Reply reply = Subscription.Reply.newBuilder() + .setProducerGroup(clientConfig.getConsumerGroup()) + .setTopic(simpleMessage.getTopic()) + .setContent(simpleMessage.getContent()) + .setSeqNum(simpleMessage.getSeqNum()) + .setUniqueId(simpleMessage.getUniqueId()) + .setTtl(simpleMessage.getTtl()) + .putAllProperties(reqMessage.getPropertiesMap()) + .putAllProperties(simpleMessage.getPropertiesMap()) + .build(); + + return Subscription.newBuilder() + .setHeader(simpleMessage.getHeader()) + .setReply(reply).build(); + } + + @Override + public void run() { + try { + latch.await(); + } catch (InterruptedException e) { + logger.error("SubStreamHandler Thread interrupted." + e.getMessage()); + } + } + + public void close() { + if (this.sender != null) { + senderOnComplete(); + this.sender = null; + } + latch.countDown(); + logger.info("SubStreamHandler closed."); + } + + private void senderOnNext(Subscription subscription) { + try { + synchronized (sender) { + sender.onNext(subscription); + } + } catch (Throwable t) { + logger.warn("StreamObserver Error onNext {}", t.getMessage()); + } + } + + private void senderOnComplete() { + try { + synchronized (sender) { + sender.onCompleted(); + } + } catch (Throwable t) { + logger.warn("StreamObserver Error onComplete {}", t.getMessage()); + } + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducer.java new file mode 100644 index 0000000000..99118f1d64 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducer.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.producer; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.util.EventMeshClientUtil; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class CloudEventProducer { + private static final Logger logger = LoggerFactory.getLogger(EventMeshGrpcProducer.class); + + private static final String PROTOCOL_TYPE = EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME; + + private final EventMeshGrpcClientConfig clientConfig; + + private final PublisherServiceBlockingStub publisherClient; + + public CloudEventProducer(EventMeshGrpcClientConfig clientConfig, PublisherServiceBlockingStub publisherClient) { + this.clientConfig = clientConfig; + this.publisherClient = publisherClient; + } + + public Response publish(List events) { + logger.info("BatchPublish message, batch size=" + events.size()); + + if (events.size() == 0) { + return null; + } + List enhancedEvents = events.stream() + .map(event -> enhanceCloudEvent(event, null)) + .collect(Collectors.toList()); + + BatchMessage enhancedMessage = EventMeshClientUtil.buildBatchMessages(enhancedEvents, clientConfig, PROTOCOL_TYPE); + try { + Response response = publisherClient.batchPublish(enhancedMessage); + logger.info("Received response " + response.toString()); + return response; + } catch (Exception e) { + logger.error("Error in BatchPublish message {}, error {}", events, e.getMessage()); + return null; + } + } + + public Response publish(CloudEvent cloudEvent) { + logger.info("Publish message " + cloudEvent.toString()); + CloudEvent enhanceEvent = enhanceCloudEvent(cloudEvent, null); + + SimpleMessage enhancedMessage = EventMeshClientUtil.buildSimpleMessage(enhanceEvent, clientConfig, PROTOCOL_TYPE); + + try { + Response response = publisherClient.publish(enhancedMessage); + logger.info("Received response " + response.toString()); + return response; + } catch (Exception e) { + logger.error("Error in publishing message {}, error {}", cloudEvent, e.getMessage()); + return null; + } + } + + public CloudEvent requestReply(CloudEvent cloudEvent, int timeout) { + logger.info("RequestReply message " + cloudEvent.toString()); + CloudEvent enhanceEvent = enhanceCloudEvent(cloudEvent, String.valueOf(timeout)); + + SimpleMessage enhancedMessage = EventMeshClientUtil.buildSimpleMessage(enhanceEvent, clientConfig, PROTOCOL_TYPE); + try { + SimpleMessage reply = publisherClient.requestReply(enhancedMessage); + logger.info("Received reply message" + reply.toString()); + + Object msg = EventMeshClientUtil.buildMessage(reply, PROTOCOL_TYPE); + if (msg instanceof CloudEvent) { + return (CloudEvent) msg; + } else { + return null; + } + } catch (Exception e) { + logger.error("Error in RequestReply message {}, error {}", cloudEvent, e.getMessage()); + return null; + } + } + + private CloudEvent enhanceCloudEvent(final CloudEvent cloudEvent, String timeout) { + CloudEventBuilder builder = CloudEventBuilder.from(cloudEvent) + .withExtension(ProtocolKey.ENV, clientConfig.getEnv()) + .withExtension(ProtocolKey.IDC, clientConfig.getIdc()) + .withExtension(ProtocolKey.IP, IPUtils.getLocalAddress()) + .withExtension(ProtocolKey.PID, Long.toString(ThreadUtils.getPID())) + .withExtension(ProtocolKey.SYS, clientConfig.getSys()) + .withExtension(ProtocolKey.LANGUAGE, "JAVA") + .withExtension(ProtocolKey.PROTOCOL_TYPE, PROTOCOL_TYPE) + .withExtension(ProtocolKey.PROTOCOL_DESC, "grpc") + .withExtension(ProtocolKey.PROTOCOL_VERSION, cloudEvent.getSpecVersion().toString()) + .withExtension(ProtocolKey.UNIQUE_ID, RandomStringUtils.generateNum(30)) + .withExtension(ProtocolKey.SEQ_NUM, RandomStringUtils.generateNum(30)) + .withExtension(ProtocolKey.USERNAME, clientConfig.getUserName()) + .withExtension(ProtocolKey.PASSWD, clientConfig.getPassword()) + .withExtension(ProtocolKey.PRODUCERGROUP, clientConfig.getProducerGroup()); + + if (timeout != null) { + builder.withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, timeout); + } + return builder.build(); + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducer.java new file mode 100644 index 0000000000..804d3341b8 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducer.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.producer; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.util.EventMeshClientUtil; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.PublisherServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.protos.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +public class EventMeshGrpcProducer implements AutoCloseable { + + private static final Logger logger = LoggerFactory.getLogger(EventMeshGrpcProducer.class); + + private static final String PROTOCOL_TYPE = EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME; + + private final EventMeshGrpcClientConfig clientConfig; + + private ManagedChannel channel; + + PublisherServiceBlockingStub publisherClient; + + CloudEventProducer cloudEventProducer; + + public EventMeshGrpcProducer(EventMeshGrpcClientConfig clientConfig) { + this.clientConfig = clientConfig; + } + + public void init() { + channel = ManagedChannelBuilder.forAddress(clientConfig.getServerAddr(), clientConfig.getServerPort()) + .usePlaintext().build(); + publisherClient = PublisherServiceGrpc.newBlockingStub(channel); + + cloudEventProducer = new CloudEventProducer(clientConfig, publisherClient); + } + + public Response publish(EventMeshMessage message) { + logger.info("Publish message " + message.toString()); + + SimpleMessage simpleMessage = EventMeshClientUtil.buildSimpleMessage(message, clientConfig, PROTOCOL_TYPE); + try { + Response response = publisherClient.publish(simpleMessage); + logger.info("Received response " + response.toString()); + return response; + } catch (Exception e) { + logger.error("Error in publishing message {}, error {}", message, e.getMessage()); + return null; + } + } + + @SuppressWarnings("unchecked") + public Response publish(List messageList) { + logger.info("BatchPublish message " + messageList.toString()); + + if (messageList.size() == 0) { + return null; + } + if (messageList.get(0) instanceof CloudEvent) { + return cloudEventProducer.publish((List) messageList); + } + BatchMessage batchMessage = EventMeshClientUtil.buildBatchMessages(messageList, clientConfig, PROTOCOL_TYPE); + try { + Response response = publisherClient.batchPublish(batchMessage); + logger.info("Received response " + response.toString()); + return response; + } catch (Exception e) { + logger.error("Error in BatchPublish message {}, error {}", messageList, e.getMessage()); + return null; + } + } + + public Response publish(CloudEvent cloudEvent) { + return cloudEventProducer.publish(cloudEvent); + } + + public CloudEvent requestReply(CloudEvent cloudEvent, int timeout) { + return cloudEventProducer.requestReply(cloudEvent, timeout); + } + + public EventMeshMessage requestReply(EventMeshMessage message, int timeout) { + logger.info("RequestReply message " + message.toString()); + + SimpleMessage simpleMessage = EventMeshClientUtil.buildSimpleMessage(message, clientConfig, PROTOCOL_TYPE); + try { + SimpleMessage reply = publisherClient.withDeadlineAfter(timeout, TimeUnit.MILLISECONDS).requestReply(simpleMessage); + logger.info("Received reply message" + reply.toString()); + + Object msg = EventMeshClientUtil.buildMessage(reply, PROTOCOL_TYPE); + if (msg instanceof EventMeshMessage) { + return (EventMeshMessage) msg; + } else { + return null; + } + } catch (Exception e) { + logger.error("Error in RequestReply message {}, error {}", message, e.getMessage()); + return null; + } + } + + @Override + public void close() { + channel.shutdown(); + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtil.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtil.java new file mode 100644 index 0000000000..71b0e2aa59 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtil.java @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.util; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +import com.fasterxml.jackson.core.type.TypeReference; + +public class EventMeshClientUtil { + + private static final Logger logger = LoggerFactory.getLogger(EventMeshClientUtil.class); + + public static RequestHeader buildHeader(EventMeshGrpcClientConfig clientConfig, String protocolType) { + return RequestHeader.newBuilder() + .setEnv(clientConfig.getEnv()) + .setIdc(clientConfig.getIdc()) + .setIp(IPUtils.getLocalAddress()) + .setPid(Long.toString(ThreadUtils.getPID())) + .setSys(clientConfig.getSys()) + .setLanguage(clientConfig.getLanguage()) + .setUsername(clientConfig.getUserName()) + .setPassword(clientConfig.getPassword()) + .setProtocolType(protocolType) + .setProtocolDesc("grpc") + // default CloudEvents version is V1 + .setProtocolVersion(SpecVersion.V1.toString()) + .build(); + } + + @SuppressWarnings("unchecked") + public static T buildMessage(SimpleMessage message, String protocolType) { + String seq = message.getSeqNum(); + String uniqueId = message.getUniqueId(); + String content = message.getContent(); + + // This is GRPC response message + if (StringUtils.isEmpty(seq) && StringUtils.isEmpty(uniqueId)) { + HashMap response = JsonUtils.deserialize(content, new TypeReference>() { + }); + return (T) response; + } + + if (EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME.equals(protocolType)) { + String contentType = message.getPropertiesOrDefault(ProtocolKey.CONTENT_TYPE, JsonFormat.CONTENT_TYPE); + try { + CloudEvent cloudEvent = EventFormatProvider.getInstance().resolveFormat(contentType) + .deserialize(content.getBytes(StandardCharsets.UTF_8)); + + CloudEventBuilder cloudEventBuilder = CloudEventBuilder.from(cloudEvent) + .withSubject(message.getTopic()) + .withExtension(ProtocolKey.SEQ_NUM, message.getSeqNum()) + .withExtension(ProtocolKey.UNIQUE_ID, message.getUniqueId()); + + message.getPropertiesMap().forEach(cloudEventBuilder::withExtension); + + return (T) cloudEventBuilder.build(); + } catch (Throwable t) { + logger.warn("Error in building message. {}", t.getMessage()); + return null; + } + } else { + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .content(content) + .topic(message.getTopic()) + .bizSeqNo(seq) + .uniqueId(uniqueId) + .prop(message.getPropertiesMap()) + .build(); + return (T) eventMeshMessage; + } + } + + public static SimpleMessage buildSimpleMessage(T message, EventMeshGrpcClientConfig clientConfig, + String protocolType) { + if (EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME.equals(protocolType)) { + CloudEvent cloudEvent = (CloudEvent) message; + String contentType = StringUtils.isEmpty(cloudEvent.getDataContentType()) ? "application/cloudevents+json" + : cloudEvent.getDataContentType(); + byte[] bodyByte = EventFormatProvider.getInstance().resolveFormat(contentType) + .serialize(cloudEvent); + String content = new String(bodyByte, StandardCharsets.UTF_8); + String ttl = cloudEvent.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL) == null ? Constants.DEFAULT_EVENTMESH_MESSAGE_TTL + : cloudEvent.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL).toString(); + + String seqNum = cloudEvent.getExtension(ProtocolKey.SEQ_NUM) == null ? RandomStringUtils.generateNum(30) + : cloudEvent.getExtension(ProtocolKey.SEQ_NUM).toString(); + + String uniqueId = cloudEvent.getExtension(ProtocolKey.UNIQUE_ID) == null ? RandomStringUtils.generateNum(30) + : cloudEvent.getExtension(ProtocolKey.UNIQUE_ID).toString(); + + SimpleMessage.Builder builder = SimpleMessage.newBuilder() + .setHeader(EventMeshClientUtil.buildHeader(clientConfig, protocolType)) + .setProducerGroup(clientConfig.getProducerGroup()) + .setTopic(cloudEvent.getSubject()) + .setTtl(ttl) + .setSeqNum(seqNum) + .setUniqueId(uniqueId) + .setContent(content) + .putProperties(ProtocolKey.CONTENT_TYPE, contentType); + + for (String extName : cloudEvent.getExtensionNames()) { + builder.putProperties(extName, cloudEvent.getExtension(extName).toString()); + } + + return builder.build(); + } else { + EventMeshMessage eventMeshMessage = (EventMeshMessage) message; + + String ttl = eventMeshMessage.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL) == null ? Constants.DEFAULT_EVENTMESH_MESSAGE_TTL + : eventMeshMessage.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL); + Map props = eventMeshMessage.getProp() == null ? new HashMap<>() : eventMeshMessage.getProp(); + + String seqNum = eventMeshMessage.getBizSeqNo() == null ? RandomStringUtils.generateNum(30) + : eventMeshMessage.getBizSeqNo(); + + String uniqueId = eventMeshMessage.getUniqueId() == null ? RandomStringUtils.generateNum(30) + : eventMeshMessage.getUniqueId(); + + return SimpleMessage.newBuilder() + .setHeader(EventMeshClientUtil.buildHeader(clientConfig, protocolType)) + .setProducerGroup(clientConfig.getProducerGroup()) + .setTopic(eventMeshMessage.getTopic()) + .setContent(eventMeshMessage.getContent()) + .setSeqNum(seqNum) + .setUniqueId(uniqueId) + .setTtl(ttl) + .putAllProperties(props) + .build(); + } + } + + @SuppressWarnings("unchecked") + public static BatchMessage buildBatchMessages(List messageList, EventMeshGrpcClientConfig clientConfig, + String protocolType) { + if (EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME.equals(protocolType)) { + List events = (List) messageList; + BatchMessage.Builder messageBuilder = BatchMessage.newBuilder() + .setHeader(EventMeshClientUtil.buildHeader(clientConfig, protocolType)) + .setProducerGroup(clientConfig.getProducerGroup()) + .setTopic(events.get(0).getSubject()); + + for (CloudEvent event : events) { + String contentType = StringUtils.isEmpty(event.getDataContentType()) ? "application/cloudevents+json" + : event.getDataContentType(); + byte[] bodyByte = EventFormatProvider.getInstance().resolveFormat(contentType) + .serialize(event); + String content = new String(bodyByte, StandardCharsets.UTF_8); + + String ttl = event.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL) == null ? Constants.DEFAULT_EVENTMESH_MESSAGE_TTL + : event.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL).toString(); + + BatchMessage.MessageItem messageItem = BatchMessage.MessageItem.newBuilder() + .setContent(content) + .setTtl(ttl) + .setSeqNum(event.getExtension(ProtocolKey.SEQ_NUM).toString()) + .setUniqueId(event.getExtension(ProtocolKey.UNIQUE_ID).toString()) + .putProperties(ProtocolKey.CONTENT_TYPE, contentType) + .build(); + + messageBuilder.addMessageItem(messageItem); + } + return messageBuilder.build(); + } else { + List eventMeshMessages = (List) messageList; + BatchMessage.Builder messageBuilder = BatchMessage.newBuilder() + .setHeader(EventMeshClientUtil.buildHeader(clientConfig, protocolType)) + .setProducerGroup(clientConfig.getProducerGroup()) + .setTopic(eventMeshMessages.get(0).getTopic()); + + for (EventMeshMessage message : eventMeshMessages) { + BatchMessage.MessageItem item = BatchMessage.MessageItem.newBuilder() + .setContent(message.getContent()) + .setUniqueId(message.getUniqueId()) + .setSeqNum(message.getBizSeqNo()) + .setTtl( + Optional.ofNullable(message.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL)).orElse(Constants.DEFAULT_EVENTMESH_MESSAGE_TTL)) + .putAllProperties(message.getProp()) + .build(); + messageBuilder.addMessageItem(item); + } + return messageBuilder.build(); + } + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/AbstractHttpClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/AbstractHttpClient.java new file mode 100644 index 0000000000..58ebb0b386 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/AbstractHttpClient.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.ssl.MyX509TrustManager; +import org.apache.eventmesh.client.http.util.HttpLoadBalanceUtils; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.loadbalance.LoadBalanceSelector; + +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +import java.io.IOException; +import java.security.SecureRandom; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractHttpClient implements AutoCloseable { + + protected EventMeshHttpClientConfig eventMeshHttpClientConfig; + + protected LoadBalanceSelector eventMeshServerSelector; + + protected final CloseableHttpClient httpClient; + + public AbstractHttpClient(EventMeshHttpClientConfig eventMeshHttpClientConfig) throws EventMeshException { + Preconditions.checkNotNull(eventMeshHttpClientConfig, "liteClientConfig can't be null"); + Preconditions.checkNotNull(eventMeshHttpClientConfig.getLiteEventMeshAddr(), "liteServerAddr can't be null"); + + this.eventMeshHttpClientConfig = eventMeshHttpClientConfig; + this.eventMeshServerSelector = HttpLoadBalanceUtils.createEventMeshServerLoadBalanceSelector( + eventMeshHttpClientConfig); + this.httpClient = setHttpClient(); + } + + @Override + public void close() throws EventMeshException { + try (final CloseableHttpClient ignore = this.httpClient) { + // ignore + } catch (IOException e) { + throw new EventMeshException("Close http client error", e); + } + } + + private CloseableHttpClient setHttpClient() throws EventMeshException { + if (!eventMeshHttpClientConfig.isUseTls()) { + return HttpClients.createDefault(); + } + SSLContext sslContext; + try { + // todo: config in properties file? + String protocol = System.getProperty("ssl.client.protocol", "TLSv1.2"); + TrustManager[] tm = new TrustManager[]{new MyX509TrustManager()}; + sslContext = SSLContext.getInstance(protocol); + sslContext.init(null, tm, new SecureRandom()); + // todo: custom client pool + return HttpClients.custom() + .setSSLContext(sslContext) + .setSSLHostnameVerifier(new DefaultHostnameVerifier()) + .build(); + } catch (Exception e) { + log.error("Error in creating HttpClient.", e); + throw new EventMeshException(e); + } + } + + protected String selectEventMesh() { + // todo: target endpoint maybe destroy, should remove the bad endpoint + if (eventMeshHttpClientConfig.isUseTls()) { + return Constants.HTTPS_PROTOCOL_PREFIX + eventMeshServerSelector.select(); + } else { + return Constants.HTTP_PROTOCOL_PREFIX + eventMeshServerSelector.select(); + } + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/EventMeshRetObj.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/EventMeshRetObj.java new file mode 100644 index 0000000000..fe024fcf5f --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/EventMeshRetObj.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http; + +public class EventMeshRetObj { + + private long resTime; + + private int retCode; + + private String retMsg; + + public long getResTime() { + return resTime; + } + + public void setResTime(long resTime) { + this.resTime = resTime; + } + + public int getRetCode() { + return retCode; + } + + public void setRetCode(int retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ProtocolConstant.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ProtocolConstant.java new file mode 100644 index 0000000000..0c1c18417f --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ProtocolConstant.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http; + +public final class ProtocolConstant { + public static final String CE_PROTOCOL = "cloudevents"; + public static final String EM_MESSAGE_PROTOCOL = "eventmeshmessage"; + public static final String OP_MESSAGE_PROTOCOL = "openmessage"; + public static final String PROTOCOL_DESC = "http"; +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/conf/EventMeshHttpClientConfig.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/conf/EventMeshHttpClientConfig.java new file mode 100644 index 0000000000..24dfd0fee4 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/conf/EventMeshHttpClientConfig.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.conf; + +import org.apache.eventmesh.common.loadbalance.LoadBalanceType; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class EventMeshHttpClientConfig { + + /** + * The event server address list + *

+ * If it's a cluster, please use ; to split, and the address format is related to loadBalanceType. + *

+ * E.g. + *

If you use Random strategy, the format like: 127.0.0.1:10105;127.0.0.2:10105 + *

If you use weighted round robin or weighted random strategy, the format like: 127.0.0.1:10105:1;127.0.0.2:10105:2 + */ + @Builder.Default + private String liteEventMeshAddr = "127.0.0.1:10105"; + + @Builder.Default + private LoadBalanceType loadBalanceType = LoadBalanceType.RANDOM; + + @Builder.Default + private int consumeThreadCore = 2; + + @Builder.Default + private int consumeThreadMax = 5; + + @Builder.Default + private String env = ""; + + @Builder.Default + private String consumerGroup = "DefaultConsumerGroup"; + + @Builder.Default + private String producerGroup = "DefaultProducerGroup"; + + @Builder.Default + private String idc = ""; + + @Builder.Default + private String ip = "127.0.0.1"; + + @Builder.Default + private String pid = ""; + + @Builder.Default + private String sys = ""; + + @Builder.Default + private String userName = ""; + + @Builder.Default + private String password = ""; + + @Builder.Default + private boolean useTls = false; + +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/consumer/EventMeshHttpConsumer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/consumer/EventMeshHttpConsumer.java new file mode 100644 index 0000000000..a891bdf177 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/consumer/EventMeshHttpConsumer.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.consumer; + +import org.apache.eventmesh.client.http.AbstractHttpClient; +import org.apache.eventmesh.client.http.EventMeshRetObj; +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.model.RequestParam; +import org.apache.eventmesh.client.http.util.HttpUtils; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.http.body.client.HeartbeatRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.SubscribeRequestBody; +import org.apache.eventmesh.common.protocol.http.body.client.UnSubscribeRequestBody; +import org.apache.eventmesh.common.protocol.http.common.ClientType; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import io.netty.handler.codec.http.HttpMethod; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventMeshHttpConsumer extends AbstractHttpClient implements AutoCloseable { + + private final ThreadPoolExecutor consumeExecutor; + + private static final List SUBSCRIPTIONS = Collections.synchronizedList(new ArrayList<>()); + + private final ScheduledThreadPoolExecutor scheduler; + + public EventMeshHttpConsumer(EventMeshHttpClientConfig eventMeshHttpClientConfig) throws EventMeshException { + this(eventMeshHttpClientConfig, null); + } + + public EventMeshHttpConsumer(EventMeshHttpClientConfig eventMeshHttpClientConfig, ThreadPoolExecutor customExecutor) + throws EventMeshException { + super(eventMeshHttpClientConfig); + this.consumeExecutor = Optional.ofNullable(customExecutor).orElseGet( + () -> ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpClientConfig.getConsumeThreadCore(), + eventMeshHttpClientConfig.getConsumeThreadMax(), "EventMesh-client-consume-") + ); + this.scheduler = new ScheduledThreadPoolExecutor( + Runtime.getRuntime().availableProcessors(), + new ThreadFactoryBuilder().setNameFormat("HTTPClientScheduler").setDaemon(true).build() + ); + } + + /** + * When receive message will callback the url. + * + * @param topicList topic that be subscribed + * @param subscribeUrl url will be trigger + * @throws EventMeshException if subscribe failed + */ + public void subscribe(List topicList, String subscribeUrl) throws EventMeshException { + Preconditions.checkNotNull(topicList, "Subscribe item cannot be null"); + Preconditions.checkNotNull(subscribeUrl, "SubscribeUrl cannot be null"); + RequestParam subscribeParam = buildCommonRequestParam() + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.SUBSCRIBE.getRequestCode()) + .addBody(SubscribeRequestBody.TOPIC, JsonUtils.serialize(topicList)) + .addBody(SubscribeRequestBody.CONSUMERGROUP, eventMeshHttpClientConfig.getConsumerGroup()) + .addBody(SubscribeRequestBody.URL, subscribeUrl); + + String target = selectEventMesh(); + try { + String subRes = HttpUtils.post(httpClient, target, subscribeParam); + EventMeshRetObj ret = JsonUtils.deserialize(subRes, EventMeshRetObj.class); + if (ret.getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } + SUBSCRIPTIONS.addAll(topicList); + } catch (Exception ex) { + throw new EventMeshException(String.format("Subscribe topic error, target:%s", target), ex); + } + } + + // todo: remove http heartBeat? + public void heartBeat(List topicList, String subscribeUrl) { + Preconditions.checkNotNull(topicList, "Subscribe item cannot be null"); + Preconditions.checkNotNull(subscribeUrl, "SubscribeUrl cannot be null"); + scheduler.scheduleAtFixedRate(() -> { + try { + List heartbeatEntities = topicList.stream().map(subscriptionItem + -> { + HeartbeatRequestBody.HeartbeatEntity heartbeatEntity = new HeartbeatRequestBody.HeartbeatEntity(); + heartbeatEntity.topic = subscriptionItem.getTopic(); + heartbeatEntity.url = subscribeUrl; + return heartbeatEntity; + }).collect(Collectors.toList()); + RequestParam requestParam = buildCommonRequestParam() + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.HEARTBEAT.getRequestCode()) + .addBody(HeartbeatRequestBody.CLIENTTYPE, ClientType.SUB.name()) + .addBody(HeartbeatRequestBody.HEARTBEATENTITIES, JsonUtils.serialize(heartbeatEntities)); + String target = selectEventMesh(); + String res = HttpUtils.post(httpClient, target, requestParam); + EventMeshRetObj ret = JsonUtils.deserialize(res, EventMeshRetObj.class); + if (ret.getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } + } catch (Exception e) { + log.error("send heartBeat error", e); + } + }, EventMeshCommon.HEARTBEAT, EventMeshCommon.HEARTBEAT, TimeUnit.MILLISECONDS); + } + + /** + * @param topicList subscribe topic + * @param unSubscribeUrl subscribeUrl + * @throws EventMeshException if unsubscribe failed + */ + public void unsubscribe(List topicList, String unSubscribeUrl) throws EventMeshException { + Preconditions.checkNotNull(topicList, "Topics cannot be null"); + Preconditions.checkNotNull(unSubscribeUrl, "unSubscribeUrl cannot be null"); + RequestParam unSubscribeParam = buildCommonRequestParam() + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.UNSUBSCRIBE.getRequestCode()) + .addBody(UnSubscribeRequestBody.TOPIC, JsonUtils.serialize(topicList)) + .addBody(UnSubscribeRequestBody.URL, unSubscribeUrl); + String target = selectEventMesh(); + try { + String unSubRes = HttpUtils.post(httpClient, target, unSubscribeParam); + EventMeshRetObj ret = JsonUtils.deserialize(unSubRes, EventMeshRetObj.class); + + if (ret.getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } + // todo: avoid concurrentModifiedException + SUBSCRIPTIONS.removeIf(item -> topicList.contains(item.getTopic())); + } catch (Exception ex) { + throw new EventMeshException(String.format("Unsubscribe topic error, target:%s", target), ex); + } + } + + @Override + public void close() throws EventMeshException { + log.info("LiteConsumer shutting down"); + super.close(); + if (consumeExecutor != null) { + consumeExecutor.shutdown(); + } + scheduler.shutdown(); + log.info("LiteConsumer shutdown"); + } + + private RequestParam buildCommonRequestParam() { + return new RequestParam(HttpMethod.POST) + .addHeader(ProtocolKey.ClientInstanceKey.ENV, eventMeshHttpClientConfig.getEnv()) + .addHeader(ProtocolKey.ClientInstanceKey.IDC, eventMeshHttpClientConfig.getIdc()) + .addHeader(ProtocolKey.ClientInstanceKey.IP, eventMeshHttpClientConfig.getIp()) + .addHeader(ProtocolKey.ClientInstanceKey.PID, eventMeshHttpClientConfig.getPid()) + .addHeader(ProtocolKey.ClientInstanceKey.SYS, eventMeshHttpClientConfig.getSys()) + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME, eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD, eventMeshHttpClientConfig.getPassword()) + // add protocol version? + .addHeader(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()) + .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) + .setTimeout(Constants.DEFAULT_HTTP_TIME_OUT) + .addBody(HeartbeatRequestBody.CONSUMERGROUP, eventMeshHttpClientConfig.getConsumerGroup()); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/model/RequestParam.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/model/RequestParam.java new file mode 100644 index 0000000000..97f4c95cb6 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/model/RequestParam.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.model; + +import org.apache.eventmesh.common.Constants; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import io.netty.handler.codec.http.HttpMethod; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RequestParam { + + private Map queryParams; + + private final HttpMethod httpMethod; + + private Map body; + + private Map headers; + + private long timeout = Constants.DEFAULT_HTTP_TIME_OUT; + + public RequestParam(HttpMethod httpMethod) { + this.httpMethod = httpMethod; + } + + public HttpMethod getHttpMethod() { + return httpMethod; + } + + public Map getHeaders() { + return headers; + } + + public RequestParam setHeaders(Map headers) { + this.headers = headers; + return this; + } + + public Map getBody() { + return body; + } + + public RequestParam setBody(Map body) { + this.body = body; + return this; + } + + public Map getQueryParamsMap() { + return queryParams; + } + + public String getQueryParams() { + if (queryParams == null || queryParams.size() == 0) { + return ""; + } + StringBuilder stringBuilder = new StringBuilder(); + try { + for (Map.Entry query : queryParams.entrySet()) { + for (String val : query.getValue()) { + stringBuilder.append("&") + .append(URLEncoder.encode(query.getKey(), "UTF-8")); + + if (val != null && !val.isEmpty()) { + stringBuilder.append("=") + .append(URLEncoder.encode(val, "UTF-8")); + } + } + } + } catch (UnsupportedEncodingException e) { + log.error("get query params failed.", e); + return ""; + } + return stringBuilder.substring(1); + } + + public RequestParam setQueryParams(Map queryParams) { + this.queryParams = queryParams; + return this; + } + + public RequestParam addQueryParam(String key, String value) { + if (queryParams == null) { + queryParams = new HashMap<>(); + } + if (!queryParams.containsKey(key)) { + queryParams.put(key, new String[]{value}); + } else { + queryParams.put(key, (String[]) Arrays.asList(queryParams.get(key), value).toArray()); + } + return this; + } + + public RequestParam addHeader(String key, Object value) { + if (headers == null) { + headers = new HashMap<>(); + } + headers.put(key, value.toString()); + return this; + } + + public RequestParam addBody(String key, String value) { + if (body == null) { + body = new HashMap<>(); + } + body.put(key, value); + return this; + } + + public long getTimeout() { + return timeout; + } + + public RequestParam setTimeout(long timeout) { + this.timeout = timeout; + return this; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/CloudEventProducer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/CloudEventProducer.java new file mode 100644 index 0000000000..995e267be0 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/CloudEventProducer.java @@ -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 org.apache.eventmesh.client.http.producer; + +import org.apache.eventmesh.client.http.AbstractHttpClient; +import org.apache.eventmesh.client.http.EventMeshRetObj; +import org.apache.eventmesh.client.http.ProtocolConstant; +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.model.RequestParam; +import org.apache.eventmesh.client.http.util.HttpUtils; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.provider.EventFormatProvider; +import io.netty.handler.codec.http.HttpMethod; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class CloudEventProducer extends AbstractHttpClient implements EventMeshProtocolProducer { + + public CloudEventProducer(EventMeshHttpClientConfig eventMeshHttpClientConfig) throws EventMeshException { + super(eventMeshHttpClientConfig); + } + + @Override + public void publish(CloudEvent cloudEvent) throws EventMeshException { + validateCloudEvent(cloudEvent); + CloudEvent enhanceCloudEvent = enhanceCloudEvent(cloudEvent); + // todo: Can put to abstract class, all protocol use the same send method? This can be a template method + RequestParam requestParam = buildCommonPostParam(enhanceCloudEvent) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + String target = selectEventMesh(); + try { + String response = HttpUtils.post(httpClient, target, requestParam); + EventMeshRetObj ret = JsonUtils.deserialize(response, EventMeshRetObj.class); + + if (ret.getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } + } catch (Exception exception) { + throw new EventMeshException(String.format("Publish message error, target:%s", target), exception); + } + + } + + @Override + public CloudEvent request(CloudEvent cloudEvent, long timeout) throws EventMeshException { + validateCloudEvent(cloudEvent); + CloudEvent enhanceCloudEvent = enhanceCloudEvent(cloudEvent); + RequestParam requestParam = buildCommonPostParam(enhanceCloudEvent) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_SYNC.getRequestCode()) + .setTimeout(timeout); + String target = selectEventMesh(); + + try { + String response = HttpUtils.post(httpClient, target, requestParam); + EventMeshRetObj ret = JsonUtils.deserialize(response, EventMeshRetObj.class); + if (ret.getRetCode() == EventMeshRetCode.SUCCESS.getRetCode()) { + return transformMessage(ret); + } + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } catch (Exception e) { + throw new EventMeshException(String.format("Request message error, target:%s", target), e); + } + } + + @Override + public void request(final CloudEvent cloudEvent, final RRCallback rrCallback, long timeout) + throws EventMeshException { + validateCloudEvent(cloudEvent); + CloudEvent enhanceCloudEvent = enhanceCloudEvent(cloudEvent); + RequestParam requestParam = buildCommonPostParam(enhanceCloudEvent) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_SYNC.getRequestCode()) + .setTimeout(timeout); + String target = selectEventMesh(); + RRCallbackResponseHandlerAdapter adapter = new RRCallbackResponseHandlerAdapter<>( + enhanceCloudEvent, rrCallback, timeout); + try { + HttpUtils.post(httpClient, null, target, requestParam, adapter); + } catch (IOException e) { + throw new EventMeshException(String.format("Request message error, target:%s", target), e); + } + + } + + private void validateCloudEvent(CloudEvent cloudEvent) { + Preconditions.checkNotNull(cloudEvent, "CloudEvent cannot be null"); + } + + private RequestParam buildCommonPostParam(CloudEvent cloudEvent) { + byte[] bodyByte = EventFormatProvider.getInstance().resolveFormat(cloudEvent.getDataContentType()) + .serialize(cloudEvent); + String content = new String(bodyByte, StandardCharsets.UTF_8); + + RequestParam requestParam = new RequestParam(HttpMethod.POST); + requestParam + .addHeader(ProtocolKey.ClientInstanceKey.ENV, eventMeshHttpClientConfig.getEnv()) + .addHeader(ProtocolKey.ClientInstanceKey.IDC, eventMeshHttpClientConfig.getIdc()) + .addHeader(ProtocolKey.ClientInstanceKey.IP, eventMeshHttpClientConfig.getIp()) + .addHeader(ProtocolKey.ClientInstanceKey.PID, eventMeshHttpClientConfig.getPid()) + .addHeader(ProtocolKey.ClientInstanceKey.SYS, eventMeshHttpClientConfig.getSys()) + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME, eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD, eventMeshHttpClientConfig.getPassword()) + .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) + .addHeader(ProtocolKey.PROTOCOL_TYPE, ProtocolConstant.CE_PROTOCOL) + .addHeader(ProtocolKey.PROTOCOL_DESC, ProtocolConstant.PROTOCOL_DESC) + .addHeader(ProtocolKey.PROTOCOL_VERSION, cloudEvent.getSpecVersion().toString()) + + // todo: move producerGroup tp header + .addBody(SendMessageRequestBody.PRODUCERGROUP, eventMeshHttpClientConfig.getProducerGroup()) + .addBody(SendMessageRequestBody.CONTENT, content); + return requestParam; + } + + private CloudEvent enhanceCloudEvent(final CloudEvent cloudEvent) { + return CloudEventBuilder.from(cloudEvent) + .withExtension(ProtocolKey.ClientInstanceKey.ENV, eventMeshHttpClientConfig.getEnv()) + .withExtension(ProtocolKey.ClientInstanceKey.IDC, eventMeshHttpClientConfig.getIdc()) + .withExtension(ProtocolKey.ClientInstanceKey.IP, eventMeshHttpClientConfig.getIp()) + .withExtension(ProtocolKey.ClientInstanceKey.PID, eventMeshHttpClientConfig.getPid()) + .withExtension(ProtocolKey.ClientInstanceKey.SYS, eventMeshHttpClientConfig.getSys()) + .withExtension(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) + .withExtension(ProtocolKey.PROTOCOL_DESC, cloudEvent.getSpecVersion().name()) + .withExtension(ProtocolKey.PROTOCOL_VERSION, cloudEvent.getSpecVersion().toString()) + .withExtension(ProtocolKey.ClientInstanceKey.BIZSEQNO, RandomStringUtils.generateNum(30)) + .withExtension(ProtocolKey.ClientInstanceKey.UNIQUEID, RandomStringUtils.generateNum(30)) + .build(); + } + + private CloudEvent transformMessage(EventMeshRetObj retObj) { + SendMessageResponseBody.ReplyMessage replyMessage = JsonUtils.deserialize(retObj.getRetMsg(), + SendMessageResponseBody.ReplyMessage.class); + // todo: deserialize message + return null; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshHttpProducer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshHttpProducer.java new file mode 100644 index 0000000000..a7e0a43637 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshHttpProducer.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.producer; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.exception.EventMeshException; + +import io.cloudevents.CloudEvent; +import io.openmessaging.api.Message; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventMeshHttpProducer implements AutoCloseable { + + private final EventMeshMessageProducer eventMeshMessageProducer; + private final CloudEventProducer cloudEventProducer; + private final OpenMessageProducer openMessageProducer; + + public EventMeshHttpProducer(final EventMeshHttpClientConfig eventMeshHttpClientConfig) throws EventMeshException { + this.cloudEventProducer = new CloudEventProducer(eventMeshHttpClientConfig); + this.eventMeshMessageProducer = new EventMeshMessageProducer(eventMeshHttpClientConfig); + this.openMessageProducer = new OpenMessageProducer(eventMeshHttpClientConfig); + } + + public void publish(final EventMeshMessage message) throws EventMeshException { + eventMeshMessageProducer.publish(message); + } + + public void publish(final CloudEvent cloudEvent) throws EventMeshException { + cloudEventProducer.publish(cloudEvent); + } + + public void publish(final Message openMessage) throws EventMeshException { + openMessageProducer.publish(openMessage); + } + + public EventMeshMessage request(final EventMeshMessage message, final long timeout) throws EventMeshException { + return eventMeshMessageProducer.request(message, timeout); + } + + public CloudEvent request(final CloudEvent cloudEvent, final long timeout) throws EventMeshException { + return cloudEventProducer.request(cloudEvent, timeout); + } + + public Message request(final Message openMessage, final long timeout) throws EventMeshException { + return openMessageProducer.request(openMessage, timeout); + } + + public void request(final EventMeshMessage message, final RRCallback rrCallback, final long timeout) + throws EventMeshException { + eventMeshMessageProducer.request(message, rrCallback, timeout); + } + + public void request(final CloudEvent cloudEvent, final RRCallback rrCallback, final long timeout) + throws EventMeshException { + cloudEventProducer.request(cloudEvent, rrCallback, timeout); + } + + public void request(final Message openMessage, final RRCallback rrCallback, final long timeout) + throws EventMeshException { + openMessageProducer.request(openMessage, rrCallback, timeout); + } + + @Override + public void close() throws EventMeshException { + try ( + final EventMeshMessageProducer ignored = eventMeshMessageProducer; + final OpenMessageProducer ignored1 = openMessageProducer; + final CloudEventProducer ignored2 = cloudEventProducer) { + log.info("Close producer"); + } + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshMessageProducer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshMessageProducer.java new file mode 100644 index 0000000000..d4fcf505e5 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshMessageProducer.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.producer; + +import org.apache.eventmesh.client.http.AbstractHttpClient; +import org.apache.eventmesh.client.http.EventMeshRetObj; +import org.apache.eventmesh.client.http.ProtocolConstant; +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.model.RequestParam; +import org.apache.eventmesh.client.http.util.HttpUtils; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.ProtocolVersion; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.io.IOException; + +import io.cloudevents.SpecVersion; +import io.netty.handler.codec.http.HttpMethod; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class EventMeshMessageProducer extends AbstractHttpClient implements EventMeshProtocolProducer { + + public EventMeshMessageProducer(EventMeshHttpClientConfig eventMeshHttpClientConfig) throws EventMeshException { + super(eventMeshHttpClientConfig); + } + + @Override + public void publish(EventMeshMessage message) throws EventMeshException { + validateEventMeshMessage(message); + RequestParam requestParam = buildCommonPostParam(message) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + + String target = selectEventMesh(); + try { + String response = HttpUtils.post(httpClient, target, requestParam); + EventMeshRetObj ret = JsonUtils.deserialize(response, EventMeshRetObj.class); + + if (ret.getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } + } catch (Exception exception) { + throw new EventMeshException(String.format("Publish message error, target:%s", target), exception); + } + } + + @Override + public EventMeshMessage request(EventMeshMessage message, long timeout) throws EventMeshException { + validateEventMeshMessage(message); + RequestParam requestParam = buildCommonPostParam(message) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_SYNC.getRequestCode()) + .setTimeout(timeout); + + String target = selectEventMesh(); + + try { + String response = HttpUtils.post(httpClient, target, requestParam); + EventMeshRetObj ret = JsonUtils.deserialize(response, EventMeshRetObj.class); + if (ret.getRetCode() == EventMeshRetCode.SUCCESS.getRetCode()) { + return transformMessage(ret); + } + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } catch (Exception e) { + throw new EventMeshException(String.format("Request message error, target:%s", target), e); + } + } + + @Override + public void request(EventMeshMessage message, RRCallback rrCallback, long timeout) + throws EventMeshException { + validateEventMeshMessage(message); + + RequestParam requestParam = buildCommonPostParam(message) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_SYNC.getRequestCode()) + .setTimeout(timeout); + + String target = selectEventMesh(); + RRCallbackResponseHandlerAdapter adapter = + new RRCallbackResponseHandlerAdapter<>(message, rrCallback, timeout); + try { + HttpUtils.post(httpClient, null, target, requestParam, adapter); + } catch (IOException e) { + throw new EventMeshException(String.format("Request message error, target:%s", target), e); + } + } + + private void validateEventMeshMessage(EventMeshMessage message) { + Preconditions.checkNotNull(message, "eventMeshMessage invalid"); + Preconditions.checkNotNull(message.getTopic(), "eventMeshMessage[topic] invalid"); + Preconditions.checkNotNull(message.getContent(), "eventMeshMessage[content] invalid"); + } + + private RequestParam buildCommonPostParam(EventMeshMessage message) { + RequestParam requestParam = new RequestParam(HttpMethod.POST); + requestParam + .addHeader(ProtocolKey.ClientInstanceKey.ENV, eventMeshHttpClientConfig.getEnv()) + .addHeader(ProtocolKey.ClientInstanceKey.IDC, eventMeshHttpClientConfig.getIdc()) + .addHeader(ProtocolKey.ClientInstanceKey.IP, eventMeshHttpClientConfig.getIp()) + .addHeader(ProtocolKey.ClientInstanceKey.PID, eventMeshHttpClientConfig.getPid()) + .addHeader(ProtocolKey.ClientInstanceKey.SYS, eventMeshHttpClientConfig.getSys()) + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME, eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD, eventMeshHttpClientConfig.getPassword()) + .addHeader(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()) + .addHeader(ProtocolKey.PROTOCOL_TYPE, ProtocolConstant.EM_MESSAGE_PROTOCOL) + .addHeader(ProtocolKey.PROTOCOL_DESC, ProtocolConstant.PROTOCOL_DESC) + //default ce version is 1.0 + .addHeader(ProtocolKey.PROTOCOL_VERSION, SpecVersion.V1.toString()) + .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) + .addBody(SendMessageRequestBody.PRODUCERGROUP, eventMeshHttpClientConfig.getProducerGroup()) + // todo: set message to content is better + .addBody(SendMessageRequestBody.TOPIC, message.getTopic()) + .addBody(SendMessageRequestBody.CONTENT, message.getContent()) + .addBody(SendMessageRequestBody.TTL, message.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL)) + .addBody(SendMessageRequestBody.BIZSEQNO, message.getBizSeqNo()) + .addBody(SendMessageRequestBody.UNIQUEID, message.getUniqueId()); + return requestParam; + } + + private EventMeshMessage transformMessage(EventMeshRetObj retObj) { + SendMessageResponseBody.ReplyMessage replyMessage = JsonUtils.deserialize(retObj.getRetMsg(), + SendMessageResponseBody.ReplyMessage.class); + return EventMeshMessage.builder() + .content(replyMessage.body) + .prop(replyMessage.properties) + .topic(replyMessage.topic).build(); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshProtocolProducer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshProtocolProducer.java new file mode 100644 index 0000000000..b3ad6a7956 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshProtocolProducer.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.producer; + +import org.apache.eventmesh.common.exception.EventMeshException; + +/** + * EventMeshProducer, SDK should implement this interface. + *

    + *
  • {@link EventMeshProtocolProducer}
  • + *
  • {@link OpenMessageProducer}
  • + *
  • {@link CloudEventProducer}
  • + *
+ */ +public interface EventMeshProtocolProducer extends AutoCloseable { + + void publish(ProtocolMessage eventMeshMessage) throws EventMeshException; + + ProtocolMessage request(ProtocolMessage message, long timeout) throws EventMeshException; + + void request(ProtocolMessage message, RRCallback rrCallback, long timeout) + throws EventMeshException; + +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/OpenMessageProducer.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/OpenMessageProducer.java new file mode 100644 index 0000000000..b817158cdc --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/OpenMessageProducer.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.producer; + +import org.apache.eventmesh.client.http.AbstractHttpClient; +import org.apache.eventmesh.client.http.EventMeshRetObj; +import org.apache.eventmesh.client.http.ProtocolConstant; +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.model.RequestParam; +import org.apache.eventmesh.client.http.util.HttpUtils; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.http.common.RequestCode; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.io.IOException; + +import io.netty.handler.codec.http.HttpMethod; +import io.openmessaging.api.Message; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class OpenMessageProducer extends AbstractHttpClient implements EventMeshProtocolProducer { + + public OpenMessageProducer(EventMeshHttpClientConfig eventMeshHttpClientConfig) + throws EventMeshException { + super(eventMeshHttpClientConfig); + } + + @Override + public void publish(Message openMessage) throws EventMeshException { + validateOpenMessage(openMessage); + RequestParam requestParam = buildCommonPostParam(openMessage) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + String target = selectEventMesh(); + try { + String response = HttpUtils.post(httpClient, target, requestParam); + EventMeshRetObj ret = JsonUtils.deserialize(response, EventMeshRetObj.class); + + if (ret.getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } + } catch (Exception exception) { + throw new EventMeshException(String.format("Publish message error, target:%s", target), exception); + } + } + + @Override + public Message request(Message message, long timeout) throws EventMeshException { + validateOpenMessage(message); + RequestParam requestParam = buildCommonPostParam(message) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_SYNC.getRequestCode()) + .setTimeout(timeout); + String target = selectEventMesh(); + + try { + String response = HttpUtils.post(httpClient, target, requestParam); + EventMeshRetObj ret = JsonUtils.deserialize(response, EventMeshRetObj.class); + if (ret.getRetCode() == EventMeshRetCode.SUCCESS.getRetCode()) { + return transformMessage(ret); + } + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } catch (Exception e) { + throw new EventMeshException(String.format("Request message error, target:%s", target), e); + } + } + + @Override + public void request(Message message, RRCallback rrCallback, long timeout) throws EventMeshException { + validateOpenMessage(message); + RequestParam requestParam = buildCommonPostParam(message) + .addHeader(ProtocolKey.REQUEST_CODE, RequestCode.MSG_SEND_SYNC.getRequestCode()) + .setTimeout(timeout); + String target = selectEventMesh(); + RRCallbackResponseHandlerAdapter adapter = + new RRCallbackResponseHandlerAdapter<>(message, rrCallback, timeout); + try { + HttpUtils.post(httpClient, null, target, requestParam, adapter); + } catch (IOException e) { + throw new EventMeshException(String.format("Request message error, target:%s", target), e); + } + } + + private void validateOpenMessage(Message openMessage) { + Preconditions.checkNotNull(openMessage, "Message cannot be null"); + } + + private RequestParam buildCommonPostParam(Message openMessage) { + RequestParam requestParam = new RequestParam(HttpMethod.POST); + requestParam + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME, eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD, eventMeshHttpClientConfig.getPassword()) + .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) + .addHeader(ProtocolKey.PROTOCOL_TYPE, ProtocolConstant.OP_MESSAGE_PROTOCOL) + .addHeader(ProtocolKey.PROTOCOL_DESC, ProtocolConstant.PROTOCOL_DESC) + // todo: add producerGroup to header, set protocol type, protocol version + .addBody(SendMessageRequestBody.PRODUCERGROUP, eventMeshHttpClientConfig.getProducerGroup()) + .addBody(SendMessageRequestBody.CONTENT, JsonUtils.serialize(openMessage)); + return requestParam; + } + + private Message transformMessage(EventMeshRetObj retObj) { + SendMessageResponseBody.ReplyMessage replyMessage = JsonUtils.deserialize(retObj.getRetMsg(), + SendMessageResponseBody.ReplyMessage.class); + // todo: deserialize message + return null; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/RRCallback.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/RRCallback.java new file mode 100644 index 0000000000..08470961a2 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/RRCallback.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.producer; + +/** + * ProtocolMessage can be + *
    + *
  • {@link org.apache.eventmesh.common.EventMeshMessage}
  • + *
  • {@link io.cloudevents.CloudEvent}
  • + *
  • {@link io.openmessaging.api.Message}
  • + *
+ */ +public interface RRCallback { + + void onSuccess(ProtocolMessage protocolMessage); + + void onException(Throwable e); + +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/RRCallbackResponseHandlerAdapter.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/RRCallbackResponseHandlerAdapter.java new file mode 100644 index 0000000000..e3c2229b7a --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/RRCallbackResponseHandlerAdapter.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.producer; + +import org.apache.eventmesh.client.http.EventMeshRetObj; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ResponseHandler; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; + +import io.cloudevents.CloudEvent; +import io.openmessaging.api.Message; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +/** + * RRCallbackResponseHandlerAdapter. + */ +@Slf4j +public class RRCallbackResponseHandlerAdapter implements ResponseHandler { + + private final long createTime; + + private final ProtocolMessage protocolMessage; + + private final RRCallback rrCallback; + + private final long timeout; + + public RRCallbackResponseHandlerAdapter(ProtocolMessage protocolMessage, RRCallback rrCallback, + long timeout) { + Preconditions.checkNotNull(rrCallback, "rrCallback invalid"); + Preconditions.checkNotNull(protocolMessage, "message invalid"); + if (!(protocolMessage instanceof EventMeshMessage) + && !(protocolMessage instanceof CloudEvent) + && !(protocolMessage instanceof Message)) { + throw new IllegalArgumentException(String.format("ProtocolMessage: %s is not supported", protocolMessage)); + } + this.protocolMessage = protocolMessage; + this.rrCallback = rrCallback; + this.timeout = timeout; + this.createTime = System.currentTimeMillis(); + } + + @Override + public String handleResponse(HttpResponse response) throws IOException { + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + rrCallback.onException(new EventMeshException(response.toString())); + return response.toString(); + } + + if (System.currentTimeMillis() - createTime > timeout) { + String err = String.format("response too late, message: %s", protocolMessage); + rrCallback.onException(new EventMeshException(err)); + return err; + } + + String res = EntityUtils.toString(response.getEntity(), Charset.forName(Constants.DEFAULT_CHARSET)); + EventMeshRetObj ret = JsonUtils.deserialize(res, EventMeshRetObj.class); + if (ret.getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + rrCallback.onException(new EventMeshException(ret.getRetCode(), ret.getRetMsg())); + return res; + } + + // todo: constructor protocol message + ProtocolMessage protocolMessage = transformToProtocolMessage(ret); + rrCallback.onSuccess(protocolMessage); + + return protocolMessage.toString(); + } + + @SuppressWarnings("unchecked") + private ProtocolMessage transformToProtocolMessage(EventMeshRetObj ret) { + SendMessageResponseBody.ReplyMessage replyMessage = JsonUtils.deserialize(ret.getRetMsg(), SendMessageResponseBody.ReplyMessage.class); + if (protocolMessage instanceof EventMeshMessage) { + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .content(replyMessage.body) + .prop(replyMessage.properties) + .topic(replyMessage.topic) + .build(); + return (ProtocolMessage) eventMeshMessage; + } + // todo: constructor other protocol message + throw new RuntimeException("Unsupported callback message type"); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ssl/MyX509TrustManager.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ssl/MyX509TrustManager.java new file mode 100644 index 0000000000..1a50038cab --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ssl/MyX509TrustManager.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.ssl; + +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.security.KeyStore; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +public class MyX509TrustManager implements X509TrustManager { + X509TrustManager myTrustManager; + + public MyX509TrustManager() throws Exception { + KeyStore keyStore = KeyStore.getInstance("JKS"); + String fileName = System.getProperty("ssl.client.cer", ""); + String pass = System.getProperty("ssl.client.pass", ""); + char[] filePass = null; + if (StringUtils.isNotBlank(pass)) { + filePass = pass.toCharArray(); + } + keyStore.load(Files.newInputStream(Paths.get(System.getProperty("confPath", System.getenv("confPath")) + + File.separator + + fileName), StandardOpenOption.READ), filePass); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(keyStore); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + for (TrustManager trustManager : trustManagers) { + if (trustManager instanceof X509TrustManager) { + myTrustManager = (X509TrustManager) trustManager; + return; + } + } + throw new Exception("Couldn't initialize"); + } + + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException { + if ((certificates != null) && (certificates.length == 1)) { + certificates[0].checkValidity(); + } else { + myTrustManager.checkServerTrusted(certificates, authType); + } + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return myTrustManager.getAcceptedIssuers(); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtils.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtils.java new file mode 100644 index 0000000000..0b17d01ca8 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtils.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.util; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.loadbalance.LoadBalanceSelector; +import org.apache.eventmesh.common.loadbalance.RandomLoadBalanceSelector; +import org.apache.eventmesh.common.loadbalance.Weight; +import org.apache.eventmesh.common.loadbalance.WeightRandomLoadBalanceSelector; +import org.apache.eventmesh.common.loadbalance.WeightRoundRobinLoadBalanceSelector; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import com.google.common.base.Splitter; + +public class HttpLoadBalanceUtils { + + private static final Pattern IP_PORT_PATTERN = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}:\\d{4,5}"); + private static final Pattern IP_PORT_WEIGHT_PATTERN = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}:\\d{4,5}:\\d{1,6}"); + + public static LoadBalanceSelector createEventMeshServerLoadBalanceSelector( + EventMeshHttpClientConfig eventMeshHttpClientConfig) + throws EventMeshException { + LoadBalanceSelector eventMeshServerSelector = null; + switch (eventMeshHttpClientConfig.getLoadBalanceType()) { + case RANDOM: + eventMeshServerSelector = new RandomLoadBalanceSelector<>(buildClusterGroupFromConfig( + eventMeshHttpClientConfig)); + break; + case WEIGHT_RANDOM: + eventMeshServerSelector = new WeightRandomLoadBalanceSelector<>(buildWeightedClusterGroupFromConfig( + eventMeshHttpClientConfig)); + break; + case WEIGHT_ROUND_ROBIN: + eventMeshServerSelector = new WeightRoundRobinLoadBalanceSelector<>(buildWeightedClusterGroupFromConfig( + eventMeshHttpClientConfig)); + break; + default: + // ignore + } + if (eventMeshServerSelector == null) { + throw new EventMeshException("liteEventMeshAddr param illegal,please check"); + } + return eventMeshServerSelector; + } + + private static List> buildWeightedClusterGroupFromConfig( + EventMeshHttpClientConfig eventMeshHttpClientConfig) + throws EventMeshException { + List eventMeshAddrs = Splitter.on(";").trimResults().splitToList(eventMeshHttpClientConfig.getLiteEventMeshAddr()); + if (CollectionUtils.isEmpty(eventMeshAddrs)) { + throw new EventMeshException("liteEventMeshAddr can not be empty"); + } + + List> eventMeshAddrWeightList = new ArrayList<>(); + for (String eventMeshAddrWight : eventMeshAddrs) { + if (!IP_PORT_WEIGHT_PATTERN.matcher(eventMeshAddrWight).matches()) { + throw new EventMeshException( + String.format("liteEventMeshAddr:%s is not illegal", eventMeshHttpClientConfig.getLiteEventMeshAddr())); + } + int splitIndex = eventMeshAddrWight.lastIndexOf(":"); + Weight weight = new Weight<>( + eventMeshAddrWight.substring(0, splitIndex), + Integer.parseInt(eventMeshAddrWight.substring(splitIndex + 1)) + ); + eventMeshAddrWeightList.add(weight); + } + return eventMeshAddrWeightList; + } + + private static List buildClusterGroupFromConfig(EventMeshHttpClientConfig eventMeshHttpClientConfig) + throws EventMeshException { + List eventMeshAddrs = Splitter.on(";").trimResults().splitToList(eventMeshHttpClientConfig.getLiteEventMeshAddr()); + if (CollectionUtils.isEmpty(eventMeshAddrs)) { + throw new EventMeshException("liteEventMeshAddr can not be empty"); + } + + List eventMeshAddrList = new ArrayList<>(); + for (String eventMeshAddr : eventMeshAddrs) { + if (!IP_PORT_PATTERN.matcher(eventMeshAddr).matches()) { + throw new EventMeshException( + String.format("liteEventMeshAddr:%s is not illegal", eventMeshHttpClientConfig.getLiteEventMeshAddr())); + } + eventMeshAddrList.add(eventMeshAddr); + } + return eventMeshAddrList; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpUtils.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpUtils.java new file mode 100644 index 0000000000..23e1546dd3 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpUtils.java @@ -0,0 +1,248 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.util; + +import org.apache.eventmesh.client.http.model.RequestParam; +import org.apache.eventmesh.common.Constants; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; +import org.apache.http.NameValuePair; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import io.netty.handler.codec.http.HttpMethod; + +import com.google.common.base.Preconditions; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HttpUtils { + + public static String post(CloseableHttpClient client, + String uri, + RequestParam requestParam) throws Exception { + final ResponseHolder responseHolder = new ResponseHolder(); + final CountDownLatch countDownLatch = new CountDownLatch(1); + post(client, null, uri, requestParam, response -> { + responseHolder.response = + EntityUtils.toString(response.getEntity(), Charset.forName(Constants.DEFAULT_CHARSET)); + countDownLatch.countDown(); + if (log.isDebugEnabled()) { + log.debug("{}", responseHolder); + } + return responseHolder.response; + }); + + try { + countDownLatch.await(requestParam.getTimeout(), TimeUnit.MILLISECONDS); + } catch (InterruptedException ie) { + //ignore + } + + return responseHolder.response; + } + + public static String post(CloseableHttpClient client, + HttpHost forwardAgent, + String uri, + RequestParam requestParam) throws Exception { + final ResponseHolder responseHolder = new ResponseHolder(); + final CountDownLatch countDownLatch = new CountDownLatch(1); + post(client, forwardAgent, uri, requestParam, response -> { + responseHolder.response = + EntityUtils.toString(response.getEntity(), Charset.forName(Constants.DEFAULT_CHARSET)); + countDownLatch.countDown(); + if (log.isDebugEnabled()) { + log.debug("{}", responseHolder); + } + return responseHolder.response; + }); + + try { + countDownLatch.await(requestParam.getTimeout(), TimeUnit.MILLISECONDS); + } catch (InterruptedException ie) { + // ignore + } + + return responseHolder.response; + } + + public static void post(CloseableHttpClient client, + HttpHost forwardAgent, + String uri, + RequestParam requestParam, + ResponseHandler responseHandler) throws IOException { + Preconditions.checkState(client != null, "client can't be null"); + Preconditions.checkState(StringUtils.isNotBlank(uri), "uri can't be null"); + Preconditions.checkState(requestParam != null, "requestParam can't be null"); + Preconditions.checkState(responseHandler != null, "responseHandler can't be null"); + Preconditions.checkState(requestParam.getHttpMethod() == HttpMethod.POST, "invalid requestParam httpMethod"); + + HttpPost httpPost = new HttpPost(uri); + + //header + if (MapUtils.isNotEmpty(requestParam.getHeaders())) { + for (Map.Entry entry : requestParam.getHeaders().entrySet()) { + httpPost.addHeader(entry.getKey(), entry.getValue()); + } + } + + //body + if (MapUtils.isNotEmpty(requestParam.getBody())) { + List pairs = new ArrayList<>(); + for (Map.Entry entry : requestParam.getBody().entrySet()) { + pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); + } + httpPost.setEntity(new UrlEncodedFormEntity(pairs, Constants.DEFAULT_CHARSET)); + } + + //ttl + RequestConfig.Builder configBuilder = RequestConfig.custom(); + configBuilder.setSocketTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) + .setConnectTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) + .setConnectionRequestTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))); + + if (forwardAgent != null) { + configBuilder.setProxy(forwardAgent); + } + + httpPost.setConfig(configBuilder.build()); + + if (log.isDebugEnabled()) { + log.debug("{}", httpPost); + } + + client.execute(httpPost, responseHandler); + } + + public static void get(CloseableHttpClient client, + HttpHost forwardAgent, + String uri, + RequestParam requestParam, + ResponseHandler responseHandler) throws Exception { + Preconditions.checkState(client != null, "client can't be null"); + Preconditions.checkState(StringUtils.isNotBlank(uri), "uri can't be null"); + Preconditions.checkState(requestParam != null, "requestParam can't be null"); + Preconditions.checkState(requestParam.getHttpMethod() == HttpMethod.GET, "invalid requestParam httpMethod"); + + //body + if (MapUtils.isNotEmpty(requestParam.getQueryParamsMap())) { + uri = uri + "?" + requestParam.getQueryParams(); + } + + HttpGet httpGet = new HttpGet(uri); + + //header + if (MapUtils.isNotEmpty(requestParam.getHeaders())) { + for (Map.Entry entry : requestParam.getHeaders().entrySet()) { + httpGet.addHeader(entry.getKey(), entry.getValue()); + } + } + + //ttl + RequestConfig.Builder configBuilder = RequestConfig.custom(); + configBuilder.setSocketTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) + .setConnectTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) + .setConnectionRequestTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))); + + if (forwardAgent != null) { + configBuilder.setProxy(forwardAgent); + } + + httpGet.setConfig(configBuilder.build()); + + if (log.isDebugEnabled()) { + log.debug("{}", httpGet); + } + + client.execute(httpGet, responseHandler); + } + + public static String get(CloseableHttpClient client, + String url, + RequestParam requestParam) throws Exception { + final ResponseHolder responseHolder = new ResponseHolder(); + final CountDownLatch countDownLatch = new CountDownLatch(1); + get(client, null, url, requestParam, response -> { + responseHolder.response = + EntityUtils.toString(response.getEntity(), Charset.forName(Constants.DEFAULT_CHARSET)); + countDownLatch.countDown(); + if (log.isDebugEnabled()) { + log.debug("{}", responseHolder); + } + return responseHolder.response; + }); + + try { + countDownLatch.await(requestParam.getTimeout(), TimeUnit.MILLISECONDS); + } catch (InterruptedException ie) { + //ignore + } + + return responseHolder.response; + } + + public static String get(CloseableHttpClient client, + HttpHost forwardAgent, + String url, + RequestParam requestParam) throws Exception { + final ResponseHolder responseHolder = new ResponseHolder(); + final CountDownLatch countDownLatch = new CountDownLatch(1); + get(client, forwardAgent, url, requestParam, response -> { + responseHolder.response = + EntityUtils.toString(response.getEntity(), Charset.forName(Constants.DEFAULT_CHARSET)); + countDownLatch.countDown(); + if (log.isDebugEnabled()) { + log.debug("{}", responseHolder); + } + return responseHolder.response; + }); + + try { + countDownLatch.await(requestParam.getTimeout(), TimeUnit.MILLISECONDS); + } catch (InterruptedException ie) { + //ignore + } + + return responseHolder.response; + } + + @Data + public static class ResponseHolder { + public String response; + + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPClient.java new file mode 100644 index 0000000000..60c27afc0e --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPClient.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp; + +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Package; + +/** + * EventMesh TCP client, used to sub/pub message by tcp. + * You can use {@link EventMeshTCPClientFactory} to create a target client. + * + * @param protocol message type + * @since 1.3.0 + */ +public interface EventMeshTCPClient extends AutoCloseable { + + void init() throws EventMeshException; + + Package rr(ProtocolMessage msg, long timeout) throws EventMeshException; + + void asyncRR(ProtocolMessage msg, AsyncRRCallback callback, long timeout) throws EventMeshException; + + Package publish(ProtocolMessage msg, long timeout) throws EventMeshException; + + void broadcast(ProtocolMessage msg, long timeout) throws EventMeshException; + + void listen() throws EventMeshException; + + void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException; + + void unsubscribe() throws EventMeshException; + + void registerPubBusiHandler(ReceiveMsgHook handler) throws EventMeshException; + + void registerSubBusiHandler(ReceiveMsgHook handler) throws EventMeshException; + + void close() throws EventMeshException; + + EventMeshTCPPubClient getPubClient(); + + EventMeshTCPSubClient getSubClient(); +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPClientFactory.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPClientFactory.java new file mode 100644 index 0000000000..69fd2e0a61 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPClientFactory.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp; + +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.impl.cloudevent.CloudEventTCPClient; +import org.apache.eventmesh.client.tcp.impl.eventmeshmessage.EventMeshMessageTCPClient; +import org.apache.eventmesh.client.tcp.impl.openmessage.OpenMessageTCPClient; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; + +import io.cloudevents.CloudEvent; +import io.openmessaging.api.Message; + +import com.google.common.base.Preconditions; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class EventMeshTCPClientFactory { + + /** + * Create target {@link EventMeshTCPClient}. + * + * @param eventMeshTcpClientConfig client config + * @param protocolMessageClass target message protocol class + * @param target message protocol type + * @return Target client + */ + @SuppressWarnings("unchecked") + public static EventMeshTCPClient createEventMeshTCPClient( + EventMeshTCPClientConfig eventMeshTcpClientConfig, Class protocolMessageClass) { + Preconditions.checkNotNull(protocolMessageClass, "ProtocolMessage type cannot be null"); + Preconditions.checkNotNull(eventMeshTcpClientConfig, "EventMeshTcpClientConfig cannot be null"); + + if (protocolMessageClass.isAssignableFrom(EventMeshMessage.class)) { + return (EventMeshTCPClient) new EventMeshMessageTCPClient(eventMeshTcpClientConfig); + } + if (protocolMessageClass.isAssignableFrom(CloudEvent.class)) { + return (EventMeshTCPClient) new CloudEventTCPClient(eventMeshTcpClientConfig); + } + if (protocolMessageClass.isAssignableFrom(Message.class)) { + return (EventMeshTCPClient) new OpenMessageTCPClient(eventMeshTcpClientConfig); + } + throw new IllegalArgumentException( + String.format("ProtocolMessageClass: %s is not supported", protocolMessageClass)); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPPubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPPubClient.java new file mode 100644 index 0000000000..eafe95ec7a --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPPubClient.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp; + +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.tcp.Package; + +/** + * EventMesh TCP publish client. + *
    + *
  • {@link org.apache.eventmesh.client.tcp.impl.cloudevent.CloudEventTCPPubClient}
  • + *
  • {@link org.apache.eventmesh.client.tcp.impl.eventmeshmessage.EventMeshMessageTCPSubClient}
  • + *
  • {@link org.apache.eventmesh.client.tcp.impl.openmessage.OpenMessageTCPPubClient}
  • + *
+ * + * @since 1.3.0 + */ +public interface EventMeshTCPPubClient extends AutoCloseable { + + void init() throws EventMeshException; + + void reconnect() throws EventMeshException; + + // todo: Hide package method, use ProtocolMessage + Package rr(ProtocolMessage event, long timeout) throws EventMeshException; + + void asyncRR(ProtocolMessage event, AsyncRRCallback callback, long timeout) throws EventMeshException; + + Package publish(ProtocolMessage event, long timeout) throws EventMeshException; + + void broadcast(ProtocolMessage event, long timeout) throws EventMeshException; + + void registerBusiHandler(ReceiveMsgHook handler) throws EventMeshException; + + void close() throws EventMeshException; +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPSubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPSubClient.java new file mode 100644 index 0000000000..8b1ec7b372 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/EventMeshTCPSubClient.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp; + +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; + +/** + * EventMesh TCP subscribe client. + *
    + *
  • {@link org.apache.eventmesh.client.tcp.impl.cloudevent.CloudEventTCPSubClient}
  • + *
  • {@link org.apache.eventmesh.client.tcp.impl.eventmeshmessage.EventMeshMessageTCPSubClient}
  • + *
  • {@link org.apache.eventmesh.client.tcp.impl.openmessage.OpenMessageTCPSubClient}
  • + *
+ * + * @since 1.3.0 + */ +public interface EventMeshTCPSubClient extends AutoCloseable { + + void init() throws EventMeshException; + + void reconnect() throws EventMeshException; + + void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException; + + void unsubscribe() throws EventMeshException; + + void listen() throws EventMeshException; + + void registerBusiHandler(ReceiveMsgHook handler) throws EventMeshException; + + void close() throws EventMeshException; +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/AsyncRRCallback.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/AsyncRRCallback.java new file mode 100644 index 0000000000..949c0efa50 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/AsyncRRCallback.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.common; + +/** + * AsyncRRCallback + */ +public interface AsyncRRCallback { + void callback(Package msg); +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/EventMeshCommon.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/EventMeshCommon.java new file mode 100644 index 0000000000..606b24cfe4 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/EventMeshCommon.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.common; + +public class EventMeshCommon { + + /** + * CLIENT heartbeat interval + */ + public static final int HEARTBEAT = 30 * 1000; + + /** + * Timeout time shared by the server + */ + public static final int DEFAULT_TIME_OUT_MILLS = 20 * 1000; + + /** + * USERAGENT for PUB + */ + public static final String USER_AGENT_PURPOSE_PUB = "pub"; + + /** + * USERAGENT for SUB + */ + public static final String USER_AGENT_PURPOSE_SUB = "sub"; + + // protocol type + public static final String CLOUD_EVENTS_PROTOCOL_NAME = "cloudevents"; + public static final String EM_MESSAGE_PROTOCOL_NAME = "eventmeshmessage"; + public static final String OPEN_MESSAGE_PROTOCOL_NAME = "openmessage"; +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/MessageUtils.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/MessageUtils.java new file mode 100644 index 0000000000..e006fa84bf --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/MessageUtils.java @@ -0,0 +1,191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.common; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.Subscription; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +import org.assertj.core.util.Preconditions; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.provider.EventFormatProvider; +import io.openmessaging.api.Message; + +public class MessageUtils { + private static final int seqLength = 10; + + public static Package hello(UserAgent user) { + Package msg = new Package(); + msg.setHeader(new Header(Command.HELLO_REQUEST, 0, null, generateRandomString(seqLength))); + msg.setBody(user); + return msg; + } + + public static Package heartBeat() { + Package msg = new Package(); + msg.setHeader(new Header(Command.HEARTBEAT_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package goodbye() { + Package msg = new Package(); + msg.setHeader(new Header(Command.CLIENT_GOODBYE_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package listen() { + Package msg = new Package(); + msg.setHeader(new Header(Command.LISTEN_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package subscribe(String topic, SubscriptionMode subscriptionMode, + SubscriptionType subscriptionType) { + Package msg = new Package(); + msg.setHeader(new Header(Command.SUBSCRIBE_REQUEST, 0, null, generateRandomString(seqLength))); + msg.setBody(generateSubscription(topic, subscriptionMode, subscriptionType)); + return msg; + } + + public static Package unsubscribe() { + Package msg = new Package(); + msg.setHeader(new Header(Command.UNSUBSCRIBE_REQUEST, 0, null, generateRandomString(seqLength))); + return msg; + } + + public static Package asyncMessageAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.ASYNC_MESSAGE_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static Package buildPackage(Object message, Command command) { + Package msg = new Package(); + msg.setHeader(new Header(command, 0, null, generateRandomString(seqLength))); + if (message instanceof CloudEvent) { + CloudEvent cloudEvent = (CloudEvent) message; + Preconditions.checkNotNull(cloudEvent.getDataContentType(), "DateContentType cannot be null"); + msg.getHeader().putProperty(Constants.PROTOCOL_TYPE, EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME); + msg.getHeader().putProperty(Constants.PROTOCOL_VERSION, cloudEvent.getSpecVersion().toString()); + msg.getHeader().putProperty(Constants.PROTOCOL_DESC, "tcp"); + byte[] bodyByte = EventFormatProvider.getInstance().resolveFormat(cloudEvent.getDataContentType()) + .serialize((CloudEvent) message); + msg.setBody(bodyByte); + } else if (message instanceof EventMeshMessage) { + msg.getHeader().putProperty(Constants.PROTOCOL_TYPE, EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME); + msg.getHeader().putProperty(Constants.PROTOCOL_VERSION, SpecVersion.V1.toString()); + msg.getHeader().putProperty(Constants.PROTOCOL_DESC, "tcp"); + msg.setBody(message); + } else if (message instanceof Message) { + msg.getHeader().putProperty(Constants.PROTOCOL_TYPE, EventMeshCommon.OPEN_MESSAGE_PROTOCOL_NAME); + // todo: this version need to be confirmed. + msg.getHeader().putProperty(Constants.PROTOCOL_VERSION, SpecVersion.V1.toString()); + } else { + // unsupported protocol for server + throw new IllegalArgumentException("Unsupported message protocol"); + } + + return msg; + } + + public static Package broadcastMessageAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.BROADCAST_MESSAGE_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static Package requestToClientAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.REQUEST_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static Package responseToClientAck(Package in) { + Package msg = new Package(); + msg.setHeader(new Header(Command.RESPONSE_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); + msg.setBody(in.getBody()); + return msg; + } + + public static UserAgent generateSubClient(UserAgent agent) { + return UserAgent.builder() + .env(agent.getEnv()) + .host(agent.getHost()) + .password(agent.getPassword()) + .username(agent.getUsername()) + .path(agent.getPath()) + .port(agent.getPort()) + .subsystem(agent.getSubsystem()) + .pid(agent.getPid()) + .version(agent.getVersion()) + .idc(agent.getIdc()) + .group(agent.getGroup()) + .purpose(EventMeshCommon.USER_AGENT_PURPOSE_SUB) + .build(); + } + + public static UserAgent generatePubClient(UserAgent agent) { + return UserAgent.builder() + .env(agent.getEnv()) + .host(agent.getHost()) + .password(agent.getPassword()) + .username(agent.getUsername()) + .path(agent.getPath()) + .port(agent.getPort()) + .subsystem(agent.getSubsystem()) + .pid(agent.getPid()) + .version(agent.getVersion()) + .idc(agent.getIdc()) + .group(agent.getGroup()) + .purpose(EventMeshCommon.USER_AGENT_PURPOSE_PUB) + .build(); + } + + private static Subscription generateSubscription(String topic, SubscriptionMode subscriptionMode, + SubscriptionType subscriptionType) { + Subscription subscription = new Subscription(); + List subscriptionItems = new ArrayList<>(); + subscriptionItems.add(new SubscriptionItem(topic, subscriptionMode, subscriptionType)); + subscription.setTopicList(subscriptionItems); + return subscription; + } + + private static String generateRandomString(int length) { + StringBuilder builder = new StringBuilder(length); + for (int i = 0; i < length; i++) { + builder.append((char) ThreadLocalRandom.current().nextInt(48, 57)); + } + return builder.toString(); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/ReceiveMsgHook.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/ReceiveMsgHook.java new file mode 100644 index 0000000000..802f038bb2 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/ReceiveMsgHook.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.common; + +import java.util.Optional; + +/** + * ReceiveMsgHook. + * + * @param receive message type. + */ +@FunctionalInterface +public interface ReceiveMsgHook { + + /** + * Handle the received message, return the response message. + * + * @param msg + * @return + */ + Optional handle(ProtocolMessage msg); + +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/RequestContext.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/RequestContext.java new file mode 100644 index 0000000000..3021754949 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/RequestContext.java @@ -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 org.apache.eventmesh.client.tcp.common; + +import org.apache.eventmesh.common.protocol.tcp.Package; + +import java.util.concurrent.CountDownLatch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RequestContext { + + private static final Logger logger = LoggerFactory.getLogger(RequestContext.class); + + private Object key; + private Package request; + private Package response; + private CountDownLatch latch; + + public RequestContext(Object key, Package request, CountDownLatch latch) { + this.key = key; + this.request = request; + this.latch = latch; + } + + public Object getKey() { + return key; + } + + public void setKey(Object key) { + this.key = key; + } + + public Package getRequest() { + return request; + } + + public void setRequest(Package request) { + this.request = request; + } + + public Package getResponse() { + return response; + } + + public void setResponse(Package response) { + this.response = response; + } + + public CountDownLatch getLatch() { + return latch; + } + + public void setLatch(CountDownLatch latch) { + this.latch = latch; + } + + public void finish(Package msg) { + this.response = msg; + latch.countDown(); + } + + public static RequestContext context(Object key, Package request, CountDownLatch latch) throws Exception { + RequestContext c = new RequestContext(key, request, latch); + logger.info("_RequestContext|create|key=" + key); + return c; + } + + + public static Object key(Package request) { + return request.getHeader().getSeq(); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java new file mode 100644 index 0000000000..7f37b73a8d --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.common; + +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.common.protocol.tcp.codec.Codec; + +import java.io.Closeable; +import java.net.InetSocketAddress; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.AdaptiveRecvByteBufAllocator; +import io.netty.channel.Channel; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class TcpClient implements Closeable { + + public final int clientNo = (new Random()).nextInt(1000); + + protected final ConcurrentHashMap contexts = new ConcurrentHashMap<>(); + + protected final String host; + protected final int port; + protected final UserAgent userAgent; + + private final Bootstrap bootstrap = new Bootstrap(); + + private final EventLoopGroup workers = new NioEventLoopGroup(); + + private Channel channel; + + private ScheduledFuture heartTask; + + protected static final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor( + Runtime.getRuntime().availableProcessors(), + new ThreadFactoryBuilder().setNameFormat("TCPClientScheduler").setDaemon(true).build()); + + public TcpClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + Preconditions.checkNotNull(eventMeshTcpClientConfig, "EventMeshTcpClientConfig cannot be null"); + Preconditions.checkNotNull(eventMeshTcpClientConfig.getHost(), "Host cannot be null"); + Preconditions.checkState(eventMeshTcpClientConfig.getPort() > 0, "port is not validated"); + this.host = eventMeshTcpClientConfig.getHost(); + this.port = eventMeshTcpClientConfig.getPort(); + this.userAgent = eventMeshTcpClientConfig.getUserAgent(); + } + + protected synchronized void open(SimpleChannelInboundHandler handler) throws Exception { + bootstrap.group(workers); + bootstrap.channel(NioSocketChannel.class); + bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1_000) + .option(ChannelOption.SO_KEEPALIVE, true) + .option(ChannelOption.SO_SNDBUF, 64 * 1024) + .option(ChannelOption.SO_RCVBUF, 64 * 1024) + .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(1024, 8192, 65536)) + .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); + bootstrap.handler(new ChannelInitializer() { + public void initChannel(SocketChannel ch) { + ch.pipeline().addLast(new Codec.Encoder(), new Codec.Decoder()) + .addLast(handler, newExceptionHandler()); + } + }); + + ChannelFuture f = bootstrap.connect(host, port).sync(); + InetSocketAddress localAddress = (InetSocketAddress) f.channel().localAddress(); + channel = f.channel(); + log + .info("connected|local={}:{}|server={}", localAddress.getAddress().getHostAddress(), localAddress.getPort(), + host + ":" + port); + } + + @Override + public void close() { + try { + channel.disconnect().sync(); + workers.shutdownGracefully(); + if (heartTask != null) { + heartTask.cancel(false); + } + goodbye(); + } catch (Exception e) { + Thread.currentThread().interrupt(); + log.warn("close tcp client failed.|remote address={}", channel.remoteAddress(), e); + } + } + + protected void heartbeat() { + if (heartTask == null) { + synchronized (TcpClient.class) { + heartTask = scheduler.scheduleAtFixedRate(() -> { + try { + if (!isActive()) { + reconnect(); + } + Package msg = MessageUtils.heartBeat(); + io(msg, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + log.debug("heart beat start {}", msg); + } catch (Exception ignore) { + // ignore + } + }, EventMeshCommon.HEARTBEAT, EventMeshCommon.HEARTBEAT, TimeUnit.MILLISECONDS); + } + } + } + + protected synchronized void reconnect() throws Exception { + ChannelFuture f = bootstrap.connect(host, port).sync(); + channel = f.channel(); + } + + protected boolean isActive() { + return (channel != null) && (channel.isActive()); + } + + protected void send(Package msg) throws Exception { + if (channel.isWritable()) { + channel.writeAndFlush(msg).addListener((ChannelFutureListener) future -> { + if (!future.isSuccess()) { + log.warn("send msg failed", future.cause()); + } + }); + } else { + channel.writeAndFlush(msg).sync(); + } + } + + protected Package io(Package msg, long timeout) throws Exception { + Object key = RequestContext.key(msg); + CountDownLatch latch = new CountDownLatch(1); + RequestContext c = RequestContext.context(key, msg, latch); + if (!contexts.contains(c)) { + contexts.put(key, c); + } else { + log.info("duplicate key : {}", key); + } + send(msg); + if (!c.getLatch().await(timeout, TimeUnit.MILLISECONDS)) { + throw new TimeoutException("operation timeout, context.key=" + c.getKey()); + } + return c.getResponse(); + } + + // todo: remove hello + protected void hello() throws Exception { + Package msg = MessageUtils.hello(userAgent); + this.io(msg, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } + + // todo: remove goodbye + protected void goodbye() throws Exception { + Package msg = MessageUtils.goodbye(); + this.io(msg, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } + + private ChannelDuplexHandler newExceptionHandler() { + return new ChannelDuplexHandler() { + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + log + .info("exceptionCaught, close connection.|remote address={}", ctx.channel().remoteAddress(), cause); + ctx.close(); + } + }; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/conf/EventMeshTCPClientConfig.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/conf/EventMeshTCPClientConfig.java new file mode 100644 index 0000000000..e47daa9245 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/conf/EventMeshTCPClientConfig.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.conf; + +import org.apache.eventmesh.common.protocol.tcp.UserAgent; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class EventMeshTCPClientConfig { + private String host; + private int port; + private UserAgent userAgent; +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPPubHandler.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPPubHandler.java new file mode 100644 index 0000000000..b83865991a --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPPubHandler.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl; + +import org.apache.eventmesh.client.tcp.common.MessageUtils; +import org.apache.eventmesh.client.tcp.common.RequestContext; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import java.util.concurrent.ConcurrentHashMap; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractEventMeshTCPPubHandler extends SimpleChannelInboundHandler { + + private final ConcurrentHashMap contexts; + + public AbstractEventMeshTCPPubHandler(ConcurrentHashMap contexts) { + this.contexts = contexts; + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Package msg) { + log.info("SimplePubClientImpl|receive|msg={}", msg); + + Preconditions.checkNotNull(msg.getHeader(), "Tcp package header cannot be null"); + Command cmd = msg.getHeader().getCmd(); + switch (cmd) { + case RESPONSE_TO_CLIENT: + callback(getMessage(msg), ctx); + sendResponse(MessageUtils.responseToClientAck(msg)); + break; + case SERVER_GOODBYE_REQUEST: + //TODO + break; + default: + break; + + } + RequestContext context = contexts.get(RequestContext.key(msg)); + if (context != null) { + contexts.remove(context.getKey()); + context.finish(msg); + } + } + + public abstract void callback(ProtocolMessage protocolMessage, ChannelHandlerContext ctx); + + public abstract ProtocolMessage getMessage(Package tcpPackage); + + public abstract void sendResponse(Package tcpPackage); + +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPSubHandler.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPSubHandler.java new file mode 100644 index 0000000000..4669244b9f --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPSubHandler.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl; + +import org.apache.eventmesh.client.tcp.common.MessageUtils; +import org.apache.eventmesh.client.tcp.common.RequestContext; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import java.util.concurrent.ConcurrentHashMap; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractEventMeshTCPSubHandler extends SimpleChannelInboundHandler { + + protected final ConcurrentHashMap contexts; + + public AbstractEventMeshTCPSubHandler(ConcurrentHashMap contexts) { + this.contexts = contexts; + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Exception { + Preconditions.checkNotNull(msg, "TCP package cannot be null"); + Preconditions.checkNotNull(msg.getHeader(), "TCP package header cannot be null"); + Command cmd = msg.getHeader().getCmd(); + log.info("|receive|type={}|msg={}", cmd, msg); + switch (cmd) { + case REQUEST_TO_CLIENT: + callback(getProtocolMessage(msg), ctx); + response(MessageUtils.requestToClientAck(msg)); + break; + case ASYNC_MESSAGE_TO_CLIENT: + callback(getProtocolMessage(msg), ctx); + response(MessageUtils.asyncMessageAck(msg)); + break; + case BROADCAST_MESSAGE_TO_CLIENT: + callback(getProtocolMessage(msg), ctx); + response(MessageUtils.broadcastMessageAck(msg)); + break; + case SERVER_GOODBYE_REQUEST: + // TODO + break; + default: + log.error("msg ignored|{}|{}", cmd, msg); + } + RequestContext context = contexts.get(RequestContext.key(msg)); + if (context != null) { + contexts.remove(context.getKey()); + context.finish(msg); + } else { + log.error("msg ignored,context not found.|{}|{}", cmd, msg); + } + } + + public abstract ProtocolMessage getProtocolMessage(Package tcpPackage); + + public abstract void callback(ProtocolMessage protocolMessage, ChannelHandlerContext ctx); + + public abstract void response(Package tcpPackage); +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPClient.java new file mode 100644 index 0000000000..d81cd84f89 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPClient.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.cloudevent; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPPubClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPSubClient; +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import io.cloudevents.CloudEvent; + +public class CloudEventTCPClient implements EventMeshTCPClient { + + private final CloudEventTCPPubClient cloudEventTCPPubClient; + + private final CloudEventTCPSubClient cloudEventTCPSubClient; + + public CloudEventTCPClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + cloudEventTCPPubClient = new CloudEventTCPPubClient(eventMeshTcpClientConfig); + cloudEventTCPSubClient = new CloudEventTCPSubClient(eventMeshTcpClientConfig); + } + + @Override + public void init() throws EventMeshException { + cloudEventTCPPubClient.init(); + cloudEventTCPSubClient.init(); + } + + @Override + public Package rr(CloudEvent cloudEvent, long timeout) throws EventMeshException { + return cloudEventTCPPubClient.rr(cloudEvent, timeout); + } + + @Override + public void asyncRR(CloudEvent cloudEvent, AsyncRRCallback callback, long timeout) throws EventMeshException { + cloudEventTCPPubClient.asyncRR(cloudEvent, callback, timeout); + } + + @Override + public Package publish(CloudEvent cloudEvent, long timeout) throws EventMeshException { + return cloudEventTCPPubClient.publish(cloudEvent, timeout); + } + + @Override + public void broadcast(CloudEvent cloudEvent, long timeout) throws EventMeshException { + cloudEventTCPPubClient.broadcast(cloudEvent, timeout); + } + + @Override + public void listen() throws EventMeshException { + cloudEventTCPSubClient.listen(); + } + + @Override + public void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException { + cloudEventTCPSubClient.subscribe(topic, subscriptionMode, subscriptionType); + } + + @Override + public void unsubscribe() throws EventMeshException { + cloudEventTCPSubClient.unsubscribe(); + } + + @Override + public void registerPubBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + cloudEventTCPPubClient.registerBusiHandler(handler); + } + + @Override + public void registerSubBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + cloudEventTCPSubClient.registerBusiHandler(handler); + } + + @Override + public void close() throws EventMeshException { + try (final EventMeshTCPPubClient pubClient = cloudEventTCPPubClient; + final EventMeshTCPSubClient subClient = cloudEventTCPSubClient) { + // close client + } + } + + @Override + public EventMeshTCPPubClient getPubClient() { + return cloudEventTCPPubClient; + } + + @Override + public EventMeshTCPSubClient getSubClient() { + return cloudEventTCPSubClient; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPPubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPPubClient.java new file mode 100644 index 0000000000..9be280f563 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPPubClient.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.cloudevent; + +import org.apache.eventmesh.client.tcp.EventMeshTCPPubClient; +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.MessageUtils; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.RequestContext; +import org.apache.eventmesh.client.tcp.common.TcpClient; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.impl.AbstractEventMeshTCPPubHandler; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ConcurrentHashMap; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; +import io.netty.channel.ChannelHandlerContext; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +/** + * A CloudEvent TCP publish client implementation. + */ +@Slf4j +class CloudEventTCPPubClient extends TcpClient implements EventMeshTCPPubClient { + + private ReceiveMsgHook callback; + + private final ConcurrentHashMap callbackConcurrentHashMap = new ConcurrentHashMap<>(); + + public CloudEventTCPPubClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + super(eventMeshTcpClientConfig); + } + + @Override + public void init() throws EventMeshException { + try { + super.open(new CloudEventTCPPubHandler(contexts)); + super.hello(); + super.heartbeat(); + } catch (Exception ex) { + throw new EventMeshException("Initialize EventMeshMessageTCPPubClient error", ex); + } + } + + @Override + public void reconnect() throws EventMeshException { + try { + super.reconnect(); + super.hello(); + } catch (Exception ex) { + throw new EventMeshException("reconnect error", ex); + } + } + + @Override + public Package rr(CloudEvent event, long timeout) throws EventMeshException { + try { + Package msg = MessageUtils.buildPackage(event, Command.REQUEST_TO_SERVER); + log.info("{}|rr|send|type={}|msg={}", clientNo, msg, msg); + return io(msg, timeout); + } catch (Exception ex) { + throw new EventMeshException("rr error", ex); + } + } + + @Override + public void asyncRR(CloudEvent event, AsyncRRCallback callback, long timeout) throws EventMeshException { + try { + Package msg = MessageUtils.buildPackage(event, Command.REQUEST_TO_SERVER); + super.send(msg); + this.callbackConcurrentHashMap.put((String) RequestContext.key(msg), callback); + } catch (Exception ex) { + throw new EventMeshException("asyncRR error", ex); + } + } + + @Override + public Package publish(CloudEvent cloudEvent, long timeout) throws EventMeshException { + try { + Package msg = MessageUtils.buildPackage(cloudEvent, Command.ASYNC_MESSAGE_TO_SERVER); + log.info("SimplePubClientImpl cloud event|{}|publish|send|type={}|protocol={}|msg={}", + clientNo, msg.getHeader().getCmd(), msg.getHeader().getProperty(Constants.PROTOCOL_TYPE), msg); + return io(msg, timeout); + } catch (Exception ex) { + throw new EventMeshException("publish error", ex); + } + } + + @Override + public void broadcast(CloudEvent cloudEvent, long timeout) throws EventMeshException { + try { + Package msg = MessageUtils.buildPackage(cloudEvent, Command.BROADCAST_MESSAGE_TO_SERVER); + log.info("{}|publish|send|type={}|protocol={}|msg={}", clientNo, msg.getHeader().getCmd(), + msg.getHeader().getProperty(Constants.PROTOCOL_TYPE), msg); + super.send(msg); + } catch (Exception ex) { + throw new EventMeshException("Broadcast message error", ex); + } + } + + @Override + public void registerBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + callback = handler; + } + + @Override + public void close() { + try { + super.close(); + } catch (Exception ex) { + log.error("Close CloudEvent TCP publish client error", ex); + } + } + + private class CloudEventTCPPubHandler extends AbstractEventMeshTCPPubHandler { + + public CloudEventTCPPubHandler(ConcurrentHashMap contexts) { + super(contexts); + } + + @Override + public void callback(CloudEvent cloudEvent, ChannelHandlerContext ctx) { + if (callback != null) { + callback.handle(cloudEvent) + .ifPresent(responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER))); + } + } + + @Override + public CloudEvent getMessage(Package tcpPackage) { + EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + Preconditions.checkNotNull(eventFormat, + String.format("Cannot find the cloudevent format: %s", JsonFormat.CONTENT_TYPE)); + return eventFormat.deserialize(tcpPackage.getBody().toString().getBytes(StandardCharsets.UTF_8)); + } + + @Override + public void sendResponse(Package tcpPackage) { + try { + send(tcpPackage); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPSubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPSubClient.java new file mode 100644 index 0000000000..f6eee73e0f --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPSubClient.java @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.cloudevent; + +import org.apache.eventmesh.client.tcp.EventMeshTCPSubClient; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.common.MessageUtils; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.RequestContext; +import org.apache.eventmesh.client.tcp.common.TcpClient; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.impl.AbstractEventMeshTCPSubHandler; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import org.apache.commons.collections4.CollectionUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; +import io.netty.channel.ChannelHandlerContext; + +import com.google.common.base.Preconditions; + +import lombok.extern.slf4j.Slf4j; + +/** + * CloudEvent TCP subscribe client implementation. + */ +@Slf4j +class CloudEventTCPSubClient extends TcpClient implements EventMeshTCPSubClient { + + private final List subscriptionItems = Collections.synchronizedList(new LinkedList<>()); + private ReceiveMsgHook callback; + + public CloudEventTCPSubClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + super(eventMeshTcpClientConfig); + } + + @Override + public void init() throws EventMeshException { + try { + open(new CloudEventTCPSubHandler(contexts)); + hello(); + heartbeat(); + log.info("SimpleSubClientImpl|{}|started!", clientNo); + } catch (Exception ex) { + throw new EventMeshException("Initialize EventMeshMessageTcpSubClient error", ex); + } + } + + @Override + public void reconnect() throws EventMeshException { + try { + super.reconnect(); + hello(); + if (!CollectionUtils.isEmpty(subscriptionItems)) { + for (SubscriptionItem item : subscriptionItems) { + Package request = MessageUtils.subscribe(item.getTopic(), item.getMode(), item.getType()); + this.io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } + } + listen(); + } catch (Exception ex) { + // + } + } + + @Override + public void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException { + try { + subscriptionItems.add(new SubscriptionItem(topic, subscriptionMode, subscriptionType)); + Package request = MessageUtils.subscribe(topic, subscriptionMode, subscriptionType); + io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } catch (Exception ex) { + throw new EventMeshException("Subscribe error", ex); + } + } + + @Override + public void unsubscribe() throws EventMeshException { + try { + Package request = MessageUtils.unsubscribe(); + io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } catch (Exception ex) { + throw new EventMeshException("Unsubscribe error", ex); + } + } + + @Override + public void listen() throws EventMeshException { + try { + Package request = MessageUtils.listen(); + io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } catch (Exception ex) { + throw new EventMeshException("Listen error", ex); + } + } + + @Override + public void registerBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + this.callback = handler; + } + + @Override + public void close() { + try { + goodbye(); + super.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private class CloudEventTCPSubHandler extends AbstractEventMeshTCPSubHandler { + + public CloudEventTCPSubHandler( + ConcurrentHashMap contexts) { + super(contexts); + } + + @Override + public CloudEvent getProtocolMessage(Package tcpPackage) { + EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + Preconditions.checkNotNull(eventFormat, + String.format("Cannot find the cloudevent format: %s", JsonFormat.CONTENT_TYPE)); + return eventFormat.deserialize(tcpPackage.getBody().toString().getBytes(StandardCharsets.UTF_8)); + } + + @Override + public void callback(CloudEvent cloudEvent, ChannelHandlerContext ctx) { + if (callback != null) { + callback.handle(cloudEvent).ifPresent( + responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER)) + ); + } + } + + @Override + public void response(Package tcpPackage) { + try { + send(tcpPackage); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPClient.java new file mode 100644 index 0000000000..a7412daa1b --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPClient.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.eventmeshmessage; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPPubClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPSubClient; +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import com.google.common.base.Preconditions; + +public class EventMeshMessageTCPClient implements EventMeshTCPClient { + + private final EventMeshTCPPubClient eventMeshMessageTCPPubClient; + private final EventMeshTCPSubClient eventMeshMessageTCPSubClient; + + public EventMeshMessageTCPClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + eventMeshMessageTCPPubClient = new EventMeshMessageTCPPubClient(eventMeshTcpClientConfig); + eventMeshMessageTCPSubClient = new EventMeshMessageTCPSubClient(eventMeshTcpClientConfig); + } + + @Override + public void init() throws EventMeshException { + eventMeshMessageTCPPubClient.init(); + eventMeshMessageTCPSubClient.init(); + } + + @Override + public Package rr(EventMeshMessage eventMeshMessage, long timeout) throws EventMeshException { + validateMessage(eventMeshMessage); + return eventMeshMessageTCPPubClient.rr(eventMeshMessage, timeout); + } + + @Override + public void asyncRR(EventMeshMessage eventMeshMessage, AsyncRRCallback callback, long timeout) + throws EventMeshException { + validateMessage(eventMeshMessage); + eventMeshMessageTCPPubClient.asyncRR(eventMeshMessage, callback, timeout); + } + + @Override + public Package publish(EventMeshMessage eventMeshMessage, long timeout) throws EventMeshException { + validateMessage(eventMeshMessage); + return eventMeshMessageTCPPubClient.publish(eventMeshMessage, timeout); + } + + @Override + public void broadcast(EventMeshMessage eventMeshMessage, long timeout) throws EventMeshException { + validateMessage(eventMeshMessage); + eventMeshMessageTCPPubClient.broadcast(eventMeshMessage, timeout); + } + + @Override + public void listen() throws EventMeshException { + eventMeshMessageTCPSubClient.listen(); + } + + @Override + public void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException { + eventMeshMessageTCPSubClient.subscribe(topic, subscriptionMode, subscriptionType); + } + + @Override + public void unsubscribe() throws EventMeshException { + eventMeshMessageTCPSubClient.unsubscribe(); + } + + @Override + public void registerPubBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + eventMeshMessageTCPPubClient.registerBusiHandler(handler); + } + + @Override + public void registerSubBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + eventMeshMessageTCPSubClient.registerBusiHandler(handler); + } + + @Override + public void close() throws EventMeshException { + try (final EventMeshTCPPubClient eventMeshTCPPubClient = eventMeshMessageTCPPubClient; + final EventMeshTCPSubClient eventMeshTCPSubClient = eventMeshMessageTCPSubClient) { + // close client + } + } + + @Override + public EventMeshTCPPubClient getPubClient() { + return eventMeshMessageTCPPubClient; + } + + @Override + public EventMeshTCPSubClient getSubClient() { + return eventMeshMessageTCPSubClient; + } + + private void validateMessage(EventMeshMessage message) { + Preconditions.checkNotNull(message, "Message cannot be null"); + Preconditions.checkArgument(isNotBlank(message.getTopic()), "Message's topic cannot be null and blank"); + Preconditions.checkArgument(isNotBlank(message.getBody()), "Message's body cannot be null and blank"); + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPPubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPPubClient.java new file mode 100644 index 0000000000..9d7b958a0f --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPPubClient.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPPubClient; +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.MessageUtils; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.RequestContext; +import org.apache.eventmesh.client.tcp.common.TcpClient; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.impl.AbstractEventMeshTCPPubHandler; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.util.concurrent.ConcurrentHashMap; + +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +/** + * EventMeshMessage TCP publish client implementation. + */ +@Slf4j +class EventMeshMessageTCPPubClient extends TcpClient implements EventMeshTCPPubClient { + + private ReceiveMsgHook callback; + + private final ConcurrentHashMap callbackConcurrentHashMap = new ConcurrentHashMap<>(); + + public EventMeshMessageTCPPubClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + super(eventMeshTcpClientConfig); + } + + @Override + public void init() throws EventMeshException { + try { + open(new EventMeshTCPPubHandler(contexts)); + hello(); + heartbeat(); + } catch (Exception ex) { + throw new EventMeshException("Initialize EventMeshMessageTCPPubClient error", ex); + } + + } + + @Override + public void reconnect() throws EventMeshException { + try { + super.reconnect(); + hello(); + } catch (Exception ex) { + throw new EventMeshException("reconnect error", ex); + } + } + + // todo: Maybe use org.apache.eventmesh.common.EvetMesh here is better + @Override + public Package rr(EventMeshMessage eventMeshMessage, long timeout) throws EventMeshException { + try { + Package msg = MessageUtils.buildPackage(eventMeshMessage, Command.REQUEST_TO_SERVER); + log.info("{}|rr|send|type={}|msg={}", clientNo, msg, msg); + return io(msg, timeout); + } catch (Exception ex) { + throw new EventMeshException("rr error"); + } + } + + @Override + public void asyncRR(EventMeshMessage eventMeshMessage, AsyncRRCallback callback, long timeout) + throws EventMeshException { + try { + Package msg = MessageUtils.buildPackage(eventMeshMessage, Command.REQUEST_TO_SERVER); + super.send(msg); + this.callbackConcurrentHashMap.put((String) RequestContext.key(msg), callback); + } catch (Exception ex) { + // should trigger callback? + throw new EventMeshException("asyncRR error", ex); + } + } + + @Override + public Package publish(EventMeshMessage eventMeshMessage, long timeout) throws EventMeshException { + try { + Package msg = MessageUtils.buildPackage(eventMeshMessage, Command.ASYNC_MESSAGE_TO_SERVER); + log.info("SimplePubClientImpl em message|{}|publish|send|type={}|protocol={}|msg={}", + clientNo, msg.getHeader().getCmd(), + msg.getHeader().getProperty(Constants.PROTOCOL_TYPE), msg); + return io(msg, timeout); + } catch (Exception ex) { + throw new EventMeshException("publish error", ex); + } + } + + @Override + public void broadcast(EventMeshMessage eventMeshMessage, long timeout) throws EventMeshException { + try { + // todo: transform EventMeshMessage to Package + Package msg = MessageUtils.buildPackage(eventMeshMessage, Command.BROADCAST_MESSAGE_TO_SERVER); + log.info("{}|publish|send|type={}|protocol={}|msg={}", clientNo, msg.getHeader().getCmd(), + msg.getHeader().getProperty(Constants.PROTOCOL_TYPE), msg); + super.send(msg); + } catch (Exception ex) { + throw new EventMeshException("Broadcast message error", ex); + } + } + + @Override + public void registerBusiHandler(ReceiveMsgHook receiveMsgHook) throws EventMeshException { + this.callback = receiveMsgHook; + } + + @Override + public void close() { + try { + super.close(); + } catch (Exception e) { + log.error("Close EventMeshMessage TCP publish client error", e); + } + } + + private class EventMeshTCPPubHandler extends AbstractEventMeshTCPPubHandler { + + public EventMeshTCPPubHandler(ConcurrentHashMap contexts) { + super(contexts); + } + + @Override + public void callback(EventMeshMessage eventMeshMessage, ChannelHandlerContext ctx) { + if (callback != null) { + callback.handle(eventMeshMessage).ifPresent( + responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER)) + ); + } + } + + @Override + public EventMeshMessage getMessage(Package tcpPackage) { + return JsonUtils.deserialize(tcpPackage.getBody().toString(), EventMeshMessage.class); + } + + @Override + public void sendResponse(Package tcpPackage) { + try { + send(tcpPackage); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + } + +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPSubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPSubClient.java new file mode 100644 index 0000000000..5ff5587b5d --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPSubClient.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.eventmeshmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPSubClient; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.client.tcp.common.MessageUtils; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.common.RequestContext; +import org.apache.eventmesh.client.tcp.common.TcpClient; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.impl.AbstractEventMeshTCPSubHandler; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class EventMeshMessageTCPSubClient extends TcpClient implements EventMeshTCPSubClient { + + private final List subscriptionItems = Collections.synchronizedList(new LinkedList<>()); + private ReceiveMsgHook callback; + + public EventMeshMessageTCPSubClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + super(eventMeshTcpClientConfig); + } + + @Override + public void init() throws EventMeshException { + try { + open(new EventMeshMessageTCPSubHandler(contexts)); + hello(); + heartbeat(); + log.info("SimpleSubClientImpl|{}|started!", clientNo); + } catch (Exception ex) { + throw new EventMeshException("Initialize EventMeshMessageTcpSubClient error", ex); + } + } + + @Override + public void reconnect() throws EventMeshException { + try { + super.reconnect(); + hello(); + if (!CollectionUtils.isEmpty(subscriptionItems)) { + for (SubscriptionItem item : subscriptionItems) { + Package request = MessageUtils.subscribe(item.getTopic(), item.getMode(), item.getType()); + this.io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } + } + listen(); + } catch (Exception ex) { + // + } + } + + @Override + public void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException { + try { + subscriptionItems.add(new SubscriptionItem(topic, subscriptionMode, subscriptionType)); + Package request = MessageUtils.subscribe(topic, subscriptionMode, subscriptionType); + io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } catch (Exception ex) { + throw new EventMeshException("Subscribe error", ex); + } + } + + @Override + public void unsubscribe() throws EventMeshException { + try { + Package request = MessageUtils.unsubscribe(); + io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } catch (Exception ex) { + throw new EventMeshException("Unsubscribe error", ex); + } + } + + public void listen() throws EventMeshException { + try { + Package request = MessageUtils.listen(); + io(request, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + } catch (Exception ex) { + throw new EventMeshException("Listen error", ex); + } + } + + + @Override + public void registerBusiHandler(ReceiveMsgHook receiveMsgHook) throws EventMeshException { + this.callback = receiveMsgHook; + } + + @Override + public void close() { + try { + super.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private class EventMeshMessageTCPSubHandler extends AbstractEventMeshTCPSubHandler { + public EventMeshMessageTCPSubHandler(ConcurrentHashMap contexts) { + super(contexts); + } + + @Override + public EventMeshMessage getProtocolMessage(Package tcpPackage) { + return JsonUtils.deserialize(tcpPackage.getBody().toString(), EventMeshMessage.class); + } + + @Override + public void callback(EventMeshMessage eventMeshMessage, ChannelHandlerContext ctx) { + if (callback != null) { + callback.handle(eventMeshMessage).ifPresent( + responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER)) + ); + } + } + + @Override + public void response(Package tcpPackage) { + try { + send(tcpPackage); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPClient.java new file mode 100644 index 0000000000..353ce8f632 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPClient.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.openmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPPubClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPSubClient; +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import io.openmessaging.api.Message; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OpenMessageTCPClient implements EventMeshTCPClient { + + private final EventMeshTCPPubClient eventMeshTCPPubClient; + private final EventMeshTCPSubClient eventMeshTCPSubClient; + + public OpenMessageTCPClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + eventMeshTCPPubClient = new OpenMessageTCPPubClient(eventMeshTcpClientConfig); + eventMeshTCPSubClient = new OpenMessageTCPSubClient(eventMeshTcpClientConfig); + } + + @Override + public void init() throws EventMeshException { + eventMeshTCPPubClient.init(); + eventMeshTCPSubClient.init(); + } + + @Override + public Package rr(Message openMessage, long timeout) throws EventMeshException { + return eventMeshTCPPubClient.rr(openMessage, timeout); + } + + @Override + public void asyncRR(Message openMessage, AsyncRRCallback callback, long timeout) throws EventMeshException { + eventMeshTCPPubClient.asyncRR(openMessage, callback, timeout); + } + + @Override + public Package publish(Message openMessage, long timeout) throws EventMeshException { + return eventMeshTCPPubClient.publish(openMessage, timeout); + } + + @Override + public void broadcast(Message openMessage, long timeout) throws EventMeshException { + eventMeshTCPPubClient.broadcast(openMessage, timeout); + } + + @Override + public void listen() throws EventMeshException { + eventMeshTCPSubClient.listen(); + } + + @Override + public void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException { + eventMeshTCPSubClient.subscribe(topic, subscriptionMode, subscriptionType); + } + + @Override + public void unsubscribe() throws EventMeshException { + eventMeshTCPSubClient.unsubscribe(); + } + + @Override + public void registerPubBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + eventMeshTCPPubClient.registerBusiHandler(handler); + } + + @Override + public void registerSubBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + eventMeshTCPSubClient.registerBusiHandler(handler); + } + + @Override + public void close() throws EventMeshException { + try (final EventMeshTCPPubClient pubClient = eventMeshTCPPubClient; + final EventMeshTCPSubClient subClient = eventMeshTCPSubClient) { + log.info("Close OpenMessageTCPClient"); + } + } + + @Override + public EventMeshTCPPubClient getPubClient() { + return eventMeshTCPPubClient; + } + + @Override + public EventMeshTCPSubClient getSubClient() { + return eventMeshTCPSubClient; + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPPubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPPubClient.java new file mode 100644 index 0000000000..f7482b52d8 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPPubClient.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.openmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPPubClient; +import org.apache.eventmesh.client.tcp.common.AsyncRRCallback; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.tcp.Package; + +import io.openmessaging.api.Message; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class OpenMessageTCPPubClient implements EventMeshTCPPubClient { + + private final EventMeshTCPClientConfig eventMeshTcpClientConfig; + + public OpenMessageTCPPubClient(final EventMeshTCPClientConfig eventMeshTcpClientConfig) { + this.eventMeshTcpClientConfig = eventMeshTcpClientConfig; + } + + @Override + public void init() throws EventMeshException { + + } + + @Override + public void reconnect() throws EventMeshException { + + } + + @Override + public Package rr(Message msg, long timeout) throws EventMeshException { + return null; + } + + @Override + public void asyncRR(Message msg, AsyncRRCallback callback, long timeout) throws EventMeshException { + + } + + @Override + public Package publish(Message cloudEvent, long timeout) throws EventMeshException { + return null; + } + + @Override + public void broadcast(Message cloudEvent, long timeout) throws EventMeshException { + + } + + @Override + public void registerBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + + } + + @Override + public void close() throws EventMeshException { + + } +} diff --git a/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPSubClient.java b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPSubClient.java new file mode 100644 index 0000000000..cf0322a0e1 --- /dev/null +++ b/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/openmessage/OpenMessageTCPSubClient.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl.openmessage; + +import org.apache.eventmesh.client.tcp.EventMeshTCPSubClient; +import org.apache.eventmesh.client.tcp.common.ReceiveMsgHook; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; + +import io.openmessaging.api.Message; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class OpenMessageTCPSubClient implements EventMeshTCPSubClient { + + private final EventMeshTCPClientConfig eventMeshTcpClientConfig; + + public OpenMessageTCPSubClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { + this.eventMeshTcpClientConfig = eventMeshTcpClientConfig; + } + + @Override + public void init() throws EventMeshException { + + } + + @Override + public void reconnect() throws EventMeshException { + + } + + @Override + public void subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) + throws EventMeshException { + + } + + @Override + public void unsubscribe() throws EventMeshException { + + } + + @Override + public void listen() throws EventMeshException { + + } + + @Override + public void registerBusiHandler(ReceiveMsgHook handler) throws EventMeshException { + + } + + @Override + public void close() throws EventMeshException { + + } +} diff --git a/eventmesh-sdk-java/src/main/resources/log4j2.xml b/eventmesh-sdk-java/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..90f56982b0 --- /dev/null +++ b/eventmesh-sdk-java/src/main/resources/log4j2.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumerTest.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumerTest.java new file mode 100644 index 0000000000..68378937f5 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumerTest.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.consumer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.common.protocol.grpc.protos.ConsumerServiceGrpc.ConsumerServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.ConsumerServiceGrpc.ConsumerServiceStub; +import org.apache.eventmesh.common.protocol.grpc.protos.HeartbeatServiceGrpc.HeartbeatServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.Subscription; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import io.grpc.stub.StreamObserver; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ConsumerServiceBlockingStub.class, ConsumerServiceStub.class, HeartbeatServiceBlockingStub.class}) +@PowerMockIgnore({"javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"}) +public class EventMeshGrpcConsumerTest { + + @Mock + private ConsumerServiceBlockingStub consumerClient; + @Mock + private ConsumerServiceStub consumerAsyncClient; + @Mock + private HeartbeatServiceBlockingStub heartbeatClient; + private EventMeshGrpcConsumer eventMeshGrpcConsumer; + + @Before + public void setUp() throws Exception { + eventMeshGrpcConsumer = new EventMeshGrpcConsumer(EventMeshGrpcClientConfig.builder().build()); + eventMeshGrpcConsumer.init(); + eventMeshGrpcConsumer.consumerClient = consumerClient; + eventMeshGrpcConsumer.consumerAsyncClient = consumerAsyncClient; + eventMeshGrpcConsumer.heartbeatClient = heartbeatClient; + when(consumerClient.subscribe(any())).thenReturn(Response.getDefaultInstance()); + when(consumerClient.unsubscribe(any())).thenReturn(Response.getDefaultInstance()); + when(heartbeatClient.heartbeat(any())).thenReturn(Response.getDefaultInstance()); + when(consumerAsyncClient.subscribeStream(any())).thenAnswer(invocation -> { + StreamObserver receiver = invocation.getArgument(0); + return new StreamObserver() { + @Override + public void onNext(Subscription value) { + receiver.onNext( + SimpleMessage.newBuilder().setUniqueId("uniqueId").setSeqNum("1").setContent("mockContent") + .setTopic("mockTopic").build()); + receiver.onCompleted(); + } + + @Override + public void onError(Throwable t) { + receiver.onError(t); + } + + @Override + public void onCompleted() { + } + }; + }); + } + + @Test + public void testSubscribeWithUrl() { + assertThat(eventMeshGrpcConsumer.subscribe(Collections.singletonList(buildMockSubscriptionItem()), + "customUrl")).isEqualTo(Response.getDefaultInstance()); + verify(consumerClient, times(1)).subscribe(any()); + verify(heartbeatClient, Mockito.after(10000L).times(1)).heartbeat(any()); + assertThat(eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(buildMockSubscriptionItem()), + "customUrl")).isEqualTo(Response.getDefaultInstance()); + verify(consumerClient, times(1)).unsubscribe(any()); + } + + @Test + public void testSubscribeStreamWithoutListener() { + eventMeshGrpcConsumer.subscribe(Collections.singletonList(buildMockSubscriptionItem())); + verifyZeroInteractions(consumerAsyncClient); + } + + @Test + public void testSubscribeStream() { + List result = new ArrayList<>(); + eventMeshGrpcConsumer.registerListener(new ReceiveMsgHook() { + @Override + public Optional handle(Object msg) throws Throwable { + result.add(msg); + return Optional.empty(); + } + + @Override + public String getProtocolType() { + return null; + } + }); + eventMeshGrpcConsumer.subscribe(Collections.singletonList(buildMockSubscriptionItem())); + assertThat(result).hasSize(1).first().isInstanceOf(EventMeshMessage.class) + .hasFieldOrPropertyWithValue("bizSeqNo", "1").hasFieldOrPropertyWithValue("uniqueId", "uniqueId") + .hasFieldOrPropertyWithValue("topic", "mockTopic") + .hasFieldOrPropertyWithValue("content", "mockContent"); + verify(consumerAsyncClient, times(1)).subscribeStream(any()); + assertThat(eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(buildMockSubscriptionItem()))).isEqualTo( + Response.getDefaultInstance()); + verify(consumerClient, times(1)).unsubscribe(any()); + } + + private SubscriptionItem buildMockSubscriptionItem() { + SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setType(SubscriptionType.SYNC); + subscriptionItem.setMode(SubscriptionMode.CLUSTERING); + subscriptionItem.setTopic("topic"); + return subscriptionItem; + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducerTest.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducerTest.java new file mode 100644 index 0000000000..6ed0b57850 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducerTest.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.producer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; + +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import io.cloudevents.core.v1.CloudEventV1; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({PublisherServiceBlockingStub.class, Response.class}) +@PowerMockIgnore({"javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"}) +public class CloudEventProducerTest { + + private CloudEventProducer cloudEventProducer; + @Mock + private PublisherServiceBlockingStub blockingStub; + @Mock + private Response mockResponse; + + @Before + public void setUp() throws Exception { + cloudEventProducer = new CloudEventProducer(EventMeshGrpcClientConfig.builder().build(), blockingStub); + when(blockingStub.batchPublish(Mockito.isA(BatchMessage.class))).thenReturn(mockResponse); + when(blockingStub.publish(Mockito.isA(SimpleMessage.class))).thenReturn(mockResponse); + } + + @Test + public void testEnhanceCloudEvent() { + MockCloudEvent mockCloudEvent = new MockCloudEvent(); + Object enhanceCloudEvent; + try { + enhanceCloudEvent = Whitebox.invokeMethod(cloudEventProducer, "enhanceCloudEvent", mockCloudEvent, + null); + } catch (Exception e) { + enhanceCloudEvent = null; + } + assertThat(enhanceCloudEvent).isNotNull().isInstanceOf(CloudEventV1.class) + .hasFieldOrPropertyWithValue("id", mockCloudEvent.getId()) + .hasFieldOrPropertyWithValue("source", mockCloudEvent.getSource()) + .hasFieldOrPropertyWithValue("type", mockCloudEvent.getType()) + .hasFieldOrPropertyWithValue("dataschema", mockCloudEvent.getDataSchema()) + .hasFieldOrPropertyWithValue("subject", mockCloudEvent.getSubject()) + .hasFieldOrPropertyWithValue("data", mockCloudEvent.getData()); + } + + @Test + public void testPublishMultiWithEmpty() { + assertThat(cloudEventProducer.publish(Collections.emptyList())).isNull(); + } + + @Test + public void testPublishMulti() { + assertThat(cloudEventProducer.publish(Collections.singletonList(new MockCloudEvent()))).isEqualTo(mockResponse); + } + + @Test + public void testPublishSingle() { + assertThat(cloudEventProducer.publish(new MockCloudEvent())).isEqualTo(mockResponse); + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducerTest.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducerTest.java new file mode 100644 index 0000000000..8d60fb1166 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducerTest.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.producer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.EventMeshMessage.EventMeshMessageBuilder; +import org.apache.eventmesh.common.protocol.grpc.protos.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Collections; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(PublisherServiceBlockingStub.class) +@PowerMockIgnore({"javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"}) +public class EventMeshGrpcProducerTest { + + private EventMeshGrpcProducer producer; + @Mock + private CloudEventProducer cloudEventProducer; + @Mock + private PublisherServiceBlockingStub stub; + + @Before + public void setUp() throws Exception { + producer = new EventMeshGrpcProducer(EventMeshGrpcClientConfig.builder().build()); + producer.cloudEventProducer = cloudEventProducer; + producer.publisherClient = stub; + doThrow(RuntimeException.class).when(stub).publish( + argThat(argument -> argument != null && StringUtils.equals(argument.getContent(), + "mockExceptionContent"))); + doReturn(Response.getDefaultInstance()).when(stub).publish( + argThat(argument -> argument != null && StringUtils.equals(argument.getContent(), "mockContent"))); + doReturn(Response.getDefaultInstance()).when(stub).batchPublish( + argThat(argument -> argument != null && StringUtils.equals(argument.getTopic(), "mockTopic"))); + doAnswer(invocation -> { + SimpleMessage simpleMessage = invocation.getArgument(0); + if (StringUtils.isEmpty(simpleMessage.getContent())) { + return SimpleMessage.getDefaultInstance(); + } + return SimpleMessage.newBuilder(simpleMessage).build(); + }).when(stub).requestReply(any()); + doReturn(stub).when(stub).withDeadlineAfter(1000, TimeUnit.MILLISECONDS); + when(cloudEventProducer.publish(anyList())).thenReturn(Response.getDefaultInstance()); + } + + @Test + public void testPublishWithException() { + assertThat(producer.publish(defaultEventMeshMessageBuilder().content("mockExceptionContent").build())).isNull(); + } + + @Test + public void testPublishEventMeshMessage() { + assertThat(producer.publish(defaultEventMeshMessageBuilder().build())).isEqualTo(Response.getDefaultInstance()); + } + + @Test + public void testPublishEmptyList() { + assertThat(producer.publish(Collections.emptyList())).isNull(); + } + + @Test + public void testPublishGenericMessageList() { + assertThat(producer.publish(Collections.singletonList(new MockCloudEvent()))).isEqualTo( + Response.getDefaultInstance()); + EventMeshMessageBuilder eventMeshMessageBuilder = defaultEventMeshMessageBuilder(); + eventMeshMessageBuilder.prop(Collections.singletonMap(Constants.EVENTMESH_MESSAGE_CONST_TTL, "1000")); + assertThat(producer.publish(Collections.singletonList(eventMeshMessageBuilder.build()))).isEqualTo( + Response.getDefaultInstance()); + } + + @Test + public void testRequestReply() { + assertThat(producer.requestReply(defaultEventMeshMessageBuilder().content(StringUtils.EMPTY).build(), + 1000)).isNull(); + EventMeshMessage eventMeshMessage = defaultEventMeshMessageBuilder().build(); + assertThat(producer.requestReply(eventMeshMessage, 1000)).hasFieldOrPropertyWithValue("content", + eventMeshMessage.getContent()).hasFieldOrPropertyWithValue("topic", eventMeshMessage.getTopic()); + } + + private EventMeshMessage.EventMeshMessageBuilder defaultEventMeshMessageBuilder() { + return EventMeshMessage.builder().bizSeqNo("bizSeqNo").content("mockContent") + .createTime(System.currentTimeMillis()).uniqueId("mockUniqueId").topic("mockTopic") + .prop(Collections.emptyMap()); + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/MockCloudEvent.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/MockCloudEvent.java new file mode 100644 index 0000000000..e5106472b6 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/MockCloudEvent.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.producer; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.util.Collections; +import java.util.Set; + +import io.cloudevents.CloudEvent; +import io.cloudevents.CloudEventData; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.data.BytesCloudEventData; + +public class MockCloudEvent implements CloudEvent { + + @Override + public CloudEventData getData() { + return BytesCloudEventData.wrap("mockData".getBytes(StandardCharsets.UTF_8)); + } + + @Override + public SpecVersion getSpecVersion() { + return SpecVersion.V1; + } + + @Override + public String getId() { + return "mockId"; + } + + @Override + public String getType() { + return "mockType"; + } + + @Override + public URI getSource() { + return URI.create("mockSource"); + } + + @Override + public String getDataContentType() { + return null; + } + + @Override + public URI getDataSchema() { + return URI.create("mockDataSchema"); + } + + @Override + public String getSubject() { + return "mockSubject"; + } + + @Override + public OffsetDateTime getTime() { + return null; + } + + @Override + public Object getAttribute(String attributeName) throws IllegalArgumentException { + return null; + } + + @Override + public Object getExtension(String extensionName) { + return null; + } + + @Override + public Set getExtensionNames() { + return Collections.emptySet(); + } +} diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtilTest.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtilTest.java new file mode 100644 index 0000000000..4b54314e07 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtilTest.java @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.grpc.util; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.protos.BatchMessage; +import org.apache.eventmesh.common.protocol.grpc.protos.SimpleMessage; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import org.junit.Test; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; + +public class EventMeshClientUtilTest { + + @Test + public void testBuildHeader() { + EventMeshGrpcClientConfig clientConfig = EventMeshGrpcClientConfig.builder().build(); + assertThat(EventMeshClientUtil.buildHeader(clientConfig, "protocolType")).hasFieldOrPropertyWithValue("env", + clientConfig.getEnv()).hasFieldOrPropertyWithValue("idc", clientConfig.getIdc()) + .hasFieldOrPropertyWithValue("ip", IPUtils.getLocalAddress()) + .hasFieldOrPropertyWithValue("pid", Long.toString(ThreadUtils.getPID())) + .hasFieldOrPropertyWithValue("sys", clientConfig.getSys()) + .hasFieldOrPropertyWithValue("language", clientConfig.getLanguage()) + .hasFieldOrPropertyWithValue("username", clientConfig.getUserName()) + .hasFieldOrPropertyWithValue("password", clientConfig.getPassword()) + .hasFieldOrPropertyWithValue("protocolType", "protocolType") + .hasFieldOrPropertyWithValue("protocolDesc", "grpc") + .hasFieldOrPropertyWithValue("protocolVersion", SpecVersion.V1.toString()); + } + + @Test + public void testBuildMessageWithEmptySeq() { + SimpleMessage message = SimpleMessage.newBuilder().setContent("{}").build(); + Object buildMessage = EventMeshClientUtil.buildMessage(message, null); + assertThat(buildMessage).isInstanceOf(HashMap.class); + assertThat(((HashMap) buildMessage)).isEmpty(); + } + + @Test + public void testBuildMessageWithCloudEventProto() { + SimpleMessage message = SimpleMessage.newBuilder().setSeqNum("1").setUniqueId(RandomStringUtils.generateNum(5)) + .setTopic("mockTopic") + .setContent("{\"specversion\":\"1.0\",\"id\":\"id\",\"source\":\"source\",\"type\":\"type\"}").build(); + Object buildMessage = EventMeshClientUtil.buildMessage(message, EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME); + assertThat(buildMessage).isInstanceOf(CloudEvent.class); + CloudEvent cloudEvent = (CloudEvent) buildMessage; + assertThat(cloudEvent).isNotNull().hasFieldOrPropertyWithValue("subject", message.getTopic()); + assertThat(cloudEvent.getExtension(ProtocolKey.SEQ_NUM)).isEqualTo(message.getSeqNum()); + assertThat(cloudEvent.getExtension(ProtocolKey.UNIQUE_ID)).isEqualTo(message.getUniqueId()); + } + + @Test + public void testBuildMessageWithDefaultProto() { + SimpleMessage message = SimpleMessage.newBuilder().setSeqNum("1").setUniqueId(RandomStringUtils.generateNum(5)) + .setTopic("mockTopic").setContent("mockContent").build(); + Object buildMessage = EventMeshClientUtil.buildMessage(message, null); + assertThat(buildMessage).isInstanceOf(EventMeshMessage.class) + .hasFieldOrPropertyWithValue("content", message.getContent()) + .hasFieldOrPropertyWithValue("topic", message.getTopic()) + .hasFieldOrPropertyWithValue("bizSeqNo", message.getSeqNum()) + .hasFieldOrPropertyWithValue("uniqueId", message.getUniqueId()); + } + + @Test + public void buildSimpleMessageWithCloudEventProto() { + CloudEvent cloudEvent = CloudEventBuilder.v1().withSubject("mockSubject").withId("mockId") + .withSource(URI.create("mockSource")).withType("mockType").withExtension(ProtocolKey.SEQ_NUM, "1") + .withExtension(ProtocolKey.UNIQUE_ID, "uniqueId").build(); + EventMeshGrpcClientConfig clientConfig = EventMeshGrpcClientConfig.builder().build(); + assertThat(EventMeshClientUtil.buildSimpleMessage(cloudEvent, clientConfig, + EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME)).hasFieldOrPropertyWithValue("header", + EventMeshClientUtil.buildHeader(clientConfig, EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME)) + .hasFieldOrPropertyWithValue("producerGroup", clientConfig.getProducerGroup()) + .hasFieldOrPropertyWithValue("topic", cloudEvent.getSubject()) + .hasFieldOrPropertyWithValue("ttl", "4000") + .hasFieldOrPropertyWithValue("seqNum", cloudEvent.getExtension(ProtocolKey.SEQ_NUM)) + .hasFieldOrPropertyWithValue("uniqueId", cloudEvent.getExtension(ProtocolKey.UNIQUE_ID)) + .hasFieldOrPropertyWithValue("content", new String( + EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE).serialize(cloudEvent), + StandardCharsets.UTF_8)); + } + + @Test + public void buildSimpleMessageWithDefaultProto() { + EventMeshMessage eventMeshMessage = EventMeshMessage.builder().content("mockContent").topic("mockTopic") + .uniqueId("mockUniqueId").bizSeqNo("mockBizSeqNo").build(); + EventMeshGrpcClientConfig clientConfig = EventMeshGrpcClientConfig.builder().build(); + assertThat( + EventMeshClientUtil.buildSimpleMessage(eventMeshMessage, clientConfig, "")).hasFieldOrPropertyWithValue( + "header", EventMeshClientUtil.buildHeader(clientConfig, "")) + .hasFieldOrPropertyWithValue("producerGroup", clientConfig.getProducerGroup()) + .hasFieldOrPropertyWithValue("topic", eventMeshMessage.getTopic()) + .hasFieldOrPropertyWithValue("ttl", "4000") + .hasFieldOrPropertyWithValue("seqNum", eventMeshMessage.getBizSeqNo()) + .hasFieldOrPropertyWithValue("uniqueId", eventMeshMessage.getUniqueId()) + .hasFieldOrPropertyWithValue("content", eventMeshMessage.getContent()); + } + + @Test + public void buildBatchMessagesWithCloudEventProto() { + List cloudEvents = Collections.singletonList( + CloudEventBuilder.v1().withSubject("mockSubject").withId("mockId").withSource(URI.create("mockSource")) + .withType("mockType").withExtension(ProtocolKey.SEQ_NUM, "1") + .withExtension(ProtocolKey.UNIQUE_ID, "uniqueId").build()); + EventMeshGrpcClientConfig clientConfig = EventMeshGrpcClientConfig.builder().build(); + BatchMessage batchMessage = EventMeshClientUtil.buildBatchMessages(cloudEvents, clientConfig, + EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME); + assertThat(batchMessage).hasFieldOrPropertyWithValue("header", + EventMeshClientUtil.buildHeader(clientConfig, EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME)) + .hasFieldOrPropertyWithValue("topic", cloudEvents.get(0).getSubject()) + .hasFieldOrPropertyWithValue("producerGroup", clientConfig.getProducerGroup()); + assertThat(batchMessage.getMessageItemList()).hasSize(1).first().hasFieldOrPropertyWithValue("content", + new String(EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE) + .serialize(cloudEvents.get(0)), StandardCharsets.UTF_8)) + .hasFieldOrPropertyWithValue("ttl", "4000") + .hasFieldOrPropertyWithValue("seqNum", cloudEvents.get(0).getExtension(ProtocolKey.SEQ_NUM)) + .hasFieldOrPropertyWithValue("uniqueId", cloudEvents.get(0).getExtension(ProtocolKey.UNIQUE_ID)); + assertThat(batchMessage.getMessageItem(0).getPropertiesMap()).containsEntry(ProtocolKey.CONTENT_TYPE, + JsonFormat.CONTENT_TYPE); + } + + @Test + public void buildBatchMessagesWithDefaultProto() { + List eventMeshMessages = Collections.singletonList( + EventMeshMessage.builder().content("mockContent").topic("mockTopic").uniqueId("mockUniqueId") + .bizSeqNo("mockBizSeqNo") + .prop(Collections.singletonMap(Constants.EVENTMESH_MESSAGE_CONST_TTL, "4000")).build()); + EventMeshGrpcClientConfig clientConfig = EventMeshGrpcClientConfig.builder().build(); + BatchMessage batchMessage = EventMeshClientUtil.buildBatchMessages(eventMeshMessages, clientConfig, ""); + assertThat(batchMessage).hasFieldOrPropertyWithValue("header", + EventMeshClientUtil.buildHeader(clientConfig, "")) + .hasFieldOrPropertyWithValue("topic", eventMeshMessages.get(0).getTopic()) + .hasFieldOrPropertyWithValue("producerGroup", clientConfig.getProducerGroup()); + EventMeshMessage firstMeshMessage = eventMeshMessages.get(0); + assertThat(batchMessage.getMessageItemList()).hasSize(1).first() + .hasFieldOrPropertyWithValue("content", firstMeshMessage.getContent()) + .hasFieldOrPropertyWithValue("uniqueId", firstMeshMessage.getUniqueId()) + .hasFieldOrPropertyWithValue("seqNum", firstMeshMessage.getBizSeqNo()) + .hasFieldOrPropertyWithValue("ttl", firstMeshMessage.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL)); + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncPublishInstance.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncPublishInstance.java new file mode 100644 index 0000000000..0e74b3030d --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncPublishInstance.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.demo; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AsyncPublishInstance { + + public static void main(String[] args) throws Exception { + + String eventMeshIPPort = "127.0.0.1:10105"; + final String topic = "TEST-TOPIC-HTTP-ASYNC"; + + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .producerGroup("EventMeshTest-producerGroup") + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())).build(); + + EventMeshHttpProducer eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + for (int i = 0; i < 1; i++) { + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .bizSeqNo(RandomStringUtils.generateNum(30)) + .content("testPublishMessage") + .topic(topic) + .uniqueId(RandomStringUtils.generateNum(30)) + .build() + .addProp(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)); + + eventMeshHttpProducer.publish(eventMeshMessage); + Thread.sleep(1000); + } + Thread.sleep(30000); + try (EventMeshHttpProducer ignore = eventMeshHttpProducer) { + // ignore + } + } +} diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncSyncRequestInstance.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncSyncRequestInstance.java new file mode 100644 index 0000000000..9f84cb6ae6 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncSyncRequestInstance.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.demo; + + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.client.http.producer.RRCallback; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import org.apache.commons.lang3.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AsyncSyncRequestInstance { + + public static Logger logger = LoggerFactory.getLogger(AsyncSyncRequestInstance.class); + + public static void main(String[] args) throws Exception { + + EventMeshHttpProducer eventMeshHttpProducer = null; + try { + //String eventMeshIPPort = args[0]; + String eventMeshIPPort = ""; + //final String topic = args[1]; + final String topic = "TEST-TOPIC-HTTP-ASYNC"; + if (StringUtils.isBlank(eventMeshIPPort)) { + // if has multi value, can config as: 127.0.0.1:10105;127.0.0.2:10105 + eventMeshIPPort = "127.0.0.1:10105"; + } + + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .producerGroup("EventMeshTest-producerGroup") + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())).build(); + + eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + + final long startTime = System.currentTimeMillis(); + final EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .bizSeqNo(RandomStringUtils.generateNum(30)) + .content("testAsyncMessage") + .topic(topic) + .uniqueId(RandomStringUtils.generateNum(30)).build(); + + eventMeshHttpProducer.request(eventMeshMessage, new RRCallback() { + @Override + public void onSuccess(EventMeshMessage o) { + logger.debug("sendmsg : {}, return : {}, cost:{}ms", eventMeshMessage.getContent(), o.getContent(), + System.currentTimeMillis() - startTime); + } + + @Override + public void onException(Throwable e) { + logger.debug("sendmsg failed", e); + } + }, 3000); + + Thread.sleep(2000); + } catch (Exception e) { + logger.warn("async send msg failed", e); + } + + Thread.sleep(30000); + try (final EventMeshHttpProducer ignore = eventMeshHttpProducer) { + // close producer + } catch (Exception e1) { + logger.warn("producer shutdown exception", e1); + } + } +} diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/SyncRequestInstance.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/SyncRequestInstance.java new file mode 100644 index 0000000000..6096438a97 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/SyncRequestInstance.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.http.demo; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.client.http.producer.EventMeshHttpProducer; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.RandomStringUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import org.apache.commons.lang3.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SyncRequestInstance { + + public static Logger logger = LoggerFactory.getLogger(SyncRequestInstance.class); + + public static void main(String[] args) throws Exception { + + EventMeshHttpProducer eventMeshHttpProducer = null; + try { + String eventMeshIPPort = args[0]; + + final String topic = args[1]; + + if (StringUtils.isBlank(eventMeshIPPort)) { + // if has multi value, can config as: 127.0.0.1:10105;127.0.0.2:10105 + eventMeshIPPort = "127.0.0.1:10105"; + } + + EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr(eventMeshIPPort) + .producerGroup("EventMeshTest-producerGroup") + .env("env") + .idc("idc") + .ip(IPUtils.getLocalAddress()) + .sys("1234") + .pid(String.valueOf(ThreadUtils.getPID())).build(); + + eventMeshHttpProducer = new EventMeshHttpProducer(eventMeshClientConfig); + + long startTime = System.currentTimeMillis(); + EventMeshMessage eventMeshMessage = EventMeshMessage.builder() + .bizSeqNo(RandomStringUtils.generateNum(30)) + .content("contentStr with special protocal") + .topic(topic) + .uniqueId(RandomStringUtils.generateNum(30)).build(); + + EventMeshMessage rsp = eventMeshHttpProducer.request(eventMeshMessage, 10000); + if (logger.isDebugEnabled()) { + logger.debug("sendmsg : {}, return : {}, cost:{}ms", eventMeshMessage.getContent(), rsp.getContent(), + System.currentTimeMillis() - startTime); + } + } catch (Exception e) { + logger.warn("send msg failed", e); + } + + Thread.sleep(30000); + try (final EventMeshHttpProducer closed = eventMeshHttpProducer) { + // close producer + } catch (Exception e1) { + logger.warn("producer shutdown exception", e1); + } + } +} diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtilsTest.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtilsTest.java new file mode 100644 index 0000000000..f97c2d81eb --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtilsTest.java @@ -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 org.apache.eventmesh.client.http.util; + +import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.loadbalance.LoadBalanceSelector; +import org.apache.eventmesh.common.loadbalance.LoadBalanceType; + +import org.junit.Assert; +import org.junit.Test; + +public class HttpLoadBalanceUtilsTest { + + @Test + public void testCreateRandomSelector() throws EventMeshException { + EventMeshHttpClientConfig eventMeshHttpClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr("127.0.0.1:1001;127.0.0.2:1002") + .build(); + LoadBalanceSelector randomSelector = HttpLoadBalanceUtils + .createEventMeshServerLoadBalanceSelector(eventMeshHttpClientConfig); + Assert.assertEquals(LoadBalanceType.RANDOM, randomSelector.getType()); + } + + @Test + public void testCreateWeightRoundRobinSelector() throws EventMeshException { + EventMeshHttpClientConfig eventMeshHttpClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr("127.0.0.1:1001:1;127.0.0.2:1001:2") + .loadBalanceType(LoadBalanceType.WEIGHT_ROUND_ROBIN).build(); + LoadBalanceSelector weightRoundRobinSelector = HttpLoadBalanceUtils + .createEventMeshServerLoadBalanceSelector(eventMeshHttpClientConfig); + Assert.assertEquals(LoadBalanceType.WEIGHT_ROUND_ROBIN, weightRoundRobinSelector.getType()); + } + + @Test + public void testCreateWeightRandomSelector() throws EventMeshException { + EventMeshHttpClientConfig eventMeshHttpClientConfig = EventMeshHttpClientConfig.builder() + .liteEventMeshAddr("127.0.0.1:1001:1;127.0.0.2:1001:2") + .loadBalanceType(LoadBalanceType.WEIGHT_RANDOM).build(); + LoadBalanceSelector weightRoundRobinSelector = HttpLoadBalanceUtils + .createEventMeshServerLoadBalanceSelector(eventMeshHttpClientConfig); + Assert.assertEquals(LoadBalanceType.WEIGHT_RANDOM, weightRoundRobinSelector.getType()); + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestCaseTopicSet.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestCaseTopicSet.java new file mode 100644 index 0000000000..669e598a8c --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestCaseTopicSet.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.common; + +/** + * Testcase set + */ +public class EventMeshTestCaseTopicSet { + + // public static final String TOPIC_PRX_WQ2ClientBroadCast = "topic-broadcast-test"; + public static final String TOPIC_PRX_WQ2ClientBroadCast = "TEST-TOPIC-TCP-BROADCAST"; + + // public static final String TOPIC_PRX_SyncSubscribeTest = "topic-sync-test"; + public static final String TOPIC_PRX_SyncSubscribeTest = "TEST-TOPIC-TCP-SYNC"; + + // public static final String TOPIC_PRX_WQ2ClientUniCast = "topic-async-test"; + public static final String TOPIC_PRX_WQ2ClientUniCast = "TEST-TOPIC-TCP-ASYNC"; + +} diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestUtils.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestUtils.java new file mode 100644 index 0000000000..42db31ba81 --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestUtils.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.common; + +import static org.apache.eventmesh.client.tcp.common.EventMeshTestCaseTopicSet.TOPIC_PRX_SyncSubscribeTest; +import static org.apache.eventmesh.client.tcp.common.EventMeshTestCaseTopicSet.TOPIC_PRX_WQ2ClientBroadCast; +import static org.apache.eventmesh.client.tcp.common.EventMeshTestCaseTopicSet.TOPIC_PRX_WQ2ClientUniCast; +import static org.apache.eventmesh.common.protocol.tcp.Command.RESPONSE_TO_SERVER; + +import org.apache.eventmesh.common.protocol.tcp.Command; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; +import org.apache.eventmesh.common.protocol.tcp.Header; +import org.apache.eventmesh.common.protocol.tcp.Package; +import org.apache.eventmesh.common.protocol.tcp.UserAgent; + +import java.util.concurrent.ThreadLocalRandom; + +public class EventMeshTestUtils { + private static final int seqLength = 10; + + public static UserAgent generateClient1() { + return UserAgent.builder() + .host("127.0.0.1") + .password(generateRandomString(8)) + .username("PU4283") + .group("EventmeshTestGroup") + .path("/data/app/umg_proxy") + .port(8362) + .subsystem("5023") + .pid(32893) + .version("2.0.11") + .idc("FT") + .build(); + } + + public static UserAgent generateClient2() { + return UserAgent.builder() + .host("127.0.0.1") + .password(generateRandomString(8)) + .username("PU4283") + .group("EventmeshTestGroup") + .path("/data/app/umg_proxy") + .port(9362) + .subsystem("5017") + .pid(42893) + .version("2.0.11") + .idc("FT").build(); + } + + public static Package syncRR() { + Package msg = new Package(); + msg.setHeader(new Header(Command.REQUEST_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateSyncRRMqMsg()); + return msg; + } + + public static Package asyncRR() { + Package msg = new Package(); + msg.setHeader(new Header(Command.REQUEST_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateAsyncRRMqMsg()); + return msg; + } + + public static Package asyncMessage() { + Package msg = new Package(); + msg.setHeader(new Header(Command.ASYNC_MESSAGE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateAsyncEventMqMsg()); + return msg; + } + + public static Package broadcastMessage() { + Package msg = new Package(); + msg.setHeader(new Header(Command.BROADCAST_MESSAGE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(generateBroadcastMqMsg()); + return msg; + } + + public static Package rrResponse(Package request) { + Package msg = new Package(); + msg.setHeader(new Header(RESPONSE_TO_SERVER, 0, null, generateRandomString(seqLength))); + msg.setBody(request.getBody()); + return msg; + } + + public static EventMeshMessage generateSyncRRMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(TOPIC_PRX_SyncSubscribeTest); + mqMsg.getProperties().put("msgtype", "persistent"); + mqMsg.getProperties().put("TTL", "300000"); + mqMsg.getProperties().put("KEYS", generateRandomString(16)); + mqMsg.setBody("testSyncRR"); + return mqMsg; + } + + + private static EventMeshMessage generateAsyncRRMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(TOPIC_PRX_SyncSubscribeTest); + mqMsg.getProperties().put("REPLY_TO", "10.36.0.109@ProducerGroup-producerPool-9-access#V1_4_0#CI"); + mqMsg.getProperties().put("TTL", "300000"); + mqMsg.getProperties().put("PROPERTY_MESSAGE_REPLY_TO", "notnull"); + mqMsg.setBody("testAsyncRR"); + return mqMsg; + } + + private static EventMeshMessage generateAsyncEventMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(TOPIC_PRX_WQ2ClientUniCast); + mqMsg.getProperties().put("REPLY_TO", "10.36.0.109@ProducerGroup-producerPool-9-access#V1_4_0#CI"); + mqMsg.getProperties().put("TTL", "30000"); + mqMsg.getProperties().put("PROPERTY_MESSAGE_REPLY_TO", "notnull"); + mqMsg.setBody("testAsyncMessage"); + return mqMsg; + } + + public static EventMeshMessage generateBroadcastMqMsg() { + EventMeshMessage mqMsg = new EventMeshMessage(); + mqMsg.setTopic(TOPIC_PRX_WQ2ClientBroadCast); + mqMsg.getProperties().put("REPLY_TO", "10.36.0.109@ProducerGroup-producerPool-9-access#V1_4_0#CI"); + mqMsg.getProperties().put("TTL", "30000"); + mqMsg.getProperties().put("PROPERTY_MESSAGE_REPLY_TO", "notnull"); + mqMsg.setBody("testAsyncMessage"); + return mqMsg; + } + + private static String generateRandomString(int length) { + StringBuilder builder = new StringBuilder(length); + for (int i = 0; i < length; i++) { + builder.append((char) ThreadLocalRandom.current().nextInt(48, 57)); + } + return builder.toString(); + } +} diff --git a/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/impl/EventMeshTCPClientFactoryTest.java b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/impl/EventMeshTCPClientFactoryTest.java new file mode 100644 index 0000000000..3467a9e42a --- /dev/null +++ b/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/impl/EventMeshTCPClientFactoryTest.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.client.tcp.impl; + +import org.apache.eventmesh.client.tcp.EventMeshTCPClient; +import org.apache.eventmesh.client.tcp.EventMeshTCPClientFactory; +import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.client.tcp.impl.cloudevent.CloudEventTCPClient; +import org.apache.eventmesh.client.tcp.impl.eventmeshmessage.EventMeshMessageTCPClient; +import org.apache.eventmesh.client.tcp.impl.openmessage.OpenMessageTCPClient; +import org.apache.eventmesh.common.protocol.tcp.EventMeshMessage; + +import org.junit.Assert; +import org.junit.Test; + +import io.cloudevents.CloudEvent; +import io.openmessaging.api.Message; + +public class EventMeshTCPClientFactoryTest { + + @Test + public void createEventMeshTCPClient() { + EventMeshTCPClientConfig meshTCPClientConfig = EventMeshTCPClientConfig.builder() + .host("localhost") + .port(1234) + .build(); + + + EventMeshTCPClient eventMeshMessageTCPClient = + EventMeshTCPClientFactory.createEventMeshTCPClient(meshTCPClientConfig, EventMeshMessage.class); + Assert.assertEquals(EventMeshMessageTCPClient.class, eventMeshMessageTCPClient.getClass()); + + EventMeshTCPClient cloudEventTCPClient = + EventMeshTCPClientFactory.createEventMeshTCPClient(meshTCPClientConfig, CloudEvent.class); + Assert.assertEquals(CloudEventTCPClient.class, cloudEventTCPClient.getClass()); + + EventMeshTCPClient openMessageTCPClient = + EventMeshTCPClientFactory.createEventMeshTCPClient(meshTCPClientConfig, Message.class); + Assert.assertEquals(OpenMessageTCPClient.class, openMessageTCPClient.getClass()); + } +} \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/resources/application.properties b/eventmesh-sdk-java/src/test/resources/application.properties new file mode 100644 index 0000000000..8bc9ce9a40 --- /dev/null +++ b/eventmesh-sdk-java/src/test/resources/application.properties @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +server.port=8088 \ No newline at end of file diff --git a/eventmesh-sdk-java/src/test/resources/log4j2.xml b/eventmesh-sdk-java/src/test/resources/log4j2.xml new file mode 100644 index 0000000000..4297021f90 --- /dev/null +++ b/eventmesh-sdk-java/src/test/resources/log4j2.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eventmesh-security-plugin/build.gradle b/eventmesh-security-plugin/build.gradle new file mode 100644 index 0000000000..d973dcedae --- /dev/null +++ b/eventmesh-security-plugin/build.gradle @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/eventmesh-security-plugin/eventmesh-security-acl/build.gradle b/eventmesh-security-plugin/eventmesh-security-acl/build.gradle new file mode 100644 index 0000000000..1ee3c750ab --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-acl/build.gradle @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { + implementation project(":eventmesh-security-plugin:eventmesh-security-api") + + testImplementation project(":eventmesh-security-plugin:eventmesh-security-api") +} diff --git a/eventmesh-security-plugin/eventmesh-security-acl/gradle.properties b/eventmesh-security-plugin/eventmesh-security-acl/gradle.properties new file mode 100644 index 0000000000..719ba4fce8 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-acl/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=security +pluginName=acl \ No newline at end of file diff --git a/eventmesh-security-plugin/eventmesh-security-acl/src/main/java/org/apache/eventmesh/acl/impl/AclServiceImpl.java b/eventmesh-security-plugin/eventmesh-security-acl/src/main/java/org/apache/eventmesh/acl/impl/AclServiceImpl.java new file mode 100644 index 0000000000..8d73bc7c9d --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-acl/src/main/java/org/apache/eventmesh/acl/impl/AclServiceImpl.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.acl.impl; + +import org.apache.eventmesh.api.acl.AclService; +import org.apache.eventmesh.api.exception.AclException; + +import java.util.Properties; + +public class AclServiceImpl implements AclService { + @Override + public void init() throws AclException { + //TODO + } + + @Override + public void start() throws AclException { + //TODO + } + + @Override + public void shutdown() throws AclException { + //TODO + } + + @Override + public void doAclCheckInConnect(Properties aclProperties) throws AclException { + //TODO + } + + @Override + public void doAclCheckInHeartbeat(Properties aclProperties) throws AclException { + //TODO + } + + @Override + public void doAclCheckInSend(Properties aclProperties) throws AclException { + //TODO + } + + @Override + public void doAclCheckInReceive(Properties aclProperties) throws AclException { + //TODO + } +} diff --git a/eventmesh-security-plugin/eventmesh-security-acl/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.acl.AclService b/eventmesh-security-plugin/eventmesh-security-acl/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.acl.AclService new file mode 100644 index 0000000000..3225b6c1d3 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-acl/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.acl.AclService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +security=org.apache.eventmesh.acl.impl.AclServiceImpl \ No newline at end of file diff --git a/eventmesh-security-plugin/eventmesh-security-api/build.gradle b/eventmesh-security-plugin/eventmesh-security-api/build.gradle new file mode 100644 index 0000000000..482f87dbe8 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-api/build.gradle @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation 'org.slf4j:slf4j-api' + + api project(":eventmesh-spi") + + testImplementation project(":eventmesh-spi") +} diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclPropertyKeys.java b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclPropertyKeys.java new file mode 100644 index 0000000000..074516fc17 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclPropertyKeys.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.acl; + +public class AclPropertyKeys { + public static final String CLIENT_IP = "clientIp"; + public static final String USER = "user"; + public static final String PASSWORD = "pwd"; + public static final String SUBSYSTEM = "subsystem"; + public static final String TOPIC = "topic"; + public static final String REQUEST_CODE = "requestCode"; + public static final String REQUEST_URI = "requestURI"; +} diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclService.java b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclService.java new file mode 100644 index 0000000000..8387de2900 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclService.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.acl; + +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.Properties; + +/** + * AclService + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.SECURITY) +public interface AclService { + void init() throws AclException; + + void start() throws AclException; + + void shutdown() throws AclException; + + void doAclCheckInConnect(Properties aclProperties) throws AclException; + + void doAclCheckInHeartbeat(Properties aclProperties) throws AclException; + + void doAclCheckInSend(Properties aclProperties) throws AclException; + + void doAclCheckInReceive(Properties aclProperties) throws AclException; + +} diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/auth/AuthService.java b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/auth/AuthService.java new file mode 100644 index 0000000000..d957b50bb4 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/auth/AuthService.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.auth; + +import org.apache.eventmesh.api.exception.AuthException; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.Map; + +/** + * AuthService + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.SECURITY) +public interface AuthService { + + void init() throws AuthException; + + void start() throws AuthException; + + void shutdown() throws AuthException; + + Map getAuthParams() throws AuthException; +} diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/common/ConfigurationWrapper.java b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/common/ConfigurationWrapper.java new file mode 100644 index 0000000000..dc359c1219 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/common/ConfigurationWrapper.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.common; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConfigurationWrapper { + + private static Logger logger = LoggerFactory.getLogger("ConfigurationWrapper"); + + private static final String EVENTMESH_CONFIG_HOME = System.getProperty("confPath", System.getenv("confPath")); + + public static Properties getConfig(String configFile) { + String configFilePath; + + // get from classpath + URL resource = ConfigurationWrapper.class.getClassLoader().getResource(configFile); + if (resource != null && new File(resource.getPath()).exists()) { + configFilePath = resource.getPath(); + } else { + // get from config home + configFilePath = EVENTMESH_CONFIG_HOME + File.separator + configFile; + } + + logger.info("loading auth config: {}", configFilePath); + Properties properties = new Properties(); + try { + properties.load(new BufferedReader(new FileReader(configFilePath))); + } catch (IOException e) { + throw new IllegalArgumentException( + String.format("Cannot load RocketMQ configuration file from :%s", configFilePath)); + } + return properties; + } +} diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/exception/AclException.java b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/exception/AclException.java new file mode 100644 index 0000000000..115be40bec --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/exception/AclException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.exception; + +/** + * AclException + */ +public class AclException extends RuntimeException { + + public AclException(String message) { + super(message); + } + + public AclException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/exception/AuthException.java b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/exception/AuthException.java new file mode 100644 index 0000000000..67bef31d7b --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/exception/AuthException.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.api.exception; + +public class AuthException extends RuntimeException { + + public AuthException(String message) { + super(message); + } + + public AuthException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/build.gradle b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/build.gradle new file mode 100644 index 0000000000..bb0f4d6314 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/build.gradle @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { + implementation project(":eventmesh-security-plugin:eventmesh-security-api") + + testImplementation project(":eventmesh-security-plugin:eventmesh-security-api") +} \ No newline at end of file diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/gradle.properties b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/gradle.properties new file mode 100644 index 0000000000..83021bb0ce --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/gradle.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=security +pluginName=auth-http-basic \ No newline at end of file diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/java/org/apache/eventmesh/auth/http/basic/config/AuthConfigs.java b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/java/org/apache/eventmesh/auth/http/basic/config/AuthConfigs.java new file mode 100644 index 0000000000..c077bf4844 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/java/org/apache/eventmesh/auth/http/basic/config/AuthConfigs.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.auth.http.basic.config; + +import org.apache.eventmesh.api.common.ConfigurationWrapper; + +import java.util.Properties; + +public class AuthConfigs { + + public String username; + + public String password; + + private static AuthConfigs instance; + + public static synchronized AuthConfigs getConfigs() { + if (instance == null) { + Properties props = ConfigurationWrapper.getConfig("auth-http-basic.properties"); + instance = new AuthConfigs(); + instance.username = props.getProperty("auth.username"); + instance.password = props.getProperty("auth.password"); + } + return instance; + } +} diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/java/org/apache/eventmesh/auth/http/basic/impl/AuthHttpBasicService.java b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/java/org/apache/eventmesh/auth/http/basic/impl/AuthHttpBasicService.java new file mode 100644 index 0000000000..c32c98807c --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/java/org/apache/eventmesh/auth/http/basic/impl/AuthHttpBasicService.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.auth.http.basic.impl; + +import org.apache.eventmesh.api.auth.AuthService; +import org.apache.eventmesh.api.exception.AuthException; +import org.apache.eventmesh.auth.http.basic.config.AuthConfigs; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +public class AuthHttpBasicService implements AuthService { + + private AuthConfigs authConfigs; + + @Override + public void init() throws AuthException { + authConfigs = AuthConfigs.getConfigs(); + } + + @Override + public void start() throws AuthException { + + } + + @Override + public void shutdown() throws AuthException { + + } + + @Override + public Map getAuthParams() throws AuthException { + if (authConfigs == null) { + init(); + } + + String token = Base64.getEncoder().encodeToString((authConfigs.username + authConfigs.password) + .getBytes(StandardCharsets.UTF_8)); + + Map authParams = new HashMap(); + authParams.put("Authorization", "Basic " + token); + return authParams; + } +} diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.auth.AuthService b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.auth.AuthService new file mode 100644 index 0000000000..2dde9367be --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.auth.AuthService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +auth-http-basic=org.apache.eventmesh.auth.http.basic.impl.AuthHttpBasicService \ No newline at end of file diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/resources/auth-http-basic.properties b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/resources/auth-http-basic.properties new file mode 100644 index 0000000000..f06e6c11f0 --- /dev/null +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/main/resources/auth-http-basic.properties @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +auth.username = **** +auth.password = **** \ No newline at end of file diff --git a/eventmesh-spi/build.gradle b/eventmesh-spi/build.gradle new file mode 100644 index 0000000000..4980522b47 --- /dev/null +++ b/eventmesh-spi/build.gradle @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +dependencies { + implementation project(":eventmesh-common") + implementation "org.apache.commons:commons-collections4" + testImplementation project(":eventmesh-common") +} \ No newline at end of file diff --git a/eventmesh-spi/gradle.properties b/eventmesh-spi/gradle.properties new file mode 100644 index 0000000000..b1312a0905 --- /dev/null +++ b/eventmesh-spi/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionFactory.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionFactory.java new file mode 100644 index 0000000000..eb4de8aa80 --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionFactory.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi; + +import org.apache.eventmesh.spi.loader.ExtensionClassLoader; +import org.apache.eventmesh.spi.loader.JarExtensionClassLoader; +import org.apache.eventmesh.spi.loader.MetaInfExtensionClassLoader; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The extension fetching factory, all extension plugins should be fetched by this factory. + * And all the extension plugins defined in eventmesh should have {@link EventMeshSPI} annotation. + */ +public class EventMeshExtensionFactory { + + private EventMeshExtensionFactory() { + + } + + private static final Logger logger = LoggerFactory.getLogger(EventMeshExtensionFactory.class); + + private static final List extensionClassLoaders = new ArrayList<>(); + + static { + extensionClassLoaders.add(new MetaInfExtensionClassLoader()); + extensionClassLoaders.add(new JarExtensionClassLoader()); + } + + private static final ConcurrentHashMap EXTENSION_INSTANCE_CACHE = + new ConcurrentHashMap<>(16); + + /** + * @param extensionType extension plugin class type + * @param extensionName extension instance name + * @param the type of the plugin + * @return plugin instance + */ + public static T getExtension(Class extensionType, String extensionName) { + if (extensionType == null) { + throw new ExtensionException("extensionType is null"); + } + if (StringUtils.isEmpty(extensionName)) { + throw new ExtensionException("extensionName is null"); + } + if (!extensionType.isInterface() || !extensionType.isAnnotationPresent(EventMeshSPI.class)) { + throw new ExtensionException(String.format("extensionType:%s is invalided", extensionType)); + } + EventMeshSPI eventMeshSPIAnnotation = extensionType.getAnnotation(EventMeshSPI.class); + if (eventMeshSPIAnnotation.isSingleton()) { + return getSingletonExtension(extensionType, extensionName); + } + return getPrototypeExtension(extensionType, extensionName); + } + + @SuppressWarnings("unchecked") + private static T getSingletonExtension(Class extensionType, String extensionInstanceName) { + return (T) EXTENSION_INSTANCE_CACHE.computeIfAbsent(extensionInstanceName, name -> { + Class extensionInstanceClass = getExtensionInstanceClass(extensionType, extensionInstanceName); + try { + if (extensionInstanceClass == null) { + return null; + } + T extensionInstance = extensionInstanceClass.newInstance(); + logger.info("initialize extension instance success, extensionType: {}, extensionInstanceName: {}", + extensionType, extensionInstanceName); + return extensionInstance; + } catch (InstantiationException | IllegalAccessException e) { + throw new ExtensionException("Extension initialize error", e); + } + }); + } + + private static T getPrototypeExtension(Class extensionType, String extensionInstanceName) { + Class extensionInstanceClass = getExtensionInstanceClass(extensionType, extensionInstanceName); + try { + if (extensionInstanceClass == null) { + return null; + } + T extensionInstance = extensionInstanceClass.newInstance(); + logger.info("initialize extension instance success, extensionType: {}, extensionName: {}", + extensionType, extensionInstanceName); + return extensionInstance; + } catch (InstantiationException | IllegalAccessException e) { + throw new ExtensionException("Extension initialize error", e); + } + } + + @SuppressWarnings("unchecked") + private static Class getExtensionInstanceClass(Class extensionType, String extensionInstanceName) { + for (ExtensionClassLoader extensionClassLoader : extensionClassLoaders) { + Map> extensionInstanceClassMap = extensionClassLoader.loadExtensionClass(extensionType, extensionInstanceName); + Class instanceClass = extensionInstanceClassMap.get(extensionInstanceName); + if (instanceClass != null) { + return (Class) instanceClass; + } + } + return null; + } + +} diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionType.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionType.java new file mode 100644 index 0000000000..5aab9d1df7 --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionType.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi; + +/** + * An Extension can be defined by extensionTypeName and extensionInstanceName + */ +public enum EventMeshExtensionType { + UNKNOWN("unknown"), + CONNECTOR("connector"), + REGISTRY("registry"), + SECURITY("security"), + PROTOCOL("protocol"), + METRICS("metrics"), + TRACE("trace"), + ; + + private final String extensionTypeName; + + EventMeshExtensionType(String extensionTypeName) { + this.extensionTypeName = extensionTypeName; + } + + public String getExtensionTypeName() { + return extensionTypeName; + } + +} diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java new file mode 100644 index 0000000000..a0ae5ecd3e --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Just as a marker for SPI + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface EventMeshSPI { + + /** + * If true, the spi instance is singleton + */ + boolean isSingleton() default false; + + /** + * {@link EventMeshExtensionType} + * + * @return extension type + */ + EventMeshExtensionType eventMeshExtensionType(); + +} + diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/ExtensionException.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/ExtensionException.java new file mode 100644 index 0000000000..874f03da5d --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/ExtensionException.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi; + +public class ExtensionException extends RuntimeException { + + public ExtensionException(Exception e) { + super(e); + } + + public ExtensionException(String message) { + super(message); + } + + public ExtensionException(String message, Exception e) { + super(message, e); + } +} diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/EventMeshExtensionConstant.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/EventMeshExtensionConstant.java new file mode 100644 index 0000000000..d550c35c6c --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/EventMeshExtensionConstant.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.loader; + +public class EventMeshExtensionConstant { + /** + * eventmesh plugin base path + */ + public static final String EVENTMESH_EXTENSION_META_DIR = "META-INF/eventmesh/"; + +} diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/EventMeshUrlClassLoader.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/EventMeshUrlClassLoader.java new file mode 100644 index 0000000000..9a27d495e1 --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/EventMeshUrlClassLoader.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.loader; + +import org.apache.commons.collections4.CollectionUtils; + +import java.net.URL; +import java.net.URLClassLoader; +import java.util.List; + +public class EventMeshUrlClassLoader extends URLClassLoader { + + public static EventMeshUrlClassLoader getInstance() { + return EventMeshUrlClassLoaderHolder.instance; + } + + /** + * Appends the specified URL to the list of URLs to search for classes and resources. + *

+ * If the URL specified is {@code null} or is already in the + * list of URLs, or if this loader is closed, then invoking this + * method has no effect. + *

+ * More detail see {@link URLClassLoader#addURL(URL)} + * + * @param urls + */ + public void addUrls(List urls) { + if (CollectionUtils.isEmpty(urls)) { + return; + } + urls.forEach(this::addURL); + } + + private EventMeshUrlClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); + } + + private static class EventMeshUrlClassLoaderHolder { + private static EventMeshUrlClassLoader instance = new EventMeshUrlClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); + } +} diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/ExtensionClassLoader.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/ExtensionClassLoader.java new file mode 100644 index 0000000000..3e13c33c22 --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/ExtensionClassLoader.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.loader; + +import java.util.Map; + +/** + * Load extension class + *

    + *
  • {@link MetaInfExtensionClassLoader}
  • + *
  • {@link JarExtensionClassLoader}
  • + *
+ */ +public interface ExtensionClassLoader { + + /** + * load extension class + * + * @param extensionType extension type class + * @param extensionInstanceName extension instance name + * @param extension type + * @return extension instance name to extension instance class + */ + Map> loadExtensionClass(Class extensionType, String extensionInstanceName); +} diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/JarExtensionClassLoader.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/JarExtensionClassLoader.java new file mode 100644 index 0000000000..8c7d883f14 --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/JarExtensionClassLoader.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.loader; + +import org.apache.eventmesh.spi.EventMeshSPI; +import org.apache.eventmesh.spi.ExtensionException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; + +/** + * Load extension from '${eventMeshPluginDir}', the default loading directory is './plugin' + */ +public class JarExtensionClassLoader implements ExtensionClassLoader { + + private static final Logger logger = LoggerFactory.getLogger(JarExtensionClassLoader.class); + + private static final String EVENT_MESH_PLUGIN_DIR = "eventMeshPluginDir"; + + private static final ConcurrentHashMap, Map>> EXTENSION_CLASS_CACHE = + new ConcurrentHashMap<>(16); + + private static final String EVENTMESH_EXTENSION_PLUGIN_DIR = + System.getProperty(EVENT_MESH_PLUGIN_DIR, + Joiner.on(File.separator).join(Lists.newArrayList(".", "plugin"))); + + @Override + public Map> loadExtensionClass(Class extensionType, + String extensionInstanceName) { + return EXTENSION_CLASS_CACHE + .computeIfAbsent(extensionType, t -> doLoadExtensionClass(t, extensionInstanceName)); + } + + private Map> doLoadExtensionClass(Class extensionType, + String extensionInstanceName) { + Map> extensionMap = new HashMap<>(16); + EventMeshSPI eventMeshSpiAnnotation = extensionType.getAnnotation(EventMeshSPI.class); + + String pluginDir = Paths.get( + EVENTMESH_EXTENSION_PLUGIN_DIR, + eventMeshSpiAnnotation.eventMeshExtensionType().getExtensionTypeName(), + extensionInstanceName + ).toString(); + + String extensionFileName = + EventMeshExtensionConstant.EVENTMESH_EXTENSION_META_DIR + extensionType.getName(); + EventMeshUrlClassLoader urlClassLoader = EventMeshUrlClassLoader.getInstance(); + urlClassLoader.addUrls(loadJarPathFromResource(pluginDir)); + try { + Enumeration extensionUrls = urlClassLoader.getResources(extensionFileName); + if (extensionUrls != null) { + while (extensionUrls.hasMoreElements()) { + URL url = extensionUrls.nextElement(); + extensionMap.putAll(loadResources(urlClassLoader, url, extensionType)); + } + } + } catch (IOException e) { + throw new ExtensionException("load extension class error", e); + } + return extensionMap; + } + + private List loadJarPathFromResource(String pluginPath) { + File plugin = new File(pluginPath); + if (!plugin.exists()) { + logger.warn("plugin dir:{} is not exist", pluginPath); + return Lists.newArrayList(); + } + if (plugin.isFile() && plugin.getName().endsWith(".jar")) { + try { + return Lists.newArrayList(plugin.toURI().toURL()); + } catch (Exception e) { + throw new ExtensionException(e); + } + } + File[] files = plugin.listFiles(); + List pluginUrls = new ArrayList<>(); + if (files != null) { + for (File file : files) { + pluginUrls.addAll(loadJarPathFromResource(file.getPath())); + } + } + // TODO: Sort the path here just to guarantee load the ConsumeMessageConcurrentlyService + // defined in EventMesh rather than defined in rocketmq + pluginUrls.sort(Comparator.comparing(URL::getPath)); + return pluginUrls; + } + + private static Map> loadResources(URLClassLoader urlClassLoader, URL url, + Class extensionType) + throws IOException { + Map> extensionMap = new HashMap<>(); + try (InputStream inputStream = url.openStream()) { + Properties properties = new Properties(); + properties.load(inputStream); + properties.forEach((extensionName, extensionClass) -> { + String extensionNameStr = (String) extensionName; + String extensionClassStr = (String) extensionClass; + try { + Class targetClass = urlClassLoader.loadClass(extensionClassStr); + logger + .info("load extension class success, extensionType: {}, extensionClass: {}", + extensionType, targetClass); + if (!extensionType.isAssignableFrom(targetClass)) { + throw new ExtensionException( + String.format("class: %s is not subClass of %s", targetClass, + extensionType)); + } + extensionMap.put(extensionNameStr, targetClass); + } catch (ClassNotFoundException e) { + throw new ExtensionException("load extension class error", e); + } + }); + } + return extensionMap; + } +} diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/MetaInfExtensionClassLoader.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/MetaInfExtensionClassLoader.java new file mode 100644 index 0000000000..8e6cc8a56f --- /dev/null +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/loader/MetaInfExtensionClassLoader.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.loader; + +import org.apache.eventmesh.spi.ExtensionException; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Load extension from classpath + */ +public class MetaInfExtensionClassLoader implements ExtensionClassLoader { + + private static final Logger logger = LoggerFactory.getLogger(MetaInfExtensionClassLoader.class); + + private static final ConcurrentHashMap, Map>> EXTENSION_CLASS_CACHE = + new ConcurrentHashMap<>(16); + + @Override + public Map> loadExtensionClass(Class extensionType, String extensionInstanceName) { + return EXTENSION_CLASS_CACHE.computeIfAbsent(extensionType, this::doLoadExtensionClass); + } + + private Map> doLoadExtensionClass(Class extensionType) { + Map> extensionMap = new HashMap<>(); + String extensionFileName = EventMeshExtensionConstant.EVENTMESH_EXTENSION_META_DIR + extensionType.getName(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + Enumeration extensionUrls = classLoader.getResources(extensionFileName); + if (extensionUrls != null) { + while (extensionUrls.hasMoreElements()) { + URL url = extensionUrls.nextElement(); + extensionMap.putAll(loadResources(url, extensionType)); + } + } + } catch (IOException e) { + throw new ExtensionException("load extension class error", e); + } + return extensionMap; + } + + private static Map> loadResources(URL url, Class extensionType) throws IOException { + Map> extensionMap = new HashMap<>(); + try (InputStream inputStream = url.openStream()) { + Properties properties = new Properties(); + properties.load(inputStream); + properties.forEach((extensionName, extensionClass) -> { + String extensionNameStr = (String) extensionName; + String extensionClassStr = (String) extensionClass; + try { + Class targetClass = Class.forName(extensionClassStr); + logger.info("load extension class success, extensionType: {}, extensionClass: {}", + extensionType, targetClass); + if (!extensionType.isAssignableFrom(targetClass)) { + throw new ExtensionException( + String.format("class: %s is not subClass of %s", targetClass, extensionType)); + } + extensionMap.put(extensionNameStr, targetClass); + } catch (ClassNotFoundException e) { + throw new ExtensionException("load extension class error", e); + } + }); + } + return extensionMap; + } +} diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java new file mode 100644 index 0000000000..5dc24c592a --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi; + +import org.apache.eventmesh.spi.example.TestPrototypeExtension; +import org.apache.eventmesh.spi.example.TestSingletonExtension; + +import org.junit.Assert; +import org.junit.Test; + +public class EventMeshExtensionFactoryTest { + + @Test + public void testGetSingletonExtension() { + TestSingletonExtension extensionA = EventMeshExtensionFactory.getExtension(TestSingletonExtension.class, "singletonExtension"); + TestSingletonExtension extensionB = EventMeshExtensionFactory.getExtension(TestSingletonExtension.class, "singletonExtension"); + Assert.assertSame(extensionA, extensionB); + } + + @Test + public void testGetPrototypeExtension() { + TestPrototypeExtension prototypeExtensionA = EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, "prototypeExtension"); + TestPrototypeExtension prototypeExtensionB = EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, "prototypeExtension"); + Assert.assertNotSame(prototypeExtensionA, prototypeExtensionB); + } +} \ No newline at end of file diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/PrototypeExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/PrototypeExtension.java new file mode 100644 index 0000000000..27a50ac59c --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/PrototypeExtension.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.example; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PrototypeExtension implements TestPrototypeExtension { + + private static final Logger logger = LoggerFactory.getLogger(PrototypeExtension.class); + + @Override + public void hello() { + logger.info("I am PrototypeExtension"); + } +} diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/SingletonExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/SingletonExtension.java new file mode 100644 index 0000000000..285867c2dd --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/SingletonExtension.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.example; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SingletonExtension implements TestSingletonExtension { + + private static final Logger logger = LoggerFactory.getLogger(SingletonExtension.class); + + @Override + public void hello() { + logger.info("I am SingletonExtension"); + } +} diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestPrototypeExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestPrototypeExtension.java new file mode 100644 index 0000000000..8117ae8c8b --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestPrototypeExtension.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.example; + +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * TestPrototypeExtension + */ +@EventMeshSPI(isSingleton = false, eventMeshExtensionType = EventMeshExtensionType.UNKNOWN) +public interface TestPrototypeExtension { + + void hello(); +} diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestSingletonExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestSingletonExtension.java new file mode 100644 index 0000000000..9b67793e12 --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestSingletonExtension.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.example; + +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * TestSingletonExtension + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.UNKNOWN) +public interface TestSingletonExtension { + + void hello(); +} diff --git a/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestPrototypeExtension b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestPrototypeExtension new file mode 100644 index 0000000000..29764071d1 --- /dev/null +++ b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestPrototypeExtension @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +prototypeExtension=org.apache.eventmesh.spi.example.PrototypeExtension \ No newline at end of file diff --git a/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestSingletonExtension b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestSingletonExtension new file mode 100644 index 0000000000..af6c8b8970 --- /dev/null +++ b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestSingletonExtension @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +singletonExtension=org.apache.eventmesh.spi.example.SingletonExtension \ No newline at end of file diff --git a/eventmesh-starter/build.gradle b/eventmesh-starter/build.gradle new file mode 100644 index 0000000000..0bc2208fd1 --- /dev/null +++ b/eventmesh-starter/build.gradle @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation project(":eventmesh-runtime") +} \ No newline at end of file diff --git a/eventmesh-starter/gradle.properties b/eventmesh-starter/gradle.properties new file mode 100644 index 0000000000..b1312a0905 --- /dev/null +++ b/eventmesh-starter/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/eventmesh-starter/src/main/java/org/apache/eventmesh/starter/StartUp.java b/eventmesh-starter/src/main/java/org/apache/eventmesh/starter/StartUp.java new file mode 100644 index 0000000000..4a2ab9d5ac --- /dev/null +++ b/eventmesh-starter/src/main/java/org/apache/eventmesh/starter/StartUp.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.starter; + +import org.apache.eventmesh.runtime.boot.EventMeshStartup; + +public class StartUp { + public static void main(String[] args) throws Exception { + EventMeshStartup.main(args); + } +} diff --git a/eventmesh-store/build.gradle b/eventmesh-store/build.gradle deleted file mode 100644 index 86b5c8636a..0000000000 --- a/eventmesh-store/build.gradle +++ /dev/null @@ -1,301 +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. - */ - -import java.util.concurrent.TimeUnit - -buildscript { - repositories { - maven { - url "https://maven.aliyun.com/repository/public" - } - - maven { - url "https://plugins.gradle.org/m2/" - } - - } - - dependencies { - //classpath("net.sourceforge.pmd:pmd-java:5.4.1") - //classpath("com.puppycrawl.tools:checkstyle:6.16.1") - classpath("gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.0.7") - classpath('com.github.spotbugs:spotbugs:4.0.0') - } -} - -allprojects { - apply plugin: 'java' - - - clean.doFirst { - delete 'build' - delete 'dist' - } - - if (project.findProperty("snapshot") instanceof String) { - if (project.property("snapshot").toBoolean()) - version = version + "-SNAPSHOT" - } -} - -task tar(type: Tar) { - extension = 'tar.gz' - compression = Compression.GZIP - archiveName = project.name + '_' + project.version + '.' + extension - destinationDir = new File(projectDir, 'build') - into('/') { - from 'dist' - } -} - -task zip(type: Zip) { - extension = 'zip' - archiveName = project.name + '.' + project.version + '.' + extension - destinationDir = new File(projectDir, 'build') - into('/') { - from 'dist' - } -} - -subprojects { - - - apply plugin: "maven" - apply plugin: "eclipse" - apply plugin: "idea" - apply plugin: "project-reports" - apply plugin: "jacoco" - apply plugin: "checkstyle" - apply plugin: "pmd" - apply plugin: 'com.github.spotbugs' - - [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' - - compileJava.options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" - - jacoco { - toolVersion = "0.8.5" - reportsDir = file("$buildDir/reports/jacoco") - } - - jacocoTestReport { -// sourceSets sourceSets.main -// executionData files("$buildDir/jacoco/jacocoTest.exec") - - reports { - xml.enabled false - csv.enabled false - html.destination file("${buildDir}/reports/jacoco") - } - } - - checkstyle { - toolVersion = "8.32" - ignoreFailures = true - sourceSets = [sourceSets.main] - configFile = 'conf/checkstyle.xml' as File - showViolations true - } - - tasks.withType(Checkstyle) { - reports { - xml.enabled false - html.enabled true - } - } - - spotbugs { - toolVersion = '4.0.2' - ignoreFailures = true - effort = "default" - reportLevel = "default" - showProgress = true - } - -// tasks.withType(com.github.spotbugs.SpotBugsTask) { -// sourceDirs = [sourceSets.main] -// reports { -// xml.enabled = false -// html.enabled = true -// } -// } - spotbugsMain { - reports { - xml.enabled = false - html.enabled = true - } - } - - spotbugsTest { - reports { - xml.enabled = false - html.enabled = true - } - } - - tasks.withType(Pmd) { - reports { - xml.enabled = false - html.enabled = true - } - } - - - pmd { - consoleOutput = true - toolVersion = "6.23.0" - rulePriority = 5 - ruleSets = ["category/java/errorprone.xml", "category/java/bestpractices.xml"] - ignoreFailures = true - } - - - - List junit = [ - "junit:junit:4.12" - ] - - List apache_commons = [ - "org.apache.commons:commons-collections4:4.1", - "commons-beanutils:commons-beanutils:1.9.3", - "org.apache.commons:commons-lang3:3.6", - "commons-codec:commons-codec:1.10" - - ] - - List logback = [ - "org.slf4j:slf4j-api:1.7.25" - ] - - List guava = [ - "com.google.guava:guava:20.0" - ] - - List fastjson = [ - "com.alibaba:fastjson:1.2.71" - ] - - List common_io = [ - "commons-io:commons-io:2.4" - ] - - List assertj = [ - "org.assertj:assertj-core:2.6.0" - ] - - List mock = [ -// "org.mockito:mockito-core:1.10.19", -"org.mockito:mockito-core:2.23.0", -"org.powermock:powermock-module-junit4:2.0.2", -"org.powermock:powermock-api-mockito2:2.0.2", - ] - - dependencies { - compile apache_commons, guava, logback, fastjson, common_io - testCompile apache_commons, guava, logback, fastjson, common_io, junit, assertj, mock - runtime apache_commons, guava, logback, fastjson, common_io - } - - jar { - manifest { - attributes("Specification-Version": project.version, - "Specification-Vendor": "WeBank, Inc.", - "Specification-Title": project.name, - "Implementation-Version": project.version, - "Implementation-Vendor": "WeBank, Inc.", - "Implementation-Title": project.name, - "Build-Jdk": project.findProperty("jdk") - ) - } - } - - task dist(dependsOn: ['jar']) { - doFirst { - new File(projectDir, '../dist/bin').mkdirs() - new File(projectDir, '../dist/apps').mkdirs() - new File(projectDir, '../dist/conf').mkdirs() - new File(projectDir, '../dist/lib').mkdirs() - } - - doLast { - copy { - into('../dist/apps/') - from project.jar.getArchivePath() - } - copy { - into '../dist/lib' - from project.configurations.runtime - exclude '**/*.properties*' - exclude '**/*testng*.jar' - exclude '**/*powermock*.jar' - exclude '**/*mockito*.jar' - exclude '**/*junit*.jar' - exclude '**/*jacoco*.jar' - exclude '**/*log4j2.xml*' - exclude '**/spring-boot-devtools*.jar' - exclude '**/mumble-sdk-test*.jar' - exclude '**/defibus*.jar' - exclude '*log4j*.jar' - exclude 'commons-collections-3.2.2.jar' - } - - copy { - into '../dist/bin' - from '../script' - } - - copy { - into '../dist/conf' - from '../conf/' - } - } - } - - javadoc { - source = sourceSets.main.java - classpath = configurations.compile - destinationDir = reporting.file("javadoc") - } - - task packageJavadoc(type: Jar, dependsOn: ['javadoc']) { - from project.javadoc.destinationDir - classifier = 'javadoc' - } - - task packageSources(type: Jar) { - from project.sourceSets.main.allSource - classifier = 'sources' // either here or in artifacts block - } - - artifacts { - archives jar - archives packageJavadoc - archives packageSources - } - - repositories { - maven { url "https://maven.aliyun.com/repository/public" } - mavenCentral() - } - - configurations.all { - resolutionStrategy.cacheChangingModulesFor 0, TimeUnit.SECONDS - resolutionStrategy.cacheDynamicVersionsFor 0, TimeUnit.SECONDS - } - -} - diff --git a/eventmesh-store/conf/broker.properties b/eventmesh-store/conf/broker.properties deleted file mode 100644 index c527776dd1..0000000000 --- a/eventmesh-store/conf/broker.properties +++ /dev/null @@ -1,25 +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. -# -namesrvAddr= -brokerClusterName= -brokerName= -brokerId=0 -brokerRole=ASYNC_MASTER -autoCreateTopicEnable=false -useReentrantLockWhenPutMessage=true -storePathRootDir=/dev/shm/store -storePathCommitLog=/dev/shm/store/commitlog diff --git a/eventmesh-store/conf/logback_broker.xml b/eventmesh-store/conf/logback_broker.xml deleted file mode 100644 index 1dee3ed454..0000000000 --- a/eventmesh-store/conf/logback_broker.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - ../logs/broker_default.log - true - - ../logs/otherdays/broker_default-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - 10 - 256 - - - - - - ../logs/broker.log - true - - ../logs/otherdays/broker-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - ../logs/protection.log - true - - ../logs/otherdays/protection-%d{yyyy-MM-dd}.%i.log - - 16MB - 24 - 1GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - ../logs/watermark.log - true - - ../logs/otherdays/watermark-%d{yyyy-MM-dd}.%i.log - - 32MB - 24 - 1GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %t %p %c - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - ../logs/store.log - true - - ../logs/otherdays/store-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - ../logs/remoting.log - true - - ../logs/otherdays/remoting-%d{yyyy-MM-dd}.%i.log - - 64MB - 24 - 1GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - ../logs/storeerror.log - true - - ../logs/otherdays/storeerror-%d{yyyy-MM-dd}.%i.log - - 64MB - 24 - 1GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - - ../logs/transaction.log - true - - ../logs/otherdays/transaction-%d{yyyy-MM-dd}.%i.log - - 16MB - 24 - 1GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - - ../logs/lock.log - true - - ../logs/otherdays/lock-%d{yyyy-MM-dd}.%i.log - - 64MB - 24 - 1GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - 10 - 256 - - - - - ../logs/stats.log - true - - ../logs/otherdays/stats-%d{yyyy-MM-dd}.%i.log - - 500MB - 24 - 12GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - ../logs/commercial.log - true - - ../logs/otherdays/commercial-%d{yyyy-MM-dd}.%i.log - - 500MB - 24 - 12GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - - true - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/conf/logback_filtersrv.xml b/eventmesh-store/conf/logback_filtersrv.xml deleted file mode 100644 index ca85a5a09c..0000000000 --- a/eventmesh-store/conf/logback_filtersrv.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - ../logs/filtersrv_default.log - true - - ../logs/otherdays/filtersrv_default-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - 10 - 256 - - - - - ../logs/filtersrv.log - true - - ../logs/otherdays/filtersrv.%i.log - - 1 - 5 - - - 100MB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - true - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/conf/logback_namesrv.xml b/eventmesh-store/conf/logback_namesrv.xml deleted file mode 100644 index 0eb2b615d0..0000000000 --- a/eventmesh-store/conf/logback_namesrv.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - ../logs/namesrv_default.log - true - - ../logs/otherdays/namesrv_default-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - 10 - 256 - - - - - ../logs/namesrv.log - true - - ../logs/otherdays/namesrv-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - ../logs/watermark.log - true - - ../logs/otherdays/watermark-%d{yyyy-MM-dd}.%i.log - - 32MB - 24 - 1GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - 10 - 256 - - - - - true - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/conf/logback_tools.xml b/eventmesh-store/conf/logback_tools.xml deleted file mode 100644 index 885098ac26..0000000000 --- a/eventmesh-store/conf/logback_tools.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - ../logs/tools_default.log - true - - ../logs/otherdays/tools_default-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - 10 - 256 - - - - - - ../logs/tools.log - true - - ../logs/otherdays/tools-%d{yyyy-MM-dd}.%i.log - - 128MB - 24 - 3GB - - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - - - 10 - 256 - - - - - - true - - %d{yyy-MM-dd HH:mm:ss:SSS,GMT+8} %p %t - %m%n - UTF-8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/conf/namesrv.properties b/eventmesh-store/conf/namesrv.properties deleted file mode 100644 index 26d255fc6c..0000000000 --- a/eventmesh-store/conf/namesrv.properties +++ /dev/null @@ -1,17 +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. -# -listenPort=9876 \ No newline at end of file diff --git a/eventmesh-store/defibus-broker/.gitignore b/eventmesh-store/defibus-broker/.gitignore deleted file mode 100644 index 7272bbaaef..0000000000 --- a/eventmesh-store/defibus-broker/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -/bin/ -/.git/ -/.gradle/ -/.settings/ -/logs -.DS_Store -.*.swp -*.ipr -*.iml -*.iws -*.class -*.log -.idea -build -.classpath -.project -/test-output/ -/dist -/.pmd -/classes -/logs \ No newline at end of file diff --git a/eventmesh-store/defibus-broker/build.gradle b/eventmesh-store/defibus-broker/build.gradle deleted file mode 100644 index cb95bb0549..0000000000 --- a/eventmesh-store/defibus-broker/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -List Log = [ - "org.slf4j:slf4j-log4j12:1.7.12", - "log4j:log4j:1.2.17" -] - -dependencies { - compile project(":defibus-common") - testCompile project(":defibus-common") - compile "org.apache.rocketmq:rocketmq-broker:$project.rocketmqVersion" - compile "ch.qos.logback:logback-core:1.2.3" - compile "ch.qos.logback:logback-classic:1.2.3" - testCompile Log -} \ No newline at end of file diff --git a/eventmesh-store/defibus-broker/conf/checkstyle.xml b/eventmesh-store/defibus-broker/conf/checkstyle.xml deleted file mode 100644 index 3d024111bc..0000000000 --- a/eventmesh-store/defibus-broker/conf/checkstyle.xml +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBrokerController.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBrokerController.java deleted file mode 100644 index 76eb754205..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBrokerController.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker; - -import cn.webank.defibus.broker.client.AdjustQueueNumStrategy; -import cn.webank.defibus.broker.client.DeFiConsumerManager; -import cn.webank.defibus.broker.client.DeFiProducerManager; -import cn.webank.defibus.broker.consumequeue.ClientRebalanceResultManager; -import cn.webank.defibus.broker.consumequeue.ConsumeQueueManager; -import cn.webank.defibus.broker.consumequeue.MessageRedirectManager; -import cn.webank.defibus.broker.monitor.QueueListeningMonitor; -import cn.webank.defibus.broker.net.DeFiBusBroker2Client; -import cn.webank.defibus.broker.processor.DeFiAdminBrokerProcessor; -import cn.webank.defibus.broker.processor.DeFiClientManageProcessor; -import cn.webank.defibus.broker.processor.DeFiPullMessageProcessor; -import cn.webank.defibus.broker.processor.DeFiReplyMessageProcessor; -import cn.webank.defibus.broker.processor.DeFiSendMessageProcessor; -import cn.webank.defibus.broker.topic.DeFiTopicConfigManager; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.util.ReflectUtil; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import org.apache.commons.lang3.Validate; -import org.apache.rocketmq.broker.BrokerController; -import org.apache.rocketmq.broker.client.ConsumerIdsChangeListener; -import org.apache.rocketmq.broker.out.BrokerOuterAPI; -import org.apache.rocketmq.broker.processor.PullMessageProcessor; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.ThreadFactoryImpl; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.constant.PermName; -import org.apache.rocketmq.common.namesrv.TopAddressing; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.remoting.RemotingServer; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBrokerController extends BrokerController { - private static final Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private static final Logger LOG_WATER_MARK = LoggerFactory.getLogger(LoggerName.WATER_MARK_LOGGER_NAME); - - private final DeFiProducerManager producerManager; - private final DeFiConsumerManager consumerManager; - private final DeFiBusBroker2Client deFiBusBroker2Client; - private final ExecutorService deFiManageExecutor; - private final ExecutorService sendReplyMessageExecutor; - private final ExecutorService pushReplyMessageExecutor; - private final BlockingQueue sendReplyThreadPoolQueue; - private final BlockingQueue pushReplyThreadPoolQueue; - private final ScheduledExecutorService deFiScheduledExecutorService; - private final ScheduledThreadPoolExecutor sendReplyScheduledExecutorService; - - private RemotingServer fastRemotingServer = null; - private final ConsumeQueueManager consumeQueueManager; - private final DeFiBusBrokerConfig deFiBusBrokerConfig; - private final DeFiTopicConfigManager extTopicConfigManager; - private final QueueListeningMonitor queueListeningMonitor; - - private DeFiPullMessageProcessor deFiPullMessageProcessor; - private MessageRedirectManager messageRedirectManager; - private ClientRebalanceResultManager clientRebalanceResultManager; - - public DeFiBrokerController(BrokerConfig brokerConfig, NettyServerConfig nettyServerConfig, - NettyClientConfig nettyClientConfig, MessageStoreConfig messageStoreConfig, - DeFiBusBrokerConfig deFiBusBrokerConfig) { - super(brokerConfig, nettyServerConfig, nettyClientConfig, messageStoreConfig); - producerManager = new DeFiProducerManager(); - - ConsumerIdsChangeListener consumerIdsChangeListener = (ConsumerIdsChangeListener) ReflectUtil.getSimpleProperty(BrokerController.class, this, "consumerIdsChangeListener"); - AdjustQueueNumStrategy adjustQueueNumStrategy = new AdjustQueueNumStrategy(this); - consumerManager = new DeFiConsumerManager(consumerIdsChangeListener, adjustQueueNumStrategy); - - this.deFiManageExecutor = - Executors.newFixedThreadPool(brokerConfig.getClientManageThreadPoolNums(), new ThreadFactoryImpl( - "ClientManageThread_")); - deFiBusBroker2Client = new DeFiBusBroker2Client(this); - this.sendReplyThreadPoolQueue = new LinkedBlockingQueue(deFiBusBrokerConfig.getSendReplyThreadPoolQueueCapacity()); - this.pushReplyThreadPoolQueue = new LinkedBlockingQueue(deFiBusBrokerConfig.getPushReplyThreadPoolQueueCapacity()); - - this.sendReplyMessageExecutor = new ThreadPoolExecutor(// - deFiBusBrokerConfig.getSendReplyMessageThreadPoolNums(),// - deFiBusBrokerConfig.getSendReplyMessageThreadPoolNums(),// - 1000 * 60,// - TimeUnit.MILLISECONDS,// - this.sendReplyThreadPoolQueue,// - new ThreadFactoryImpl("sendReplyMessageThread_")); - this.pushReplyMessageExecutor = new ThreadPoolExecutor(// - deFiBusBrokerConfig.getPushReplyMessageThreadPoolNums(),// - deFiBusBrokerConfig.getPushReplyMessageThreadPoolNums(),// - 1000 * 60,// - TimeUnit.MILLISECONDS,// - this.pushReplyThreadPoolQueue,// - new ThreadFactoryImpl("pushReplyMessageThread_")); - - this.consumeQueueManager = ConsumeQueueManager.onlyInstance(); - consumeQueueManager.setBrokerController(this); - extTopicConfigManager = new DeFiTopicConfigManager(this); - - BrokerOuterAPI brokerOuterAPI = super.getBrokerOuterAPI(); - ReflectUtil.setSimpleProperty(BrokerController.class, this, "brokerOuterAPI", brokerOuterAPI); - - String wsAddr = deFiBusBrokerConfig.getRmqAddressServerDomain() + "/" + deFiBusBrokerConfig.getRmqAddressServerSubGroup(); - TopAddressing topAddressing = (TopAddressing) ReflectUtil.getSimpleProperty(BrokerOuterAPI.class, brokerOuterAPI, "topAddressing"); - ReflectUtil.setSimpleProperty(TopAddressing.class, topAddressing, "wsAddr", wsAddr); - - if (this.getBrokerConfig().getNamesrvAddr() != null) { - brokerOuterAPI.updateNameServerAddressList(this.getBrokerConfig().getNamesrvAddr()); - LOG.info("user specfied name server address: {}", this.getBrokerConfig().getNamesrvAddr()); - } - - deFiScheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r, "brokerControllerScheduledThread"); - t.setDaemon(true); - return t; - } - }); - - sendReplyScheduledExecutorService = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r, "sendReplyScheduledThread"); - t.setDaemon(true); - return t; - } - }); - - this.deFiBusBrokerConfig = deFiBusBrokerConfig; - this.getConfiguration().registerConfig(deFiBusBrokerConfig); - this.messageRedirectManager = new MessageRedirectManager(this); - this.clientRebalanceResultManager = new ClientRebalanceResultManager(this); - this.queueListeningMonitor = new QueueListeningMonitor(this); - DeFiBusBrokerStartup.setDeFiBrokerController(this); - } - - @Override - public boolean initialize() throws CloneNotSupportedException { - boolean result = super.initialize(); - - result = result && this.extTopicConfigManager.load(); - - //reset the lastDeliverOffsetTable as offsetTable of consumer - consumeQueueManager.load(); - - String rrTopic = this.getBrokerConfig().getBrokerClusterName() + "-" + DeFiBusConstant.RR_REPLY_TOPIC; - if (getTopicConfigManager().selectTopicConfig(rrTopic) == null) { - TopicConfig topicConfig = new TopicConfig(rrTopic); - topicConfig.setWriteQueueNums(1); - topicConfig.setReadQueueNums(1); - topicConfig.setPerm(PermName.PERM_INHERIT | PermName.PERM_READ | PermName.PERM_WRITE); - this.getTopicConfigManager().updateTopicConfig(topicConfig); - } - this.getTopicConfigManager().getSystemTopic().add(rrTopic); - - return result; - } - - public DeFiTopicConfigManager getExtTopicConfigManager() { - return DeFiBrokerController.this.extTopicConfigManager; - } - - public void start() throws Exception { - super.start(); - deFiScheduledExecutorService.scheduleAtFixedRate(() -> { - this.getConsumerOffsetManager().scanUnsubscribedTopic(); - this.getConsumeQueueManager().scanUnsubscribedTopic(); - }, 3600 * 1000, 3600 * 1000, TimeUnit.MILLISECONDS); - this.queueListeningMonitor.start(); - } - - public void scheduleTask(Runnable task, long delay) { - deFiScheduledExecutorService.schedule(task, delay, TimeUnit.MILLISECONDS); - } - - public void scheduleTaskAtFixedRate(Runnable task, long delay, long period) { - deFiScheduledExecutorService.scheduleAtFixedRate(task, delay, period, TimeUnit.MILLISECONDS); - } - - public void shutdown() { - deFiManageExecutor.shutdown(); - sendReplyMessageExecutor.shutdown(); - pushReplyMessageExecutor.shutdown(); - - deFiScheduledExecutorService.shutdown(); - sendReplyScheduledExecutorService.shutdown(); - - messageRedirectManager.shutdown(); - this.queueListeningMonitor.shutdown(); - - super.shutdown(); - } - - public void registerProcessor() { - super.registerProcessor(); - fastRemotingServer = (RemotingServer) ReflectUtil.getSimpleProperty(BrokerController.class, this, "fastRemotingServer"); - Validate.notNull(fastRemotingServer, "fastRemotingServer is null"); - - DeFiReplyMessageProcessor sendDirectMessageProcessor = new DeFiReplyMessageProcessor(this); - super.getRemotingServer().registerProcessor(DeFiBusRequestCode.SEND_DIRECT_MESSAGE, sendDirectMessageProcessor, this.sendReplyMessageExecutor); - super.getRemotingServer().registerProcessor(DeFiBusRequestCode.SEND_DIRECT_MESSAGE_V2, sendDirectMessageProcessor, this.sendReplyMessageExecutor); - fastRemotingServer.registerProcessor(DeFiBusRequestCode.SEND_DIRECT_MESSAGE, sendDirectMessageProcessor, this.sendReplyMessageExecutor); - fastRemotingServer.registerProcessor(DeFiBusRequestCode.SEND_DIRECT_MESSAGE_V2, sendDirectMessageProcessor, this.sendReplyMessageExecutor); - - DeFiAdminBrokerProcessor extAdminBrokerProcessor = new DeFiAdminBrokerProcessor(this); - ExecutorService adminBrokerExecutor = (ExecutorService) ReflectUtil.getSimpleProperty(BrokerController.class, - this, "adminBrokerExecutor"); - super.getRemotingServer().registerProcessor(DeFiBusRequestCode.GET_CONSUME_STATS_V2, extAdminBrokerProcessor, adminBrokerExecutor); - super.getRemotingServer().registerProcessor(RequestCode.GET_BROKER_RUNTIME_INFO, extAdminBrokerProcessor, adminBrokerExecutor); - fastRemotingServer.registerProcessor(DeFiBusRequestCode.GET_CONSUME_STATS_V2, extAdminBrokerProcessor, adminBrokerExecutor); - fastRemotingServer.registerProcessor(RequestCode.GET_BROKER_RUNTIME_INFO, extAdminBrokerProcessor, adminBrokerExecutor); - super.getRemotingServer().registerProcessor(RequestCode.UPDATE_AND_CREATE_TOPIC, extAdminBrokerProcessor, adminBrokerExecutor); - fastRemotingServer.registerProcessor(RequestCode.UPDATE_AND_CREATE_TOPIC, extAdminBrokerProcessor, adminBrokerExecutor); - - DeFiSendMessageProcessor deFiSendMessageProcessor = new DeFiSendMessageProcessor(this); - ExecutorService sendMessageExecutor = (ExecutorService) ReflectUtil.getSimpleProperty(BrokerController.class, - this, "sendMessageExecutor"); - super.getRemotingServer().registerProcessor(RequestCode.SEND_MESSAGE, deFiSendMessageProcessor, sendMessageExecutor); - super.getRemotingServer().registerProcessor(RequestCode.SEND_MESSAGE_V2, deFiSendMessageProcessor, sendMessageExecutor); - super.getRemotingServer().registerProcessor(RequestCode.SEND_BATCH_MESSAGE, deFiSendMessageProcessor, sendMessageExecutor); - super.getRemotingServer().registerProcessor(RequestCode.CONSUMER_SEND_MSG_BACK, deFiSendMessageProcessor, sendMessageExecutor); - this.fastRemotingServer.registerProcessor(RequestCode.SEND_MESSAGE, deFiSendMessageProcessor, sendMessageExecutor); - this.fastRemotingServer.registerProcessor(RequestCode.SEND_MESSAGE_V2, deFiSendMessageProcessor, sendMessageExecutor); - this.fastRemotingServer.registerProcessor(RequestCode.SEND_BATCH_MESSAGE, deFiSendMessageProcessor, sendMessageExecutor); - this.fastRemotingServer.registerProcessor(RequestCode.CONSUMER_SEND_MSG_BACK, deFiSendMessageProcessor, sendMessageExecutor); - - deFiPullMessageProcessor = new DeFiPullMessageProcessor(this); - ExecutorService pullMessageExecutor = (ExecutorService) ReflectUtil.getSimpleProperty(BrokerController.class, - this, "pullMessageExecutor"); - super.getRemotingServer().registerProcessor(RequestCode.PULL_MESSAGE, deFiPullMessageProcessor, pullMessageExecutor); - this.fastRemotingServer.registerProcessor(RequestCode.PULL_MESSAGE, deFiPullMessageProcessor, pullMessageExecutor); - - DeFiClientManageProcessor deFiClientManageProcessor = new DeFiClientManageProcessor(this); - super.getRemotingServer().registerProcessor(DeFiBusRequestCode.GET_CONSUMER_LIST_BY_GROUP_AND_TOPIC, deFiClientManageProcessor, deFiManageExecutor); - fastRemotingServer.registerProcessor(DeFiBusRequestCode.GET_CONSUMER_LIST_BY_GROUP_AND_TOPIC, deFiClientManageProcessor, deFiManageExecutor); - - } - - public DeFiBusBroker2Client getDeFiBusBroker2Client() { - return deFiBusBroker2Client; - } - - @Override - public DeFiProducerManager getProducerManager() { - return producerManager; - } - - @Override - public void printWaterMark() { - LOG_WATER_MARK.info("{\"SendQueueSize\":\"{}\",\"PullQueueSize\":\"{}\",\"GotQueueSize\":\"{}\",\"PushQueueSize\":\"{}\",\"SendSlowTimeMills\":\"{}\",\"PullSlowTimeMills\":\"{}\",\"HeartbeatQueueSize\":\"{}\"}", - this.getSendThreadPoolQueue().size(), - this.getPullThreadPoolQueue().size(), - this.sendReplyThreadPoolQueue.size(), - this.pushReplyThreadPoolQueue.size(), - this.headSlowTimeMills4SendThreadPoolQueue(), - this.headSlowTimeMills4PullThreadPoolQueue(), - this.getHeartbeatThreadPoolQueue().size()); - } - - public DeFiBusBrokerConfig getDeFiBusBrokerConfig() { - return deFiBusBrokerConfig; - } - - public ExecutorService getPushReplyMessageExecutor() { - return pushReplyMessageExecutor; - } - - public ExecutorService getSendReplyMessageExecutor() { - return sendReplyMessageExecutor; - } - - public ScheduledThreadPoolExecutor getSendReplyScheduledExecutorService() { - return sendReplyScheduledExecutorService; - } - - public ConsumeQueueManager getConsumeQueueManager() { - return consumeQueueManager; - } - - public PullMessageProcessor getPullMessageProcessor() { - return deFiPullMessageProcessor; - } - - @Override - public DeFiConsumerManager getConsumerManager() { - return this.consumerManager; - } - - public MessageRedirectManager getMessageRedirectManager() { - return messageRedirectManager; - } - - public ClientRebalanceResultManager getClientRebalanceResultManager() { - return clientRebalanceResultManager; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBrokerPathConfigHelper.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBrokerPathConfigHelper.java deleted file mode 100644 index ceb5a273a2..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBrokerPathConfigHelper.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker; - -import java.io.File; -import org.apache.rocketmq.broker.BrokerPathConfigHelper; - -public class DeFiBrokerPathConfigHelper extends BrokerPathConfigHelper { - private static String topicConfigPath = System.getProperty("user.home") + File.separator + "topicConfig"; - private static String brokerConfigPath = System.getProperty("user.home") + File.separator + "brokerConfig"; - - public static String getTopicConfigPath() { - return topicConfigPath; - } - - public static void setTopicConfigPath(String topicConfigPath) { - DeFiBrokerPathConfigHelper.topicConfigPath = topicConfigPath; - } - - public static String getBrokerConfigPath() { - return brokerConfigPath; - } - - public static void setBrokerConfigPath(String brokerConfigPath) { - DeFiBrokerPathConfigHelper.brokerConfigPath = brokerConfigPath; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBusBrokerStartup.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBusBrokerStartup.java deleted file mode 100644 index 8c59ffcaba..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/DeFiBusBrokerStartup.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker; - -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.joran.JoranConfigurator; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.DeFiBusConstant; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.PosixParser; -import org.apache.rocketmq.broker.BrokerPathConfigHelper; -import org.apache.rocketmq.broker.BrokerStartup; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.MQVersion; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.logging.InternalLoggerFactory; -import org.apache.rocketmq.remoting.common.RemotingUtil; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.netty.NettySystemConfig; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.srvutil.ServerUtil; -import org.apache.rocketmq.store.config.BrokerRole; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.slf4j.LoggerFactory; - -public class DeFiBusBrokerStartup extends BrokerStartup { - private static DeFiBrokerController deFiBrokerController; - - public static void main(String[] args) { - createBrokerController(args); - BrokerStartup.start(deFiBrokerController); - } - - public static DeFiBrokerController createBrokerController(String[] args) { - System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION)); - if (null == System.getProperty(NettySystemConfig.COM_ROCKETMQ_REMOTING_SOCKET_SNDBUF_SIZE)) { - NettySystemConfig.socketSndbufSize = 131072; - } - if (null == System.getProperty(NettySystemConfig.COM_ROCKETMQ_REMOTING_SOCKET_RCVBUF_SIZE)) { - NettySystemConfig.socketRcvbufSize = 131072; - } - - try { - Options options = ServerUtil.buildCommandlineOptions(new Options()); - commandLine = - ServerUtil.parseCmdLine("mqbroker", args, buildCommandlineOptions(options), - new PosixParser()); - if (null == commandLine) { - System.exit(-1); - return null; - } - - final BrokerConfig brokerConfig = new BrokerConfig(); - final NettyServerConfig nettyServerConfig = new NettyServerConfig(); - final NettyClientConfig nettyClientConfig = new NettyClientConfig(); - nettyServerConfig.setListenPort(10911); - final MessageStoreConfig messageStoreConfig = new MessageStoreConfig(); - final DeFiBusBrokerConfig deFiBusBrokerConfig = new DeFiBusBrokerConfig(); - - if (BrokerRole.SLAVE == messageStoreConfig.getBrokerRole()) { - int ratio = messageStoreConfig.getAccessMessageInMemoryMaxRatio() - 10; - messageStoreConfig.setAccessMessageInMemoryMaxRatio(ratio); - } - - if (commandLine.hasOption('p')) { - MixAll.printObjectProperties(null, brokerConfig); - MixAll.printObjectProperties(null, nettyServerConfig); - MixAll.printObjectProperties(null, nettyClientConfig); - MixAll.printObjectProperties(null, messageStoreConfig); - System.exit(0); - } else if (commandLine.hasOption('m')) { - MixAll.printObjectProperties(null, brokerConfig, true); - MixAll.printObjectProperties(null, nettyServerConfig, true); - MixAll.printObjectProperties(null, nettyClientConfig, true); - MixAll.printObjectProperties(null, messageStoreConfig, true); - System.exit(0); - } - - if (commandLine.hasOption('c')) { - String file = commandLine.getOptionValue('c'); - if (file != null) { - configFile = file; - InputStream in = new BufferedInputStream(new FileInputStream(file)); - properties = new Properties(); - properties.load(in); - - parsePropertie2SystemEnv(properties); - MixAll.properties2Object(properties, brokerConfig); - MixAll.properties2Object(properties, nettyServerConfig); - MixAll.properties2Object(properties, nettyClientConfig); - MixAll.properties2Object(properties, messageStoreConfig); - MixAll.properties2Object(properties, deFiBusBrokerConfig); - BrokerPathConfigHelper.setBrokerConfigPath(file); - DeFiBrokerPathConfigHelper.setBrokerConfigPath(file); - String path = new File(file).getParent(); - DeFiBrokerPathConfigHelper.setTopicConfigPath(path); - DeFiBrokerPathConfigHelper.setBrokerConfigPath(path); - - System.out.println("load config properties file OK, " + file); - in.close(); - } - } - - MixAll.properties2Object(ServerUtil.commandLine2Properties(commandLine), brokerConfig); - - if (null == brokerConfig.getRocketmqHome()) { - System.out.println("Please set the " + MixAll.ROCKETMQ_HOME_ENV - + " variable in your environment to match the location of the RocketMQ installation"); - System.exit(-2); - } - - String namesrvAddr = brokerConfig.getNamesrvAddr(); - if (null != namesrvAddr) { - try { - String[] addrArray = namesrvAddr.split(";"); - if (addrArray != null) { - for (String addr : addrArray) { - RemotingUtil.string2SocketAddress(addr); - } - } - } catch (Exception e) { - System.out.printf( - "The Name Server Address[%s] illegal, please set it as follows, \"127.0.0.1:9876;192.168.0.1:9876\"%n", - namesrvAddr); - System.exit(-3); - } - } - - switch (messageStoreConfig.getBrokerRole()) { - case ASYNC_MASTER: - case SYNC_MASTER: - brokerConfig.setBrokerId(MixAll.MASTER_ID); - break; - case SLAVE: - if (brokerConfig.getBrokerId() <= 0) { - System.out.println("Slave's brokerId must be > 0"); - System.exit(-3); - } - - break; - default: - break; - } - - messageStoreConfig.setHaListenPort(nettyServerConfig.getListenPort() + 1); - - LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); - JoranConfigurator configurator = new JoranConfigurator(); - configurator.setContext(lc); - lc.reset(); - configurator.doConfigure(brokerConfig.getRocketmqHome() + "/conf/logback_broker.xml"); - log = InternalLoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - - MixAll.printObjectProperties(log, brokerConfig); - MixAll.printObjectProperties(log, nettyServerConfig); - MixAll.printObjectProperties(log, nettyClientConfig); - MixAll.printObjectProperties(log, messageStoreConfig); - - brokerConfig.setMessageStorePlugIn(DeFiBusConstant.PLUGIN_CLASS_NAME); - final DeFiBrokerController deFiBrokerController = new DeFiBrokerController(// - brokerConfig, // - nettyServerConfig, // - nettyClientConfig, // - messageStoreConfig, - deFiBusBrokerConfig); - boolean initResult = deFiBrokerController.initialize(); - if (!initResult) { - deFiBrokerController.shutdown(); - System.exit(-3); - } - - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - private volatile boolean hasShutdown = false; - private AtomicInteger shutdownTimes = new AtomicInteger(0); - - @Override - public void run() { - synchronized (this) { - log.info("shutdown hook was invoked, " + this.shutdownTimes.incrementAndGet()); - if (!this.hasShutdown) { - this.hasShutdown = true; - long begineTime = System.currentTimeMillis(); - deFiBrokerController.shutdown(); - long consumingTimeTotal = System.currentTimeMillis() - begineTime; - log.info("shutdown hook over, consuming time total(ms): " + consumingTimeTotal); - } - } - } - }, "ShutdownHook")); - - return deFiBrokerController; - } catch (Throwable e) { - e.printStackTrace(); - System.exit(-1); - } - - return null; - } - - private static void parsePropertie2SystemEnv(Properties properties) { - if (properties == null) { - return; - } - String rmqAddressServerDomain = properties.getProperty("rmqAddressServerDomain", "jmenv.tbsite.net"); - String rmqAddressServerSubGroup = properties.getProperty("rmqAddressServerSubGroup", "nsaddr"); - System.setProperty("rocketmq.namesrv.domain", rmqAddressServerDomain); - System.setProperty("rocketmq.namesrv.domain.subgroup", rmqAddressServerSubGroup); - } - - public static DeFiBrokerController getDeFiBrokerController() { - return deFiBrokerController; - } - - public static void setDeFiBrokerController(DeFiBrokerController deFiBrokerController) { - DeFiBusBrokerStartup.deFiBrokerController = deFiBrokerController; - } - - private static Options buildCommandlineOptions(final Options options) { - Option opt = new Option("c", "configFile", true, "Broker config properties file"); - opt.setRequired(false); - options.addOption(opt); - - opt = new Option("p", "printConfigItem", false, "Print all config item"); - opt.setRequired(false); - options.addOption(opt); - - opt = new Option("m", "printImportantConfig", false, "Print important config item"); - opt.setRequired(false); - options.addOption(opt); - - return options; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/AdjustQueueNumStrategy.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/AdjustQueueNumStrategy.java deleted file mode 100644 index ed89963dda..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/AdjustQueueNumStrategy.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.client; - -import java.util.List; -import java.util.Set; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; - -import io.netty.channel.Channel; - -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.store.config.BrokerRole; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusConstant; - -public class AdjustQueueNumStrategy { - private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private final DeFiBrokerController deFiBrokerController; - private final ScheduledThreadPoolExecutor autoScaleQueueSizeExecutorService; - - public AdjustQueueNumStrategy(final DeFiBrokerController deFiBrokerController) { - this.deFiBrokerController = deFiBrokerController; - - autoScaleQueueSizeExecutorService = new ScheduledThreadPoolExecutor(3, new ThreadFactory() { - AtomicInteger threadNo = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r, "AdjustQueueNumScheduledThread_" + threadNo.incrementAndGet()); - t.setDaemon(true); - return t; - } - }); - } - - public void increaseQueueNum(String topic) { - adjustQueueNumByConsumerCount(topic, AdjustType.INCREASE_QUEUE_NUM); - } - - public void decreaseQueueNum(String topic) { - adjustQueueNumByConsumerCount(topic, AdjustType.DECREASE_QUEUE_NUM); - } - - private void adjustQueueNumByConsumerCount(String topic, AdjustType scaleType) { - if (BrokerRole.SLAVE == this.deFiBrokerController.getMessageStoreConfig().getBrokerRole()) { - log.info("skip adjust queue num in slave."); - return; - } - if (topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX) || topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)) { - log.info("skip adjust queue num for topic [{}]", topic); - return; - } - switch (scaleType) { - case INCREASE_QUEUE_NUM: - adjustReadQueueNumByConsumerCount(topic, 0, scaleType); - adjustWriteQueueNumByConsumerCount(topic, 10 * 1000, scaleType); - break; - - case DECREASE_QUEUE_NUM: - adjustWriteQueueNumByConsumerCount(topic, 0, scaleType); - long delayTimeMinutes = Math.min(deFiBrokerController.getDeFiBusBrokerConfig().getScaleQueueSizeDelayTimeMinute(), 10); - long delayTimeMillis = delayTimeMinutes * 60 * 1000; - adjustReadQueueNumByConsumerCount(topic, delayTimeMillis, scaleType); - break; - } - } - - private void adjustReadQueueNumByConsumerCount(String topic, long delayMills, AdjustType mode) { - Runnable scaleQueueTask = new Runnable() { - private int alreadyRetryTimes = 0; - - @Override - public void run() { - TopicConfig topicConfig = deFiBrokerController.getTopicConfigManager().getTopicConfigTable().get(topic); - if (topicConfig != null) { - synchronized (topicConfig) { - - //query again to ensure it's newest - topicConfig = deFiBrokerController.getTopicConfigManager().getTopicConfigTable().get(topic); - int adjustReadQueueSize = adjustQueueSizeByMaxConsumerCount(topic); - - if (AdjustType.INCREASE_QUEUE_NUM == mode && adjustReadQueueSize < topicConfig.getReadQueueNums()) { - log.info("can not decrease read queue size to {} for [{}], prev: {}, {}", adjustReadQueueSize, topic, topicConfig.getReadQueueNums(), mode); - return; - } - if (AdjustType.DECREASE_QUEUE_NUM == mode && adjustReadQueueSize > topicConfig.getReadQueueNums()) { - log.info("can not increase read queue size to {} for [{}], prev: {}, {}", adjustReadQueueSize, topic, topicConfig.getReadQueueNums(), mode); - return; - } - - if (adjustReadQueueSize != topicConfig.getReadQueueNums()) { - log.info("try adjust read queue size to {} for [{}], prev: {}, {}", adjustReadQueueSize, topic, topicConfig.getReadQueueNums(), mode); - if (adjustReadQueueSize < topicConfig.getWriteQueueNums()) { - log.info("adjust read queues to {} for [{}] fail. read queue size can't less than write queue size[{}]. {}", - adjustReadQueueSize, topic, topicConfig.getWriteQueueNums(), mode); - return; - } - boolean canAdjustReadQueueSize = isCanAdjustReadQueueSize(topic, adjustReadQueueSize); - if (canAdjustReadQueueSize) { - if (adjustReadQueueSize >= topicConfig.getWriteQueueNums() && adjustReadQueueSize < 1024) { - if (mode == AdjustType.INCREASE_QUEUE_NUM && adjustReadQueueSize > 4) { - log.warn("[NOTIFY]auto adjust queues more than 4 for [{}]. {}", topic, mode); - } - TopicConfig topicConfigNew = generateNewTopicConfig(topicConfig, topicConfig.getWriteQueueNums(), adjustReadQueueSize); - deFiBrokerController.getTopicConfigManager().updateTopicConfig(topicConfigNew); - deFiBrokerController.registerBrokerAll(true, false, true); - notifyWhenTopicConfigChange(topic); - } else if (adjustReadQueueSize >= 1024) { - log.warn("[NOTIFY]auto adjust queue num is limited to 1024 for [{}]. {}", topic, mode); - } - } else { - if (this.alreadyRetryTimes < deFiBrokerController.getDeFiBusBrokerConfig().getScaleQueueRetryTimesMax()) { - log.info("try adjust read queue size to {} for [{}] fail. retry times: [{}]. {}", adjustReadQueueSize, topic, this.alreadyRetryTimes, mode); - this.alreadyRetryTimes++; - scheduleAdjustQueueSizeTask(this, delayMills, topic, mode); - log.info("adjustQueueSizeScheduleExecutor queued: {}", autoScaleQueueSizeExecutorService.getQueue().size()); - } else { - log.warn("try adjust read queue size to {} for [{}] fail. ignore after retry {} times. {}", adjustReadQueueSize, topic, this.alreadyRetryTimes, mode); - } - } - } else { - log.info("no need to adjust read queue size for [{}]. now [w:{}/r:{}]. {}", topic, topicConfig.getWriteQueueNums(), topicConfig.getReadQueueNums(), mode); - } - } - } else { - log.info("skip adjust read queue size for [{}]. topicConfig is null.", topic); - } - } - }; - this.scheduleAdjustQueueSizeTask(scaleQueueTask, delayMills, topic, mode); - } - - private void adjustWriteQueueNumByConsumerCount(String topic, long delayMills, AdjustType mode) { - Runnable scaleTask = new Runnable() { - @Override - public void run() { - TopicConfig topicConfig = deFiBrokerController.getTopicConfigManager().getTopicConfigTable().get(topic); - if (topicConfig != null) { - synchronized (topicConfig) { - - //query again to ensure it's newest - topicConfig = deFiBrokerController.getTopicConfigManager().getTopicConfigTable().get(topic); - int adjustWriteQueueSize = adjustQueueSizeByMaxConsumerCount(topic); - - if (AdjustType.INCREASE_QUEUE_NUM == mode && adjustWriteQueueSize < topicConfig.getWriteQueueNums()) { - log.info("can not decrease write queue size to {} for [{}], prev: {}, {}", adjustWriteQueueSize, topic, topicConfig.getWriteQueueNums(), mode); - return; - } - if (AdjustType.DECREASE_QUEUE_NUM == mode && adjustWriteQueueSize > topicConfig.getWriteQueueNums()) { - log.info("can not increase write queue size to {} for [{}], prev: {}, {}", adjustWriteQueueSize, topic, topicConfig.getWriteQueueNums(), mode); - return; - } - - if (adjustWriteQueueSize != topicConfig.getWriteQueueNums()) { - log.info("try adjust write queue size to {} for [{}], prev: {}. {}", adjustWriteQueueSize, topic, topicConfig.getWriteQueueNums(), mode); - if (adjustWriteQueueSize >= 0 && adjustWriteQueueSize <= topicConfig.getReadQueueNums()) { - TopicConfig topicConfigNew = generateNewTopicConfig(topicConfig, adjustWriteQueueSize, topicConfig.getReadQueueNums()); - deFiBrokerController.getTopicConfigManager().updateTopicConfig(topicConfigNew); - deFiBrokerController.registerBrokerAll(true, false, true); - notifyWhenTopicConfigChange(topic); - } else { - log.info("adjust write queues to {} for [{}] fail. target write queue size can't less than 0 or greater than read queue size[{}]. mode: {}", - adjustWriteQueueSize, topic, topicConfig.getReadQueueNums(), mode); - } - } else { - log.info("no need to adjust write queue size for [{}]. now [w:{}/r:{}]. {}", topic, topicConfig.getWriteQueueNums(), topicConfig.getReadQueueNums(), mode); - } - } - } else { - log.info("skip adjust write queue size for [{}]. topicConfig is null.", topic); - } - } - }; - this.scheduleAdjustQueueSizeTask(scaleTask, delayMills, topic, mode); - } - - private void scheduleAdjustQueueSizeTask(Runnable task, long delay, String topic, AdjustType mode) { - int queueSize = autoScaleQueueSizeExecutorService.getQueue().size(); - if (queueSize < this.deFiBrokerController.getDeFiBusBrokerConfig().getScaleQueueThreadPoolQueueCapacity()) { - autoScaleQueueSizeExecutorService.schedule(task, delay, TimeUnit.MILLISECONDS); - } else { - log.warn("schedule adjust queue size reject. thread pool queue is full. capacity: {} topic: {}, {}", queueSize, topic, mode); - } - } - - private int adjustQueueSizeByMaxConsumerCount(String topic) { - int queueSize = this.deFiBrokerController.getDeFiBusBrokerConfig().getMinQueueNum(); - Set maxCidList = null; - Set topicConsumeByWho = this.deFiBrokerController.getConsumerManager().queryTopicConsumeByWho(topic); - for (String group : topicConsumeByWho) { - DeFiConsumerGroupInfo consumerGroupInfo = (DeFiConsumerGroupInfo) this.deFiBrokerController.getConsumerManager().getConsumerGroupInfo(group); - if (consumerGroupInfo != null && consumerGroupInfo.getMessageModel() == MessageModel.CLUSTERING) { - Set cidList = consumerGroupInfo.getClientIdBySubscription(topic); - if (cidList != null) { - int scaleSize = this.scaleQueueSize(cidList); - if (scaleSize >= queueSize) { - queueSize = scaleSize; - maxCidList = cidList; - } - } - } - } - log.info("calculate queue size by max consumer count, result: {} cidList: {}", queueSize, maxCidList); - return queueSize; - } - - private int scaleQueueSize(Set cidList) { - int scaleQueueSize = 0; - long nearbyClients = nearbyClients(cidList); - if (nearbyClients != 0) { - scaleQueueSize = new Long(nearbyClients).intValue(); - } else if (isAllClientsHaveNotIDCSurffix(cidList)) { - scaleQueueSize = cidList.size(); - } - return scaleQueueSize; - } - - private long nearbyClients(Set cidList) { - long locClient = cidList.stream().filter(new Predicate() { - @Override - public boolean test(String cid) { - String[] cidArr = cid.split(DeFiBusConstant.INSTANCE_NAME_SEPERATER); - if (cidArr.length > 2) { - String idc = cidArr[cidArr.length - 1]; - String clusterName = deFiBrokerController.getBrokerConfig().getBrokerClusterName(); - if (clusterName.toUpperCase().startsWith(idc) || - idc.startsWith(clusterName.toUpperCase())) { - return true; - } - } - return false; - } - }).count(); - return locClient; - } - - private boolean isAllClientsHaveNotIDCSurffix(Set cidList) { - long suffixClients = cidList.stream().filter(new Predicate() { - @Override - public boolean test(String cid) { - String[] cidArr = cid.split(DeFiBusConstant.INSTANCE_NAME_SEPERATER); - if (cidArr.length > 2) { - return true; - } - return false; - } - }).count(); - return suffixClients == 0; - } - - public void notifyWhenTopicConfigChange(String topic) { - Set topicConsumeByWho = this.deFiBrokerController.getConsumerManager().queryTopicConsumeByWho(topic); - for (String group : topicConsumeByWho) { - ConsumerGroupInfo consumerGroupInfo = this.deFiBrokerController.getConsumerManager().getConsumerGroupInfo(group); - if (consumerGroupInfo != null) { - List channelList = consumerGroupInfo.getAllChannel(); - for (Channel channel : channelList) { - this.deFiBrokerController.getDeFiBusBroker2Client().notifyWhenTopicConfigChange(channel, topic); - } - } - } - } - - private TopicConfig generateNewTopicConfig(TopicConfig topicConfigOld, int writeQueueSize, int readQueueSize) { - TopicConfig topicConfigNew = new TopicConfig(); - topicConfigNew.setPerm(topicConfigOld.getPerm()); - topicConfigNew.setTopicName(topicConfigOld.getTopicName()); - topicConfigNew.setWriteQueueNums(writeQueueSize); - topicConfigNew.setReadQueueNums(readQueueSize); - topicConfigNew.setOrder(topicConfigOld.isOrder()); - topicConfigNew.setTopicFilterType(topicConfigOld.getTopicFilterType()); - topicConfigNew.setTopicSysFlag(topicConfigOld.getTopicSysFlag()); - return topicConfigNew; - } - - public boolean isCanAdjustReadQueueSize(String topic, int scaleQueueSize) { - TopicConfig topicConfig = deFiBrokerController.getTopicConfigManager().getTopicConfigTable().get(topic); - if (topicConfig != null) { - for (int qId = scaleQueueSize; qId < topicConfig.getReadQueueNums(); qId++) { - long maxOffsetInConsumeQueue = deFiBrokerController.getMessageStore().getMaxOffsetInQueue(topic, qId); - long lastMsgTime = deFiBrokerController.getMessageStore().getMessageStoreTimeStamp(topic, qId, maxOffsetInConsumeQueue - 1); - long diff = System.currentTimeMillis() - lastMsgTime; - if (diff < 60 * 1000) { - log.info("adjust queue num, still new message in within {} ms, default threshold 60000 ms", System.currentTimeMillis() - lastMsgTime); - return false; - } - - Set topicConsumeByWho = this.deFiBrokerController.getConsumerManager().queryTopicConsumeByWho(topic); - Set groupInOffset = this.deFiBrokerController.getConsumerOffsetManager().whichGroupByTopic(topic); - if (groupInOffset != null && !groupInOffset.isEmpty()) { - topicConsumeByWho.addAll(groupInOffset); - } - boolean allConsumed = isAllMessageConsumed(topic, topicConsumeByWho, qId); - if (!allConsumed) { - return false; - } - } - return true; - } - return false; - } - - private boolean isAllMessageConsumed(String topic, Set groups, int queueId) { - for (String group : groups) { - long maxOffset = deFiBrokerController.getMessageStore().getMaxOffsetInQueue(topic, queueId); - long ackOffset = deFiBrokerController.getConsumeQueueManager().queryOffset(group, topic, queueId); - if (ackOffset < maxOffset) { - log.info("not finish consume message for topic: {} by group : {}, queueId: {}, ackOffset: {}, maxOffset: {}", - topic, group, queueId, ackOffset, maxOffset); - return false; - } - } - return true; - } - - public enum AdjustType { - INCREASE_QUEUE_NUM, - DECREASE_QUEUE_NUM - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiConsumerGroupInfo.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiConsumerGroupInfo.java deleted file mode 100644 index c76e492395..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiConsumerGroupInfo.java +++ /dev/null @@ -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. - */ - -package cn.webank.defibus.broker.client; - -import io.netty.channel.Channel; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArraySet; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiConsumerGroupInfo extends ConsumerGroupInfo { - private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private final ConcurrentHashMap/*clientId*/> clientIdMap = new ConcurrentHashMap<>(); - - public DeFiConsumerGroupInfo(String groupName, ConsumeType consumeType, MessageModel messageModel, - ConsumeFromWhere consumeFromWhere) { - super(groupName, consumeType, messageModel, consumeFromWhere); - } - - public boolean registerClientId(final Set subList, final String clientId) { - boolean update = false; - - HashSet subTopicSet = new HashSet<>(); - for (SubscriptionData sub : subList) { - subTopicSet.add(sub.getTopic()); - if (clientIdMap.get(sub.getTopic()) == null) { - update = true; - CopyOnWriteArraySet clientIdSet = new CopyOnWriteArraySet<>(); - clientIdSet.add(clientId); - clientIdMap.put(sub.getTopic(), clientIdSet); - log.info("add clientId {} into {}", clientId, sub.getTopic()); - } else { - if (!clientIdMap.get(sub.getTopic()).contains(clientId)) { - update = true; - clientIdMap.get(sub.getTopic()).add(clientId); - log.info("add clientId {} into {}", clientId, sub.getTopic()); - } - } - } - - Iterator>> it = clientIdMap.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry> entry = it.next(); - String topic = entry.getKey(); - if (entry.getValue().contains(clientId)) { - if (!subTopicSet.contains(topic)) { - entry.getValue().remove(clientId); - update = true; - log.info("remove clientId {} from {}", clientId, topic); - if (entry.getValue().isEmpty()) { - it.remove(); - log.info("remove clientId, clientId set of {} is empty, remove it.", topic); - } - } - } - } - - return update; - } - - public Set unregisterClientId(final ClientChannelInfo clientChannelInfo) { - Set whichTopic = new HashSet<>(); - if (clientChannelInfo != null) { - String clientId = clientChannelInfo.getClientId(); - Iterator>> it = clientIdMap.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry> entry = it.next(); - if (entry.getValue().contains(clientId)) { - log.info("unregister clientId {} from {}", clientId, entry.getKey()); - entry.getValue().remove(clientId); - whichTopic.add(entry.getKey()); - if (entry.getValue().isEmpty()) { - log.info("unregister clientId, clientId set of {} is empty, remove it.", entry.getKey()); - it.remove(); - } - } - } - } - return whichTopic; - } - - @Override - public boolean doChannelCloseEvent(final String remoteAddr, final Channel channel) { - try { - final ClientChannelInfo channelInfo = getChannelInfoTable().get(channel); - if (channelInfo != null) { - unregisterClientId(channelInfo); - } - super.doChannelCloseEvent(remoteAddr, channel); - return true; - } catch (Exception ex) { - log.warn("doChannelCloseEvent fail.", ex); - return false; - } - } - - public Set findSubscribedTopicByClientId(final String clientId) { - Set result = new HashSet<>(); - Iterator>> it = clientIdMap.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry> entry = it.next(); - String topic = entry.getKey(); - if (entry.getValue().contains(clientId)) { - result.add(topic); - } - } - return result; - } - - public Set getClientIdBySubscription(String topic) { - if (topic != null) { - return clientIdMap.get(topic); - } - return new HashSet<>(); - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiConsumerManager.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiConsumerManager.java deleted file mode 100644 index 4da50e9a21..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiConsumerManager.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.client; - -import cn.webank.defibus.common.util.ReflectUtil; -import io.netty.channel.Channel; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ConsumerGroupEvent; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.broker.client.ConsumerIdsChangeListener; -import org.apache.rocketmq.broker.client.ConsumerManager; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.common.RemotingHelper; -import org.apache.rocketmq.remoting.common.RemotingUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiConsumerManager extends ConsumerManager { - private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private static final long CHANNEL_EXPIRED_TIMEOUT = 1000 * 120; - private ConcurrentHashMap consumerTable = - new ConcurrentHashMap(1024); - private final ConsumerIdsChangeListener consumerIdsChangeListener; - private final AdjustQueueNumStrategy adjustQueueNumStrategy; - - public DeFiConsumerManager(final ConsumerIdsChangeListener consumerIdsChangeListener, - final AdjustQueueNumStrategy strategy) { - super(consumerIdsChangeListener); - this.consumerIdsChangeListener = consumerIdsChangeListener; - this.adjustQueueNumStrategy = strategy; - - try { - this.consumerTable = (ConcurrentHashMap) ReflectUtil.getSimpleProperty(ConsumerManager.class, this, "consumerTable"); - } catch (Exception ex) { - log.warn("init DeFiConsumerManager err.", ex); - } - } - - @Override - public boolean registerConsumer(final String group, final ClientChannelInfo clientChannelInfo, - ConsumeType consumeType, MessageModel messageModel, ConsumeFromWhere consumeFromWhere, - final Set subList, boolean isNotifyConsumerIdsChangedEnable) { - ConsumerGroupInfo consumerGroupInfo = this.consumerTable.get(group); - if (null == consumerGroupInfo) { - ConsumerGroupInfo tmp = new DeFiConsumerGroupInfo(group, consumeType, messageModel, consumeFromWhere); - ConsumerGroupInfo prev = this.consumerTable.putIfAbsent(group, tmp); - consumerGroupInfo = prev != null ? prev : tmp; - } - DeFiConsumerGroupInfo deFiConsumerGroupInfo = (DeFiConsumerGroupInfo) consumerGroupInfo; - - Set oldSub = deFiConsumerGroupInfo.findSubscribedTopicByClientId(clientChannelInfo.getClientId()); - boolean r1 = super.registerConsumer(group, clientChannelInfo, consumeType, messageModel, consumeFromWhere, subList, isNotifyConsumerIdsChangedEnable); - boolean r2 = deFiConsumerGroupInfo.registerClientId(subList, clientChannelInfo.getClientId()); - - if (r1 || r2) { - adjustQueueNum(oldSub, subList); - if (isNotifyConsumerIdsChangedEnable) { - this.consumerIdsChangeListener.handle(ConsumerGroupEvent.CHANGE, group, consumerGroupInfo.getAllChannel()); - } - } - - this.consumerIdsChangeListener.handle(ConsumerGroupEvent.REGISTER, group, subList); - return r1 || r2; - } - - @Override - public void unregisterConsumer(final String group, final ClientChannelInfo clientChannelInfo, - boolean isNotifyConsumerIdsChangedEnable) { - ConsumerGroupInfo consumerGroupInfo = this.consumerTable.get(group); - Set subscribeTopics = null; - if (null != consumerGroupInfo) { - DeFiConsumerGroupInfo deFiConsumerGroupInfo = (DeFiConsumerGroupInfo) consumerGroupInfo; - subscribeTopics = deFiConsumerGroupInfo.unregisterClientId(clientChannelInfo); - } - super.unregisterConsumer(group, clientChannelInfo, isNotifyConsumerIdsChangedEnable); - - if (subscribeTopics != null) { - for (String topic : subscribeTopics) { - adjustQueueNumStrategy.decreaseQueueNum(topic); - } - } - } - - @Override - public void doChannelCloseEvent(final String remoteAddr, final Channel channel) { - Set subscribeTopics = null; - Iterator> it = this.consumerTable.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry next = it.next(); - ConsumerGroupInfo info = next.getValue(); - if (info.getChannelInfoTable().get(channel) != null) { - ClientChannelInfo clientChannelInfo = info.getChannelInfoTable().get(channel); - DeFiConsumerGroupInfo deFiConsumerGroupInfo = (DeFiConsumerGroupInfo) info; - subscribeTopics = deFiConsumerGroupInfo.findSubscribedTopicByClientId(clientChannelInfo.getClientId()); - } - } - super.doChannelCloseEvent(remoteAddr, channel); - - if (subscribeTopics != null) { - for (String topic : subscribeTopics) { - adjustQueueNumStrategy.decreaseQueueNum(topic); - } - } - } - - @Override - public void scanNotActiveChannel() { - Iterator> it = this.consumerTable.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry next = it.next(); - String group = next.getKey(); - DeFiConsumerGroupInfo consumerGroupInfo = (DeFiConsumerGroupInfo) next.getValue(); - ConcurrentMap channelInfoTable = - consumerGroupInfo.getChannelInfoTable(); - - Iterator> itChannel = channelInfoTable.entrySet().iterator(); - while (itChannel.hasNext()) { - Map.Entry nextChannel = itChannel.next(); - ClientChannelInfo clientChannelInfo = nextChannel.getValue(); - long diff = System.currentTimeMillis() - clientChannelInfo.getLastUpdateTimestamp(); - if (diff > CHANNEL_EXPIRED_TIMEOUT) { - log.warn( - "SCAN: remove expired channel from ConsumerManager consumerTable. channel={}, consumerGroup={}", - RemotingHelper.parseChannelRemoteAddr(clientChannelInfo.getChannel()), group); - RemotingUtil.closeChannel(clientChannelInfo.getChannel()); - itChannel.remove(); - Set subscribeTopics = consumerGroupInfo.unregisterClientId(clientChannelInfo); - if (subscribeTopics != null) { - for (String topic : subscribeTopics) { - adjustQueueNumStrategy.decreaseQueueNum(topic); - } - } - } - } - - if (channelInfoTable.isEmpty()) { - log.warn( - "SCAN: remove expired channel from ConsumerManager consumerTable, all clear, consumerGroup={}", - group); - it.remove(); - } - } - } - - private void adjustQueueNum(final Set oldSub, final Set subList) { - for (SubscriptionData subscriptionData : subList) { - if (!oldSub.contains(subscriptionData.getTopic())) { - //new sub topic, increase queue num - adjustQueueNumStrategy.increaseQueueNum(subscriptionData.getTopic()); - } - } - for (String topic : oldSub) { - boolean stillSub = false; - for (SubscriptionData subscriptionData : subList) { - if (topic.equals(subscriptionData.getTopic())) { - stillSub = true; - break; - } - } - if (!stillSub) { - //no sub anymore, decrease queue num - adjustQueueNumStrategy.decreaseQueueNum(topic); - } - } - } - - public void notifyWhenTopicConfigChange(String topic) { - adjustQueueNumStrategy.notifyWhenTopicConfigChange(topic); - } - - public ConcurrentHashMap getConsumerTable() { - return this.consumerTable; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiProducerManager.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiProducerManager.java deleted file mode 100644 index dcd681258d..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/client/DeFiProducerManager.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.client; - -import io.netty.channel.Channel; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ProducerManager; -import org.apache.rocketmq.common.constant.LoggerName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiProducerManager extends ProducerManager { - private static final Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - - private final ConcurrentHashMap producerChannelTable - = new ConcurrentHashMap(); - private final Lock deleteChannelLock = new ReentrantLock(); - private static final long LockTimeoutMillis = 3000; - - @SuppressWarnings("unchecked") - public DeFiProducerManager() { - super(); - } - - @Override - public void scanNotActiveChannel() { - super.scanNotActiveChannel(); - } - - @Override - public void doChannelCloseEvent(final String remoteAddr, final Channel channel) { - super.doChannelCloseEvent(remoteAddr, channel); - if (channel == null) { - return; - } - String cid = null; - try { - try { - if (this.deleteChannelLock.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) { - for (Map.Entry entry : producerChannelTable.entrySet()) { - Channel producerChannel = entry.getValue().getChannel(); - if (producerChannel.equals(channel)) { - cid = entry.getKey(); - break; - } - } - if (cid != null) { - producerChannelTable.remove(cid); - } - } - } finally { - this.deleteChannelLock.unlock(); - } - } catch (Exception e) { - LOG.warn("ProducerManager do delete client channel map lock timeout"); - } - } - - @Override - public void registerProducer(final String group, final ClientChannelInfo clientChannelInfo) { - super.registerProducer(group, clientChannelInfo); - producerChannelTable.put(clientChannelInfo.getClientId(), clientChannelInfo); - } - - @Override - public void unregisterProducer(final String group, final ClientChannelInfo clientChannelInfo) { - super.unregisterProducer(group, clientChannelInfo); - producerChannelTable.remove(clientChannelInfo.getClientId()); - } - - public ClientChannelInfo getClientChannel(String clientId) { - return producerChannelTable.get(clientId); - } - - public HashMap> getGroupChannelTable() { - return super.getGroupChannelTable(); - } - - public ConcurrentHashMap getProducerChannelTable() { - return producerChannelTable; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ClientRebalanceResultManager.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ClientRebalanceResultManager.java deleted file mode 100644 index 7edd4f7954..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ClientRebalanceResultManager.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.consumequeue; - -import cn.webank.defibus.broker.DeFiBrokerController; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.rocketmq.common.constant.LoggerName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ClientRebalanceResultManager { - private final DeFiBrokerController deFiBrokerController; - private static final Logger log = LoggerFactory.getLogger(LoggerName.REBALANCE_LOCK_LOGGER_NAME); - - private final ConcurrentHashMap>> clientListenMap - = new ConcurrentHashMap<>(); - - public ClientRebalanceResultManager(DeFiBrokerController deFiBrokerController) { - this.deFiBrokerController = deFiBrokerController; - } - - public void updateListenMap(String group, String topic, int queueId, String clientId) { - ConcurrentHashMap> groupMap = clientListenMap.get(group); - if (groupMap == null) { - groupMap = new ConcurrentHashMap>(); - clientListenMap.put(group, groupMap); - } - ConcurrentHashMap topicMap = groupMap.get(topic); - if (topicMap == null) { - topicMap = new ConcurrentHashMap<>(); - groupMap.put(topic, topicMap); - } - String old = topicMap.put(queueId, clientId); - if (!clientId.equals(old)) { - log.info("update client listen map. new: {} old: {} {} {} {}", - clientId, old, group, topic, queueId); - } - } - - public HashMap getTopicListenMap(String group, String topic) { - HashMap listenMap = new HashMap<>(); - if (clientListenMap.get(group) != null && clientListenMap.get(group).get(topic) != null) { - ConcurrentHashMap queueMap = clientListenMap.get(group).get(topic); - for (Integer queueId : queueMap.keySet()) { - listenMap.put(queueId, queueMap.get(queueId)); - } - } - return listenMap; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueManager.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueManager.java deleted file mode 100644 index dda111388d..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueManager.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.consumequeue; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.broker.client.DeFiConsumerGroupInfo; -import cn.webank.defibus.broker.client.DeFiConsumerManager; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.protocol.DeFiBusTopicConfig; -import io.netty.channel.Channel; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.common.MQVersion; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.body.ResetOffsetBody; -import org.apache.rocketmq.common.protocol.header.ResetOffsetRequestHeader; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ConsumeQueueManager { - private static final Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - - private ConcurrentMap tqMaxAccumulated = new ConcurrentHashMap<>();//accumulated depth for each queue - private static ConsumeQueueManager deFiQueueManager = new ConsumeQueueManager(); - private static final String TOPIC_GROUP_SEPARATOR = "@"; - private ConcurrentMap> lastDeliverOffsetTable = - new ConcurrentHashMap>(512); - private static final double MIN_CLEAN_THRESHOLD = 0.7; - private static final double RESERVE_PERCENT = 0.65; - - private DeFiBrokerController deFiBrokerController; - - private ConsumeQueueManager() { - } - - public void scanUnsubscribedTopic() { - try { - ConcurrentMap> offsetTable = - this.getBrokerController().getConsumerOffsetManager().getOffsetTable(); - Iterator>> it = this.lastDeliverOffsetTable.entrySet().iterator(); - - while (it.hasNext()) { - Map.Entry> next = it.next(); - String topicAtGroup = next.getKey(); - - if (offsetTable.get(topicAtGroup) == null) { - it.remove(); - LOG.warn("scanUnsubscribedTopic remove topic lastDeliverOffsetTable, {}", topicAtGroup); - } - } - } catch (Exception ex) { - LOG.info("scanUnsubscribedTopic fail.", ex); - } - } - - public DeFiBrokerController getBrokerController() { - return deFiBrokerController; - } - - public static ConsumeQueueManager onlyInstance() { - return deFiQueueManager; - } - - public void recordLastDeliverOffset(final String group, final String topic, final int queueId, final long offset) { - String key = topic + TOPIC_GROUP_SEPARATOR + group; - this.lastDeliverOffsetTable.putIfAbsent(key, new ConcurrentHashMap(32)); - ConcurrentMap map = this.lastDeliverOffsetTable.get(key); - map.put(queueId, offset); - } - - public long queryDeliverOffset(final String group, final String topic, final int queueId) { - String key = topic + TOPIC_GROUP_SEPARATOR + group; - ConcurrentMap map = this.lastDeliverOffsetTable.get(key); - if (null != map) { - Long ackOffset = this.getBrokerController().getConsumerOffsetManager().queryOffset(group, topic, queueId); - Long lastDeliverOffset = map.get(queueId); - if (ackOffset == null || lastDeliverOffset == null) - return -1; - - if (lastDeliverOffset < ackOffset) { - map.put(queueId, ackOffset); - } - return map.get(queueId); - } - return -1; - } - - public long getMaxQueueDepth(String topic) { - return this.deFiBrokerController.getExtTopicConfigManager().selectExtTopicConfig(topic).getMaxQueueDepth(); - } - - public void setBrokerController(DeFiBrokerController brokerController) { - this.deFiBrokerController = brokerController; - } - - //update accumulated depth - public void load() { - deFiBrokerController.scheduleTaskAtFixedRate(() -> { - LOG.debug("start to scheduleTask query ConsumeQueueWaterMark"); - Iterator> iterator = tqMaxAccumulated.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - TopicQueue tq = entry.getKey(); - try { - TopicConfig topicConfig = this.getBrokerController().getTopicConfigManager().selectTopicConfig(tq.topic); - if (topicConfig == null) { - iterator.remove(); - LOG.info("scan queue depth. topicConfig is null, remove {}", entry.getValue()); - } else if (tq.queueId >= topicConfig.getReadQueueNums()) { - iterator.remove(); - LOG.info("scan queue depth. qId is invalid, topicConfig.ReadQueueNums={}, remove {}", topicConfig.getReadQueueNums(), entry.getValue()); - } else { - ConsumeQueueWaterMark consumeQueueWaterMark = ConsumeQueueManager.this.calculateMinAccumulated(tq.topic, tq.queueId); - if (consumeQueueWaterMark != null) { - ConsumeQueueWaterMark oldCqWm = tqMaxAccumulated.put(tq, consumeQueueWaterMark); - if (LOG.isDebugEnabled()) { - if (!consumeQueueWaterMark.equals(oldCqWm)) { - LOG.debug("[UPDATE ConsumeQueueWaterMark] Updated for {}, -> {}", tq, consumeQueueWaterMark); - } else { - LOG.debug("[UPDATE ConsumeQueueWaterMark] Does not changed for {}, {}, {} ", tq, oldCqWm, consumeQueueWaterMark); - } - } - } else { - LOG.warn("ConsumeQueueWaterMark is null for {} , remove it from tqMaxAccumulated", tq); - } - } - } catch (Exception e) { - LOG.error("unknow error when update ConsumeQueueWaterMark for " + tq, e); - } - } - }, 1000, deFiBrokerController.getDeFiBusBrokerConfig().getDepthCheckInterval()); - } - - public ConsumeQueueWaterMark getMinAccumulated(String topic, int queueId) { - TopicQueue tq = new TopicQueue(topic, queueId); - //calculate the accumulated depth for the first time, or get the value in other case - if (!tqMaxAccumulated.containsKey(tq)) { - ConsumeQueueWaterMark consumeQueueWaterMark = calculateMinAccumulated(topic, queueId); - if (consumeQueueWaterMark != null) { - tqMaxAccumulated.putIfAbsent(tq, consumeQueueWaterMark); - LOG.debug("ConsumeQueueWaterMark is put first time : {}", consumeQueueWaterMark); - } else { - LOG.warn("[BUG]calculateMaxAccumulated returns null for {}-{}", topic, queueId); - } - } - - return tqMaxAccumulated.get(tq); - } - - //use as key in tqMaxAccumulated - private static class TopicQueue { - private final String topic; - private final int queueId; - - private TopicQueue(String topic, int queueId) { - this.topic = topic; - this.queueId = queueId; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof TopicQueue)) - return false; - - TopicQueue that = (TopicQueue) o; - - if (queueId != that.queueId) - return false; - return topic.equals(that.topic); - } - - @Override - public int hashCode() { - int result = topic.hashCode(); - result = 31 * result + queueId; - return result; - } - - @Override - public String toString() { - return "TopicQueue{" + - "topic='" + topic + '\'' + - ", queueId=" + queueId + - '}'; - } - } - - public ConsumeQueueWaterMark calculateMinAccumulated(String topic, int queueId) { - Set subscribedGroups = deFiBrokerController.getConsumerOffsetManager().whichGroupByTopic(topic); - Set checkGroups = new HashSet(); - DeFiBusTopicConfig deFiBusTopicConfig = this.getBrokerController().getExtTopicConfigManager().selectExtTopicConfig(topic); - long maxDepth = deFiBusTopicConfig != null ? deFiBusTopicConfig.getMaxQueueDepth() : DeFiBusTopicConfig.DEFAULT_QUEUE_LENGTH; - double highWatermark = deFiQueueManager.getBrokerController().getDeFiBusBrokerConfig().getQueueDepthHighWatermark(); - ConsumeQueueWaterMark minDepth = null; - long maxOffset = this.deFiBrokerController.getMessageStore().getMaxOffsetInQueue(topic, queueId); - LOG.debug("calculateMinAccumulated topic:{},queueID:{},subscribedGroups{}", topic, queueId, subscribedGroups); - - //calculate accumulated depth for each consumer group - for (String consumerGroup : subscribedGroups) { - if (topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX) || topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX) || consumerGroup.startsWith(DeFiBusConstant.EXT_CONSUMER_GROUP)) { - continue; - } - - DeFiConsumerManager consumerManager = (DeFiConsumerManager) this.deFiBrokerController.getConsumerManager(); - DeFiConsumerGroupInfo deFiConsumerGroupInfo = (DeFiConsumerGroupInfo) consumerManager.getConsumerGroupInfo(consumerGroup); - - //ignore offline consumer group - if (deFiConsumerGroupInfo == null || deFiConsumerGroupInfo.getClientIdBySubscription(topic) == null - || deFiConsumerGroupInfo.getClientIdBySubscription(topic).isEmpty()) { - continue; - } - long ackOffset = queryOffset(consumerGroup, topic, queueId); - long thisDepth = maxOffset - ackOffset; - long lastDeliverOffset = queryDeliverOffset(consumerGroup, topic, queueId); - - if (lastDeliverOffset >= 0) { - thisDepth = maxOffset - lastDeliverOffset; - } - - checkGroups.add(consumerGroup); - ConsumeQueueWaterMark depthOfThisGroup = new ConsumeQueueWaterMark(consumerGroup, topic, queueId, lastDeliverOffset, thisDepth); - if (minDepth == null) { - minDepth = depthOfThisGroup; - } else if (depthOfThisGroup.getAccumulated() < minDepth.getAccumulated()) { - minDepth = depthOfThisGroup; - } - - LOG.debug("topic:{},queueID:{},depthOfThisGroup:{} ,minDepth:{}", topic, queueId, depthOfThisGroup, minDepth); - - if (depthOfThisGroup.getAccumulated() > maxDepth) { - LOG.error("Quota exceed 100% for topic:{},queueID:{},depthOfThisGroup:{} ,maxDepth:{} maxOffset: {} ackOffset: {}" - , topic, queueId, depthOfThisGroup, maxDepth, maxOffset, ackOffset); - } else if (depthOfThisGroup.getAccumulated() > maxDepth * highWatermark) { - LOG.error("Quota exceed {}% for topic:{}, queueID:{}, depthOfThisGroup:{}, maxDepth:{} maxOffset: {} ackOffset: {}" - , highWatermark * 100, topic, queueId, depthOfThisGroup, maxDepth, maxOffset, ackOffset); - } - } - - if (checkGroups.isEmpty()) { - minDepth = new ConsumeQueueWaterMark("NO_ONLINE_GROUP", topic, queueId, maxOffset, 0); - } - - for (String consumerGroup : checkGroups) { - long thisDepth = maxOffset - queryOffset(consumerGroup, topic, queueId); - long lastDeliverOffset = queryDeliverOffset(consumerGroup, topic, queueId); - - if (lastDeliverOffset >= 0) { - thisDepth = maxOffset - lastDeliverOffset; - } - - if (thisDepth > maxDepth) { - if (checkGroups.size() > 1 && minDepth.getAccumulated() < maxDepth * MIN_CLEAN_THRESHOLD) { - autoUpdateDepth(consumerGroup, topic, queueId, maxDepth, maxOffset); - } - } - } - return minDepth; - } - - private void autoUpdateDepth(String consumerGroup, String topic, int queueId, long maxDepth, long maxOffset) { - if (!this.deFiBrokerController.getDeFiBusBrokerConfig().isAutoUpdateDepth()) { - return; - } - - DeFiConsumerManager consumerManager = this.deFiBrokerController.getConsumerManager(); - DeFiConsumerGroupInfo deFiConsumerGroupInfo = (DeFiConsumerGroupInfo) consumerManager.getConsumerGroupInfo(consumerGroup); - - //ignore offline consumer group - if (deFiConsumerGroupInfo == null || deFiConsumerGroupInfo.getClientIdBySubscription(topic) == null - || deFiConsumerGroupInfo.getClientIdBySubscription(topic).isEmpty()) { - return; - } - - long lastDeliverOffset = queryDeliverOffset(consumerGroup, topic, queueId); - long nowDeliverOffset = maxOffset - (long) (maxDepth * RESERVE_PERCENT); - - this.deFiBrokerController.getConsumeQueueManager().recordLastDeliverOffset(consumerGroup, topic, queueId, nowDeliverOffset); - LOG.warn("autoUpdateDepth for {}, topic: {}, queueId: {}, maxOffset:{}, lastDeliverOffset: {}, maxQueueDepth:{}, nowDeliverOffset: {}" - , consumerGroup, topic, queueId, maxOffset, lastDeliverOffset, maxDepth, nowDeliverOffset); - - if (this.deFiBrokerController.getConsumerOffsetManager().queryOffset(consumerGroup, topic, queueId) != -1) { - this.deFiBrokerController.getConsumerOffsetManager().commitOffset("resetByBroker", consumerGroup, topic, queueId, nowDeliverOffset); - } else { - LOG.warn("no consumerOffset in consumerOffsetManager, skip reset consumerOffset. group={}, topic={}, queueId={}", consumerGroup, topic, queueId); - } - - resetOffsetOnClient(consumerGroup, topic, queueId, maxDepth, maxOffset); - } - - public long queryOffset(final String group, final String topic, final int queueId) { - String key = topic + TOPIC_GROUP_SEPARATOR + group; - ConcurrentMap map = this.deFiBrokerController.getConsumerOffsetManager().getOffsetTable().get(key); - if (null != map) { - Long offset = map.get(queueId); - if (offset != null) - return offset; - } - - return -1; - } - - public void resetOffsetOnClient(String consumerGroup, String topic, int queueId, long maxDepth, long maxOffset) { - long nowDeliverOffset = maxOffset - (long) (maxDepth * RESERVE_PERCENT); - Map offsetTable = new HashMap(); - TopicConfig topicConfig = deFiBrokerController.getTopicConfigManager().selectTopicConfig(topic); - - if (queueId < topicConfig.getWriteQueueNums()) { - MessageQueue mq = new MessageQueue(topic, deFiBrokerController.getBrokerConfig().getBrokerName(), queueId); - offsetTable.put(mq, nowDeliverOffset); - } - - ResetOffsetRequestHeader requestHeader = new ResetOffsetRequestHeader(); - requestHeader.setTopic(topic); - requestHeader.setGroup(consumerGroup); - requestHeader.setTimestamp(0); - RemotingCommand request = - RemotingCommand.createRequestCommand(RequestCode.RESET_CONSUMER_CLIENT_OFFSET, requestHeader); - - ResetOffsetBody body = new ResetOffsetBody(); - body.setOffsetTable(offsetTable); - request.setBody(body.encode()); - - ConsumerGroupInfo consumerGroupInfo = - this.deFiBrokerController.getConsumerManager().getConsumerGroupInfo(consumerGroup); - - if (consumerGroupInfo != null && !consumerGroupInfo.getAllChannel().isEmpty()) { - ConcurrentMap channelInfoTable = - consumerGroupInfo.getChannelInfoTable(); - for (Map.Entry entry : channelInfoTable.entrySet()) { - int version = entry.getValue().getVersion(); - if (version >= MQVersion.Version.V3_0_7_SNAPSHOT.ordinal()) { - try { - this.deFiBrokerController.getRemotingServer().invokeOneway(entry.getKey(), request, 5000); - LOG.info("[reset-offset] reset offset success. topic={}, group={}, clientId={}", - topic, consumerGroup, entry.getValue().getClientId()); - } catch (Exception e) { - LOG.warn("[reset-offset] reset offset failed. topic={}, group={}", - new Object[] {topic, consumerGroup}, e); - } - } - } - } else { - String errorInfo = - String.format("Consumer not online, so can not reset offset, Group: %s Topic: %s Timestamp: %d", - requestHeader.getGroup(), - requestHeader.getTopic(), - requestHeader.getTimestamp()); - LOG.info(errorInfo); - return; - } - } -} - diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueWaterMark.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueWaterMark.java deleted file mode 100644 index 93afb47d0b..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueWaterMark.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.consumequeue; - -public class ConsumeQueueWaterMark { - private String consumerGroup; - private final String topic; - private final int queueId; - private long lastDeliverOffset; - private long accumulated; - - public ConsumeQueueWaterMark(String consumerGroup, String topic, int queueId, long lastDeliverOffset, - long accumulated) { - this.consumerGroup = consumerGroup; - this.topic = topic; - this.queueId = queueId; - this.lastDeliverOffset = lastDeliverOffset; - this.accumulated = accumulated; - } - - public ConsumeQueueWaterMark(String consumerGroup, String topic, int queueId) { - this.consumerGroup = consumerGroup; - this.topic = topic; - this.queueId = queueId; - } - - public ConsumeQueueWaterMark(String topic, int queueId) { - this.topic = topic; - this.queueId = queueId; - } - - public void setLastDeliverOffset(long lastDeliverOffset) { - this.lastDeliverOffset = lastDeliverOffset; - } - - public void setAccumulated(long accumulated) { - this.accumulated = accumulated; - } - - public long getAccumulated() { - return accumulated; - } - - public String getConsumerGroup() { - return consumerGroup; - } - - public String getTopic() { - return topic; - } - - public int getQueueId() { - return queueId; - } - - public long getLastDeliverOffset() { - return lastDeliverOffset; - } - - @Override - public String toString() { - return "ConsumeQueueWaterMark{" + - "consumerGroup='" + consumerGroup + '\'' + - ", topic='" + topic + '\'' + - ", queueId=" + queueId + - ", lastDeliverOffset=" + lastDeliverOffset + - ", accumulated=" + accumulated + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof ConsumeQueueWaterMark)) - return false; - - ConsumeQueueWaterMark that = (ConsumeQueueWaterMark) o; - - if (queueId != that.queueId) - return false; - if (lastDeliverOffset != that.lastDeliverOffset) - return false; - if (accumulated != that.accumulated) - return false; - if (!consumerGroup.equals(that.consumerGroup)) - return false; - return topic.equals(that.topic); - } - - @Override - public int hashCode() { - int result = consumerGroup.hashCode(); - result = 31 * result + topic.hashCode(); - result = 31 * result + queueId; - result = 31 * result + (int) (lastDeliverOffset ^ (lastDeliverOffset >>> 32)); - result = 31 * result + (int) (accumulated ^ (accumulated >>> 32)); - return result; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/MessageRedirectManager.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/MessageRedirectManager.java deleted file mode 100644 index 092c988c6c..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/consumequeue/MessageRedirectManager.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.consumequeue; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.broker.DeFiBrokerPathConfigHelper; -import com.alibaba.fastjson.JSON; -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.common.ConfigManager; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MessageRedirectManager { - private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private final ConcurrentHashMap> redirectMap = new ConcurrentHashMap<>(); - private final DeFiBrokerController deFiBrokerController; - private Random random = new Random(); - RedirectConfigManager configManager; - - public MessageRedirectManager(DeFiBrokerController deFiBrokerController) { - this.deFiBrokerController = deFiBrokerController; - configManager = new RedirectConfigManager(); - configManager.load(); - } - - public void shutdown() { - if (configManager != null) { - configManager.persist(); - } - } - - public RedirectResult redirectMessageToWhichQueue(SendMessageRequestHeader requestHeader, String flag) { - if (hasRedirectConfig(flag, requestHeader.getTopic())) { - ArrayList grayQueueId = findCandidateQueueId(flag, requestHeader.getTopic()); - if (grayQueueId.size() > 0) { - int redirectQueueId = grayQueueId.get(Math.abs(random.nextInt()) % grayQueueId.size()); - return new RedirectResult(RedirectStates.REDIRECT_OK, redirectQueueId); - } else { - return new RedirectResult(RedirectStates.NO_INSTANCE_FOUND, -1); - } - } else { - return new RedirectResult(RedirectStates.NO_REDIRECT_CONFIG, -1); - } - } - - private boolean hasRedirectConfig(String flag, String topic) { - if (flag != null && topic != null) { - return redirectMap.get(topic) != null - && redirectMap.get(topic).get(flag) != null - && redirectMap.get(topic).get(flag).getIps().size() > 0; - } - return false; - } - - private ArrayList findCandidateQueueId(String flag, String topic) { - ArrayList candidateQueueId = new ArrayList<>(); - if (flag != null) { - ConcurrentHashMap flagMap = redirectMap.get(topic); - if (flagMap != null) { - RedirectConfItem confItems = flagMap.get(flag); - if (confItems != null) { - String groupName = confItems.getConsumerGroup(); - HashMap cidMap = deFiBrokerController.getClientRebalanceResultManager().getTopicListenMap(groupName, topic); - for (Integer qId : cidMap.keySet()) { - String cid = cidMap.get(qId); - if (StringUtils.isNotEmpty(cid)) { - String ip = StringUtils.split(cid, "@")[0]; - if (confItems.getIps().contains(ip)) { - candidateQueueId.add(qId); - } - } - } - } - } - } - return candidateQueueId; - } - - public void updateConfigs(List list) { - List old = getConfigList(); - for (RedirectConfItem item : list) { - ConcurrentHashMap flagMap = redirectMap.get(item.getTopic()); - if (flagMap == null) { - flagMap = new ConcurrentHashMap<>(); - redirectMap.put(item.getTopic(), flagMap); - } - RedirectConfItem oldItem = flagMap.put(item.getRedirectFlag(), item); - if (oldItem != null && !oldItem.equals(item)) { - log.info("update redirect message config, old: {} new: {}", oldItem, item); - } - } - } - - public List getConfigList() { - List list = new ArrayList<>(); - for (String topic : redirectMap.keySet()) { - for (String flag : redirectMap.get(topic).keySet()) { - list.add(redirectMap.get(topic).get(flag)); - } - } - return list; - } - - public static class RedirectConfItem { - String topic; - String consumerGroup; - String redirectFlag; - Set ips = new HashSet<>(); - - public String getTopic() { - return topic; - } - - public void setTopic(String topic) { - this.topic = topic; - } - - public String getConsumerGroup() { - return consumerGroup; - } - - public void setConsumerGroup(String consumerGroup) { - this.consumerGroup = consumerGroup; - } - - public String getRedirectFlag() { - return redirectFlag; - } - - public void setRedirectFlag(String redirectFlag) { - this.redirectFlag = redirectFlag; - } - - public Set getIps() { - return ips; - } - - public void setIps(Set ips) { - this.ips = ips; - } - - public boolean equals(RedirectConfItem obj) { - return obj != null && this.topic.equals(obj.getTopic()) - && this.redirectFlag.equals(obj.getRedirectFlag()) - && this.consumerGroup.equals(obj.getConsumerGroup()) - && this.ips.equals(obj.getIps()); - } - - @Override public String toString() { - return "RedirectConfItem{" + - "topic='" + topic + '\'' + - ", consumerGroup='" + consumerGroup + '\'' + - ", redirectFlag='" + redirectFlag + '\'' + - ", ips=" + ips + - '}'; - } - } - - public class RedirectResult { - RedirectStates states; - int redirectQueueId; - - public RedirectResult(RedirectStates states, int redirectQueueId) { - this.states = states; - this.redirectQueueId = redirectQueueId; - } - - public RedirectStates getStates() { - return states; - } - - public int getRedirectQueueId() { - return redirectQueueId; - } - } - - public enum RedirectStates { - REDIRECT_OK, - NO_REDIRECT_CONFIG, - NO_INSTANCE_FOUND - } - - public class RedirectConfigManager extends ConfigManager { - private List configList = new ArrayList<>(); - - @Override public String encode() { - return encode(false); - } - - @Override public String configFilePath() { - String rootDir = DeFiBrokerPathConfigHelper.getBrokerConfigPath(); - return rootDir + File.separator + "messageRedirectConfig.json"; - } - - @Override public void decode(String jsonString) { - if (jsonString != null) { - List list = JSON.parseArray(jsonString, RedirectConfItem.class); - if (list != null) { - updateConfigs(list); - } - } - } - - @Override public String encode(boolean prettyFormat) { - return JSON.toJSONString(getConfigList(), prettyFormat); - } - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/monitor/QueueListeningMonitor.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/monitor/QueueListeningMonitor.java deleted file mode 100644 index 9ed0702f2e..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/monitor/QueueListeningMonitor.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.monitor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import io.netty.channel.Channel; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.common.MQVersion; -import org.apache.rocketmq.common.ThreadFactoryImpl; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.body.ConsumerRunningInfo; -import org.apache.rocketmq.common.protocol.header.GetConsumerRunningInfoRequestHeader; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.common.RemotingHelper; -import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class QueueListeningMonitor { - private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private final DeFiBrokerController deFiBrokerController; - private final ScheduledExecutorService scheduledExecutorService; - - public QueueListeningMonitor(DeFiBrokerController deFiBrokerController) { - this.deFiBrokerController = deFiBrokerController; - scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl( - "ScanQueueListeningScheduledThread")); - } - - public void start() { - scheduledExecutorService.scheduleAtFixedRate( - () -> { - try { - scanQueueMissListening(); - } catch (Throwable e) { - log.warn("scan queue miss listening : ", e); - } - }, - deFiBrokerController.getDeFiBusBrokerConfig().getCheckQueueListeningPeriod(), - deFiBrokerController.getDeFiBusBrokerConfig().getCheckQueueListeningPeriod(), - TimeUnit.MINUTES); - } - - public void shutdown() { - scheduledExecutorService.shutdown(); - } - - private void scanQueueMissListening() { - if (!deFiBrokerController.getDeFiBusBrokerConfig().isCheckQueueListening()) { - return; - } - - for (Map.Entry entry : deFiBrokerController.getConsumerManager().getConsumerTable().entrySet()) { - String groupName = entry.getKey(); - ConsumerGroupInfo groupInfo = entry.getValue(); - if (groupInfo.getMessageModel().equals(MessageModel.BROADCASTING)) { - continue; - } - - boolean rebalanceRecently = false; - - Map listenQueueCountMap = new HashMap<>(); - - groupLoop: - for (Channel channel : groupInfo.getChannelInfoTable().keySet()) { - ClientChannelInfo clientChannelInfo = groupInfo.getChannelInfoTable().get(channel); - - if (clientChannelInfo.getVersion() < MQVersion.Version.V3_1_8_SNAPSHOT.ordinal()) { - log.warn("The Consumer <{}> Version <{}> too low to finish, please upgrade it to V3_1_8_SNAPSHOT", - clientChannelInfo.getClientId(), - MQVersion.getVersionDesc(clientChannelInfo.getVersion())); - continue; - } - - ConsumerRunningInfo runningInfo = callConsumer(groupName, clientChannelInfo); - - if (runningInfo == null) { - log.warn("[MISS LISTENING] clientId <{}> group <{}>, runningInfo is null", clientChannelInfo.getClientId(), groupName); - continue; - } - - for (SubscriptionData subscriptionData : runningInfo.getSubscriptionSet()) { - if (System.currentTimeMillis() - subscriptionData.getSubVersion() < 2 * 60 * 1000) { - rebalanceRecently = true; - break groupLoop; - } - } - - //miss listening when subscribing a topic but not listening any queue - if (runningInfo.getSubscriptionSet() != null && !runningInfo.getSubscriptionSet().isEmpty() && runningInfo.getMqTable().isEmpty()) { - log.warn("[MISS LISTENING] clientId <{}> group <{}>, listening none queue", clientChannelInfo.getClientId(), groupName); - continue; - } - - String analyzeProcessQueue = ConsumerRunningInfo.analyzeProcessQueue(clientChannelInfo.getClientId(), runningInfo); - if (StringUtils.isNotEmpty(analyzeProcessQueue)) { - log.warn("[BLOCKED SUBSCRIBER] " + analyzeProcessQueue); - } - - Set mqSet = runningInfo.getMqTable().keySet(); - for (MessageQueue mq : mqSet) { - if (!mq.getBrokerName().equals(this.deFiBrokerController.getBrokerConfig().getBrokerName())) { - continue; - } - Integer listenQueueNum = listenQueueCountMap.get(mq.getTopic()); - if (listenQueueNum == null) - listenQueueNum = 0; - - listenQueueCountMap.put(mq.getTopic(), listenQueueNum + 1); - } - } - - //skip if do rebalance in 2 min - if (!rebalanceRecently) { - for (String topic : listenQueueCountMap.keySet()) { - TopicConfig topicConfig = this.deFiBrokerController.getTopicConfigManager().selectTopicConfig(topic); - if (null == topicConfig) { - continue; - } - int queueNum = topicConfig.getReadQueueNums(); - int listeningNum = listenQueueCountMap.get(topic); - if (queueNum != listeningNum) { - log.warn("[MISS LISTENING] group <{}>, topic={}, queueNum={}, listeningNum={}", groupName, topic, queueNum, listeningNum); - } - } - } - - } - } - - private ConsumerRunningInfo callConsumer(String groupName, ClientChannelInfo clientChannelInfo) { - - String clientId = clientChannelInfo.getClientId(); - - GetConsumerRunningInfoRequestHeader requestHeader = new GetConsumerRunningInfoRequestHeader(); - requestHeader.setConsumerGroup(groupName); - requestHeader.setClientId(clientId); - requestHeader.setJstackEnable(false); - - try { - - RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_CONSUMER_RUNNING_INFO, requestHeader); - - RemotingCommand response = this.deFiBrokerController.getBroker2Client().callClient(clientChannelInfo.getChannel(), request); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - byte[] body = response.getBody(); - if (body != null) { - return ConsumerRunningInfo.decode(body, ConsumerRunningInfo.class); - } - } - default: - break; - } - - } catch (RemotingTimeoutException e) { - log.warn("consumer <{}> <{}> Timeout: {}", groupName, clientId, RemotingHelper.exceptionSimpleDesc(e)); - } catch (Exception e) { - log.warn("invoke consumer <{}> <{}> Exception: {}", groupName, clientId, RemotingHelper.exceptionSimpleDesc(e)); - } - - log.warn("consumer <{}> <{}> running info result null", groupName, clientId); - return null; - } - -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/net/DeFiBusBroker2Client.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/net/DeFiBusBroker2Client.java deleted file mode 100644 index 37827d84b5..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/net/DeFiBusBroker2Client.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.net; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.protocol.header.NotifyTopicChangedRequestHeader; -import cn.webank.defibus.common.protocol.header.ReplyMessageRequestHeader; -import io.netty.channel.Channel; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusBroker2Client { - private static final Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private final DeFiBrokerController deFiBrokerController; - - public DeFiBusBroker2Client(DeFiBrokerController deFiBrokerController) { - this.deFiBrokerController = deFiBrokerController; - } - - public boolean pushRRReplyMessageToClient(final Channel channel, - ReplyMessageRequestHeader replyMessageRequestHeader, MessageExt msgInner) { - replyMessageRequestHeader.setSysFlag(msgInner.getSysFlag()); - RemotingCommand request = RemotingCommand.createRequestCommand(DeFiBusRequestCode.PUSH_RR_REPLY_MSG_TO_CLIENT, replyMessageRequestHeader); - request.markOnewayRPC(); - request.setBody(msgInner.getBody()); - try { - this.deFiBrokerController.getRemotingServer().invokeOneway(channel, request, 3000); - } catch (RemotingTimeoutException e) { - LOG.warn("push reply message to client failed ", e); - try { - this.deFiBrokerController.getRemotingServer().invokeOneway(channel, request, 3000); - } catch (Exception sube) { - LOG.warn("push reply message to client failed again ", sube); - return false; - } - } catch (Exception e) { - LOG.warn("push reply message to client failed ", e); - return false; - } - - return true; - } - - public void notifyWhenTopicConfigChange(final Channel channel, String topic) { - NotifyTopicChangedRequestHeader notifyTopicChangedRequestHeader = new NotifyTopicChangedRequestHeader(); - notifyTopicChangedRequestHeader.setTopic(topic); - RemotingCommand remotingCommand = RemotingCommand.createRequestCommand(DeFiBusRequestCode.NOTIFY_WHEN_TOPIC_CONFIG_CHANGE, notifyTopicChangedRequestHeader); - remotingCommand.markOnewayRPC(); - try { - this.deFiBrokerController.getRemotingServer().invokeOneway(channel, remotingCommand, 500); - } catch (Exception e) { - LOG.warn("notify consumer <" + channel + "> topic config change fail.", e); - } - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/plugin/DeFiPluginMessageStore.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/plugin/DeFiPluginMessageStore.java deleted file mode 100644 index fee67360c0..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/plugin/DeFiPluginMessageStore.java +++ /dev/null @@ -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. - */ - -package cn.webank.defibus.broker.plugin; - -import cn.webank.defibus.broker.consumequeue.ConsumeQueueManager; -import cn.webank.defibus.common.DeFiBusConstant; -import org.apache.rocketmq.broker.plugin.AbstractPluginMessageStore; -import org.apache.rocketmq.broker.plugin.MessageStorePluginContext; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.message.MessageAccessor; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.message.MessageExtBatch; -import org.apache.rocketmq.store.GetMessageResult; -import org.apache.rocketmq.store.GetMessageStatus; -import org.apache.rocketmq.store.MessageExtBrokerInner; -import org.apache.rocketmq.store.MessageFilter; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.PutMessageResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiPluginMessageStore extends AbstractPluginMessageStore { - private final static Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - protected MessageStore next = null; - protected MessageStorePluginContext context; - private ConsumeQueueManager deFiQueueManager = ConsumeQueueManager.onlyInstance(); - private final PluginStoreStatService pluginStoreStatService = new PluginStoreStatService(); - private final String clusterName = deFiQueueManager.getBrokerController().getBrokerConfig().getBrokerClusterName(); - private final String brokerName = deFiQueueManager.getBrokerController().getBrokerConfig().getBrokerName(); - - public DeFiPluginMessageStore(MessageStorePluginContext context, MessageStore next) { - super(context, next); - this.next = next; - this.context = context; - } - - @Override - public void start() throws Exception { - pluginStoreStatService.start(); - next.start(); - } - - @Override - public void shutdown() { - next.shutdown(); - pluginStoreStatService.shutdown(); - } - - @Override - public PutMessageResult putMessage(MessageExtBrokerInner msg) { - long startTime = System.nanoTime(); - MessageAccessor.putProperty(msg, DeFiBusConstant.PROPERTY_MESSAGE_CLUSTER, clusterName); - MessageAccessor.putProperty(msg, DeFiBusConstant.PROPERTY_MESSAGE_BROKER, brokerName); - msg.setPropertiesString(MessageDecoder.messageProperties2String(msg.getProperties())); - - PutMessageResult result = next.putMessage(msg); - long eclipseNanoTime = System.nanoTime() - startTime; - pluginStoreStatService.recordPutTime(eclipseNanoTime); - return result; - } - - @Override - public PutMessageResult putMessages(MessageExtBatch messageExtBatch) { - long startTime = System.nanoTime(); - PutMessageResult result = next.putMessages(messageExtBatch); - long eclipseNanoTime = System.nanoTime() - startTime; - pluginStoreStatService.recordPutTime(eclipseNanoTime); - return result; - } - - @Override - public GetMessageResult getMessage(String group, String topic, int queueId, long offset, - int maxMsgNums, final MessageFilter messageFilter) { - long startTime = System.nanoTime(); - GetMessageResult getMessageResult - = next.getMessage(group, topic, queueId, offset, maxMsgNums, messageFilter); - - if (getMessageResult.getStatus().equals(GetMessageStatus.FOUND)) { - this.deFiQueueManager.recordLastDeliverOffset(group, topic, queueId, getMessageResult.getNextBeginOffset()); - } - - long eclipseNanoTime = System.nanoTime() - startTime; - pluginStoreStatService.recordGetTime(eclipseNanoTime); - - return getMessageResult; - } - - public MessageStore getDefaultMessageStore() { - return next; - } -} \ No newline at end of file diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/plugin/PluginStoreStatService.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/plugin/PluginStoreStatService.java deleted file mode 100644 index 01e987e3bc..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/plugin/PluginStoreStatService.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.plugin; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import org.apache.rocketmq.common.ThreadFactoryImpl; -import org.apache.rocketmq.common.constant.LoggerName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PluginStoreStatService { - private final static Logger LOG = LoggerFactory.getLogger(LoggerName.ROCKETMQ_STATS_LOGGER_NAME); - private final String[] MESSAGE_ENTIRE_TIME_DESC = new String[] { - "[<=1000ns]", "[<=10000ns]", "[10000~100000ns]", - "[100000~1000000ns]", "[1~10ms]", "[10~100ms]", "[100~1000ms]", "[>=1000ms]"}; - private volatile AtomicLong[] putMessageDistributeTime; - private volatile AtomicLong[] getMessageDistributeTime; - private ScheduledExecutorService scheduleService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl - ("DeFiBusPluginStore_Stat_")); - - public void start() { - putMessageDistributeTime = new AtomicLong[MESSAGE_ENTIRE_TIME_DESC.length]; - getMessageDistributeTime = new AtomicLong[MESSAGE_ENTIRE_TIME_DESC.length]; - for (int i = 0; i < MESSAGE_ENTIRE_TIME_DESC.length; i++) { - putMessageDistributeTime[i] = new AtomicLong(0); - getMessageDistributeTime[i] = new AtomicLong(0); - } - - scheduleService.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - printStoreStat(); - } - }, 60 * 1000, 60 * 1000, TimeUnit.MILLISECONDS); - - } - - public void shutdown() { - scheduleService.shutdownNow(); - } - - public void recordPutTime(long value) { - final AtomicLong[] times = this.putMessageDistributeTime; - - if (null == times) - return; - - if (value <= 1000) { - times[0].incrementAndGet(); - } else if (value < 10000) { - times[1].incrementAndGet(); - } else if (value < 100000) { - times[2].incrementAndGet(); - } else if (value < 1000000) { - times[3].incrementAndGet(); - } else if (value < 10000000) { - times[4].incrementAndGet(); - } else if (value < 100000000) { - times[5].incrementAndGet(); - } else if (value < 1000000000) { - times[6].incrementAndGet(); - } else { - times[7].incrementAndGet(); - } - } - - public void recordGetTime(long value) { - final AtomicLong[] times = this.getMessageDistributeTime; - - if (null == times) - return; - - //stat - if (value <= 1000) { - times[0].incrementAndGet(); - } else if (value < 10000) { - times[1].incrementAndGet(); - } else if (value < 100000) { - times[2].incrementAndGet(); - } else if (value < 1000000) { - times[3].incrementAndGet(); - } else if (value < 10000000) { - times[4].incrementAndGet(); - } else if (value < 100000000) { - times[5].incrementAndGet(); - } else if (value < 1000000000) { - times[6].incrementAndGet(); - } else { - times[7].incrementAndGet(); - } - } - - public void printStoreStat() { - StringBuilder sbPut = new StringBuilder(); - for (int i = 0; i < MESSAGE_ENTIRE_TIME_DESC.length; i++) { - long value = putMessageDistributeTime[i].get(); - sbPut.append(String.format("%s:%d", MESSAGE_ENTIRE_TIME_DESC[i], value)); - sbPut.append(" "); - } - - StringBuilder sbGet = new StringBuilder(); - for (int i = 0; i < MESSAGE_ENTIRE_TIME_DESC.length; i++) { - long value = getMessageDistributeTime[i].get(); - sbGet.append(String.format("%s:%d", MESSAGE_ENTIRE_TIME_DESC[i], value)); - sbGet.append(" "); - } - - LOG.info("putMessage stat:" + sbPut); - LOG.info("getMessage stat:" + sbGet); - for (int i = 0; i < MESSAGE_ENTIRE_TIME_DESC.length; i++) { - putMessageDistributeTime[i].set(0); - } - - for (int i = 0; i < MESSAGE_ENTIRE_TIME_DESC.length; i++) { - getMessageDistributeTime[i].set(0); - } - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiAdminBrokerProcessor.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiAdminBrokerProcessor.java deleted file mode 100644 index 51af081b69..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiAdminBrokerProcessor.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusVersion; -import cn.webank.defibus.common.admin.DeFiBusConsumeStats; -import cn.webank.defibus.common.admin.DeFiBusOffsetWrapper; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.protocol.DeFiBusTopicConfig; -import io.netty.channel.ChannelHandlerContext; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.UtilAll; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.body.KVTable; -import org.apache.rocketmq.common.protocol.header.CreateTopicRequestHeader; -import org.apache.rocketmq.common.protocol.header.GetConsumeStatsRequestHeader; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.common.RemotingHelper; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyRequestProcessor; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.store.DefaultMessageStore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiAdminBrokerProcessor implements NettyRequestProcessor { - private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private final DeFiBrokerController deFiBrokerController; - - public DeFiAdminBrokerProcessor(final DeFiBrokerController deFiBrokerController) { - this.deFiBrokerController = deFiBrokerController; - } - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - switch (request.getCode()) { - case RequestCode.UPDATE_AND_CREATE_TOPIC: - return this.updateAndCreateTopic(ctx, request); - case RequestCode.GET_BROKER_RUNTIME_INFO: - return this.getBrokerRuntimeInfo(ctx, request); - case DeFiBusRequestCode.GET_CONSUME_STATS_V2: - return this.getConsumeStatsV2(ctx, request); - default: - break; - } - - return null; - } - - @Override - public boolean rejectRequest() { - return false; - } - - private RemotingCommand getBrokerRuntimeInfo(ChannelHandlerContext ctx, RemotingCommand request) { - final RemotingCommand response = RemotingCommand.createResponseCommand(null); - - HashMap runtimeInfo = this.prepareRuntimeInfo(); - KVTable kvTable = new KVTable(); - kvTable.setTable(runtimeInfo); - - byte[] body = kvTable.encode(); - response.setBody(body); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - return response; - } - - private HashMap prepareRuntimeInfo() { - HashMap runtimeInfo = this.deFiBrokerController.getMessageStore().getRuntimeInfo(); - runtimeInfo.put("brokerVersionDesc", DeFiBusVersion.getVersionDesc(DeFiBusVersion.CURRENT_VERSION)); - runtimeInfo.put("brokerVersion", String.valueOf(DeFiBusVersion.CURRENT_VERSION)); - - runtimeInfo.put("msgPutTotalYesterdayMorning", - String.valueOf(this.deFiBrokerController.getBrokerStats().getMsgPutTotalYesterdayMorning())); - runtimeInfo.put("msgPutTotalTodayMorning", String.valueOf(this.deFiBrokerController.getBrokerStats().getMsgPutTotalTodayMorning())); - runtimeInfo.put("msgPutTotalTodayNow", String.valueOf(this.deFiBrokerController.getBrokerStats().getMsgPutTotalTodayNow())); - - runtimeInfo.put("msgGetTotalYesterdayMorning", - String.valueOf(this.deFiBrokerController.getBrokerStats().getMsgGetTotalYesterdayMorning())); - runtimeInfo.put("msgGetTotalTodayMorning", String.valueOf(this.deFiBrokerController.getBrokerStats().getMsgGetTotalTodayMorning())); - runtimeInfo.put("msgGetTotalTodayNow", String.valueOf(this.deFiBrokerController.getBrokerStats().getMsgGetTotalTodayNow())); - - runtimeInfo.put("sendThreadPoolQueueSize", String.valueOf(this.deFiBrokerController.getSendThreadPoolQueue().size())); - - runtimeInfo.put("sendThreadPoolQueueCapacity", - String.valueOf(this.deFiBrokerController.getBrokerConfig().getSendThreadPoolQueueCapacity())); - - runtimeInfo.put("pullThreadPoolQueueSize", String.valueOf(this.deFiBrokerController.getPullThreadPoolQueue().size())); - runtimeInfo.put("pullThreadPoolQueueCapacity", - String.valueOf(this.deFiBrokerController.getBrokerConfig().getPullThreadPoolQueueCapacity())); - - runtimeInfo.put("dispatchBehindBytes", String.valueOf(this.deFiBrokerController.getMessageStore().dispatchBehindBytes())); - runtimeInfo.put("pageCacheLockTimeMills", String.valueOf(this.deFiBrokerController.getMessageStore().lockTimeMills())); - - runtimeInfo.put("sendThreadPoolQueueHeadWaitTimeMills", String.valueOf(this.deFiBrokerController.headSlowTimeMills4SendThreadPoolQueue())); - runtimeInfo.put("pullThreadPoolQueueHeadWaitTimeMills", String.valueOf(this.deFiBrokerController.headSlowTimeMills4PullThreadPoolQueue())); - runtimeInfo.put("earliestMessageTimeStamp", String.valueOf(this.deFiBrokerController.getMessageStore().getEarliestMessageTime())); - runtimeInfo.put("startAcceptSendRequestTimeStamp", String.valueOf(this.deFiBrokerController.getBrokerConfig().getStartAcceptSendRequestTimeStamp())); - if (this.deFiBrokerController.getMessageStore() instanceof DefaultMessageStore) { - DefaultMessageStore defaultMessageStore = (DefaultMessageStore) this.deFiBrokerController.getMessageStore(); - runtimeInfo.put("remainTransientStoreBufferNumbs", String.valueOf(defaultMessageStore.remainTransientStoreBufferNumbs())); - if (defaultMessageStore.getMessageStoreConfig().isTransientStorePoolEnable()) { - runtimeInfo.put("remainHowManyDataToCommit", MixAll.humanReadableByteCount(defaultMessageStore.getCommitLog().remainHowManyDataToCommit(), false)); - } - runtimeInfo.put("remainHowManyDataToFlush", MixAll.humanReadableByteCount(defaultMessageStore.getCommitLog().remainHowManyDataToFlush(), false)); - } - - java.io.File commitLogDir = new java.io.File(this.deFiBrokerController.getMessageStoreConfig().getStorePathRootDir()); - if (commitLogDir.exists()) { - runtimeInfo.put("commitLogDirCapacity", String.format("Total : %s, Free : %s.", MixAll.humanReadableByteCount(commitLogDir.getTotalSpace(), false), MixAll.humanReadableByteCount(commitLogDir.getFreeSpace(), false))); - } - -// runtimeInfo.put("producerCount", String.valueOf(this.deFiBrokerController.getProducerManager().getProducerChannelTable().size())); -// runtimeInfo.put("consumerCount", String.valueOf(this.deFiBrokerController.getConsumerManager().getConsumerChannelMap().size())); - - return runtimeInfo; - } - - private RemotingCommand getConsumeStatsV2(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - final RemotingCommand response = RemotingCommand.createResponseCommand(null); - final GetConsumeStatsRequestHeader requestHeader = - (GetConsumeStatsRequestHeader) request.decodeCommandCustomHeader(GetConsumeStatsRequestHeader.class); - - DeFiBusConsumeStats consumeStats = new DeFiBusConsumeStats(); - - Set topics = new HashSet(); - if (UtilAll.isBlank(requestHeader.getTopic())) { - topics = this.deFiBrokerController.getConsumerOffsetManager().whichTopicByConsumer(requestHeader.getConsumerGroup()); - } else { - topics.add(requestHeader.getTopic()); - } - - for (String topic : topics) { - TopicConfig topicConfig = this.deFiBrokerController.getTopicConfigManager().selectTopicConfig(topic); - if (null == topicConfig) { - log.warn("consumeStats, topic config not exist, {}", topic); - continue; - } - - { - SubscriptionData findSubscriptionData = - this.deFiBrokerController.getConsumerManager().findSubscriptionData(requestHeader.getConsumerGroup(), topic); - - if (null == findSubscriptionData // - && this.deFiBrokerController.getConsumerManager().findSubscriptionDataCount(requestHeader.getConsumerGroup()) > 0) { - log.warn("consumeStats, the consumer group[{}], topic[{}] not exist", requestHeader.getConsumerGroup(), topic); - continue; - } - } - - for (int i = 0; i < topicConfig.getReadQueueNums(); i++) { - MessageQueue mq = new MessageQueue(); - mq.setTopic(topic); - mq.setBrokerName(this.deFiBrokerController.getBrokerConfig().getBrokerName()); - mq.setQueueId(i); - - DeFiBusOffsetWrapper offsetWrapper = new DeFiBusOffsetWrapper(); - - long brokerOffset = this.deFiBrokerController.getMessageStore().getMaxOffsetInQueue(topic, i); - if (brokerOffset < 0) - brokerOffset = 0; - - long consumerOffset = this.deFiBrokerController.getConsumerOffsetManager().queryOffset(// - requestHeader.getConsumerGroup(), // - topic, // - i); - if (consumerOffset < 0) - consumerOffset = 0; - - long lastDeliverOffset = this.deFiBrokerController.getConsumeQueueManager().queryDeliverOffset(// - requestHeader.getConsumerGroup(), // - topic, // - i); - if (lastDeliverOffset < consumerOffset) { - lastDeliverOffset = consumerOffset; - this.deFiBrokerController.getConsumeQueueManager().recordLastDeliverOffset(requestHeader.getConsumerGroup(), // - topic, i, consumerOffset); - } - - offsetWrapper.setBrokerOffset(brokerOffset); - offsetWrapper.setConsumerOffset(consumerOffset); - offsetWrapper.setLastDeliverOffset(lastDeliverOffset); - - long timeOffset = consumerOffset - 1; - if (timeOffset >= 0) { - long lastTimestamp = this.deFiBrokerController.getMessageStore().getMessageStoreTimeStamp(topic, i, timeOffset); - if (lastTimestamp > 0) { - offsetWrapper.setLastTimestamp(lastTimestamp); - } - } - - consumeStats.getOffsetTable().put(mq, offsetWrapper); - } - - double consumeTps = this.deFiBrokerController.getBrokerStatsManager().tpsGroupGetNums(requestHeader.getConsumerGroup(), topic); - - consumeTps += consumeStats.getConsumeTps(); - consumeStats.setConsumeTps(consumeTps); - } - - byte[] body = consumeStats.encode(); - response.setBody(body); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - return response; - } - - private RemotingCommand updateAndCreateTopic(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - final RemotingCommand response = RemotingCommand.createResponseCommand(null); - final CreateTopicRequestHeader requestHeader = - (CreateTopicRequestHeader) request.decodeCommandCustomHeader(CreateTopicRequestHeader.class); - log.info("updateAndCreateTopic called by {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - - if (requestHeader.getTopic().equals(this.deFiBrokerController.getBrokerConfig().getBrokerClusterName())) { - String errorMsg = "the topic[" + requestHeader.getTopic() + "] is conflict with system reserved words."; - log.warn(errorMsg); - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark(errorMsg); - return response; - } - - try { - response.setCode(ResponseCode.SUCCESS); - response.setOpaque(request.getOpaque()); - response.markResponseType(); - response.setRemark(null); - ctx.writeAndFlush(response); - } catch (Exception e) { - log.error("Failed to produce a proper response", e); - } - - TopicConfig topicConfig = new TopicConfig(requestHeader.getTopic()); - topicConfig.setReadQueueNums(requestHeader.getReadQueueNums()); - topicConfig.setWriteQueueNums(requestHeader.getWriteQueueNums()); - topicConfig.setTopicFilterType(requestHeader.getTopicFilterTypeEnum()); - topicConfig.setPerm(requestHeader.getPerm()); - topicConfig.setTopicSysFlag(requestHeader.getTopicSysFlag() == null ? 0 : requestHeader.getTopicSysFlag()); - - this.deFiBrokerController.getTopicConfigManager().updateTopicConfig(topicConfig); - - //set topic queue depth - HashMap extFields = request.getExtFields(); - long maxLength = extFields.get("maxQueueDepth") == null ? DeFiBusTopicConfig.DEFAULT_QUEUE_LENGTH : Long.valueOf(extFields.get("maxQueueDepth")); - this.deFiBrokerController.getExtTopicConfigManager().updateTopicConfig( - new DeFiBusTopicConfig(requestHeader.getTopic(), maxLength)); - - if (this.deFiBrokerController.getBrokerConfig().getBrokerId() != MixAll.MASTER_ID) { - return null; - } - - this.deFiBrokerController.registerIncrementBrokerData(topicConfig, this.deFiBrokerController.getTopicConfigManager().getDataVersion()); - - this.deFiBrokerController.getConsumerManager().notifyWhenTopicConfigChange(requestHeader.getTopic()); - - return null; - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiClientManageProcessor.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiClientManageProcessor.java deleted file mode 100644 index 159b46402c..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiClientManageProcessor.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.broker.client.DeFiConsumerGroupInfo; -import cn.webank.defibus.broker.client.DeFiConsumerManager; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.protocol.header.GetConsumerListByGroupAndTopicRequestHeader; -import io.netty.channel.ChannelHandlerContext; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.GetConsumerListByGroupResponseBody; -import org.apache.rocketmq.common.protocol.header.GetConsumerListByGroupResponseHeader; -import org.apache.rocketmq.remoting.common.RemotingHelper; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyRequestProcessor; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiClientManageProcessor implements NettyRequestProcessor { - private final DeFiBrokerController deFiBrokerController; - private static final Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - - public DeFiClientManageProcessor(DeFiBrokerController deFiBrokerController) { - this.deFiBrokerController = deFiBrokerController; - } - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { - switch (request.getCode()) { - case DeFiBusRequestCode.GET_CONSUMER_LIST_BY_GROUP_AND_TOPIC: - return getConsumerListByGroupAndTopic(ctx, request); - default: - break; - } - return null; - } - - private RemotingCommand getConsumerListByGroupAndTopic(ChannelHandlerContext ctx, RemotingCommand request) - throws RemotingCommandException { - final RemotingCommand response = - RemotingCommand.createResponseCommand(GetConsumerListByGroupResponseHeader.class); - final GetConsumerListByGroupAndTopicRequestHeader requestHeader = - (GetConsumerListByGroupAndTopicRequestHeader) request - .decodeCommandCustomHeader(GetConsumerListByGroupAndTopicRequestHeader.class); - DeFiConsumerManager deFiConsumerManager = (DeFiConsumerManager) this.deFiBrokerController.getConsumerManager(); - ConsumerGroupInfo consumerGroupInfo = deFiConsumerManager.getConsumerGroupInfo(requestHeader.getConsumerGroup()); - - if (consumerGroupInfo != null) { - if (consumerGroupInfo instanceof DeFiConsumerGroupInfo) { - DeFiConsumerGroupInfo wqCGInfo = (DeFiConsumerGroupInfo) consumerGroupInfo; - List cidList = new ArrayList<>(); - if (requestHeader.getTopic() != null) { - Set cids = wqCGInfo.getClientIdBySubscription(requestHeader.getTopic()); - if (cids != null) { - cidList.addAll(cids); - } - GetConsumerListByGroupResponseBody body = new GetConsumerListByGroupResponseBody(); - body.setConsumerIdList(cidList); - response.setBody(body.encode()); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - return response; - } - } - - //topic is null or consumerGroupInfo not an instance fo deFiConsumerGroupInfo - List clientIds = consumerGroupInfo.getAllClientId(); - if (!clientIds.isEmpty()) { - GetConsumerListByGroupResponseBody body = new GetConsumerListByGroupResponseBody(); - body.setConsumerIdList(clientIds); - response.setBody(body.encode()); - response.setCode(ResponseCode.SUCCESS); - response.setRemark(null); - return response; - } else { - LOG.warn("getAllClientId failed, {} {}", requestHeader.getConsumerGroup(), - RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - } - } else { - LOG.warn("getConsumerGroupInfo failed, {} {}", requestHeader.getConsumerGroup(), - RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - } - - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("no consumer for this group, " + requestHeader.getConsumerGroup()); - return response; - } - - @Override - public boolean rejectRequest() { - return false; - } -} - diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiPullMessageProcessor.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiPullMessageProcessor.java deleted file mode 100644 index caf77e0fdb..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiPullMessageProcessor.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import io.netty.channel.ChannelHandlerContext; -import org.apache.rocketmq.broker.BrokerController; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.broker.processor.PullMessageProcessor; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.protocol.header.PullMessageRequestHeader; -import org.apache.rocketmq.common.protocol.header.PullMessageResponseHeader; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static org.apache.rocketmq.common.protocol.ResponseCode.NO_PERMISSION; -import static org.apache.rocketmq.common.protocol.ResponseCode.PULL_NOT_FOUND; -import static org.apache.rocketmq.common.protocol.ResponseCode.SUBSCRIPTION_GROUP_NOT_EXIST; -import static org.apache.rocketmq.common.protocol.ResponseCode.SUBSCRIPTION_NOT_EXIST; -import static org.apache.rocketmq.common.protocol.ResponseCode.SUBSCRIPTION_NOT_LATEST; - -public class DeFiPullMessageProcessor extends PullMessageProcessor { - private DeFiBrokerController deFiBrokerController; - private static final Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - - public DeFiPullMessageProcessor(BrokerController brokerController) { - super(brokerController); - this.deFiBrokerController = (DeFiBrokerController) brokerController; - } - - @Override - public RemotingCommand processRequest(final ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - RemotingCommand response = super.processRequest(ctx, request); - - final PullMessageRequestHeader requestHeader = - (PullMessageRequestHeader) request.decodeCommandCustomHeader(PullMessageRequestHeader.class); - ConsumerGroupInfo consumerGroupInfo = deFiBrokerController.getConsumerManager().getConsumerGroupInfo(requestHeader.getConsumerGroup()); - if (consumerGroupInfo != null) { - ClientChannelInfo clientChannelInfo = consumerGroupInfo.getChannelInfoTable().get(ctx.channel()); - if (clientChannelInfo != null) { - String clientId = clientChannelInfo.getClientId(); - deFiBrokerController.getClientRebalanceResultManager().updateListenMap(requestHeader.getConsumerGroup(), requestHeader.getTopic(), requestHeader.getQueueId(), clientId); - } - } - handleProcessResult(requestHeader, response); - return response; - } - - private void handleProcessResult(final PullMessageRequestHeader requestHeader, final RemotingCommand response) { - if (response != null) { - switch (response.getCode()) { - case SUBSCRIPTION_GROUP_NOT_EXIST: - case NO_PERMISSION: - case SUBSCRIPTION_NOT_EXIST: - case SUBSCRIPTION_NOT_LATEST: - response.setCode(PULL_NOT_FOUND); - final PullMessageResponseHeader responseHeader = (PullMessageResponseHeader) response.readCustomHeader(); - responseHeader.setMinOffset(this.deFiBrokerController.getMessageStore().getMinOffsetInQueue(requestHeader.getTopic(), requestHeader.getQueueId())); - responseHeader.setMaxOffset(this.deFiBrokerController.getMessageStore().getMaxOffsetInQueue(requestHeader.getTopic(), requestHeader.getQueueId())); - responseHeader.setNextBeginOffset(requestHeader.getQueueOffset()); - responseHeader.setSuggestWhichBrokerId(MixAll.MASTER_ID); - break; - } - } - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiReplyMessageProcessor.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiReplyMessageProcessor.java deleted file mode 100644 index 189d052de2..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiReplyMessageProcessor.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.broker.plugin.DeFiPluginMessageStore; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.message.DeFiBusMessageConst; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.protocol.header.ReplyMessageRequestHeader; -import io.netty.channel.ChannelHandlerContext; -import java.net.SocketAddress; -import java.util.Map; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.mqtrace.SendMessageContext; -import org.apache.rocketmq.broker.processor.AbstractSendMessageProcessor; -import org.apache.rocketmq.common.MQVersion; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.TopicFilterType; -import org.apache.rocketmq.common.UtilAll; -import org.apache.rocketmq.common.constant.PermName; -import org.apache.rocketmq.common.help.FAQUrl; -import org.apache.rocketmq.common.message.MessageAccessor; -import org.apache.rocketmq.common.message.MessageConst; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeaderV2; -import org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader; -import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig; -import org.apache.rocketmq.common.sysflag.MessageSysFlag; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyRequestProcessor; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.store.DefaultMessageStore; -import org.apache.rocketmq.store.MessageExtBrokerInner; -import org.apache.rocketmq.store.PutMessageResult; -import org.apache.rocketmq.store.config.StorePathConfigHelper; -import org.apache.rocketmq.store.stats.BrokerStatsManager; - -public class DeFiReplyMessageProcessor extends AbstractSendMessageProcessor implements NettyRequestProcessor { - private DeFiBrokerController deFiBrokerController; - - public DeFiReplyMessageProcessor(final DeFiBrokerController deFiBrokerController) { - super(deFiBrokerController); - this.deFiBrokerController = deFiBrokerController; - } - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - SendMessageContext mqtraceContext = null; - switch (request.getCode()) { - case DeFiBusRequestCode.SEND_DIRECT_MESSAGE_V2: - case DeFiBusRequestCode.SEND_DIRECT_MESSAGE: - SendMessageRequestHeader requestHeader = parseRequestHeader(request); - if (requestHeader == null) { - return null; - } - - mqtraceContext = buildMsgContext(ctx, requestHeader); - this.executeSendMessageHookBefore(ctx, request, mqtraceContext); - final RemotingCommand response = this.processReplyMessageRequest(ctx, request, mqtraceContext, requestHeader); - - this.executeSendMessageHookAfter(response, mqtraceContext); - return response; - default: - log.warn("Unsupported request code :" + request.getCode()); - } - return null; - } - - @Override - protected SendMessageRequestHeader parseRequestHeader(RemotingCommand request) throws RemotingCommandException { - SendMessageRequestHeaderV2 requestHeaderV2 = null; - SendMessageRequestHeader requestHeader = null; - switch (request.getCode()) { - case DeFiBusRequestCode.SEND_DIRECT_MESSAGE_V2: - requestHeaderV2 = - (SendMessageRequestHeaderV2) request - .decodeCommandCustomHeader(SendMessageRequestHeaderV2.class); - case DeFiBusRequestCode.SEND_DIRECT_MESSAGE: - if (null == requestHeaderV2) { - requestHeader = - (SendMessageRequestHeader) request - .decodeCommandCustomHeader(SendMessageRequestHeader.class); - } else { - requestHeader = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV1(requestHeaderV2); - } - default: - break; - } - return requestHeader; - } - - @Override - public boolean rejectRequest() { - return this.deFiBrokerController.getMessageStore().isOSPageCacheBusy(); - } - - private RemotingCommand processReplyMessageRequest(final ChannelHandlerContext ctx, // - final RemotingCommand request, // - final SendMessageContext sendMessageContext, // - final SendMessageRequestHeader requestHeader) throws RemotingCommandException { - long arriveBrokerTime = System.currentTimeMillis(); - final RemotingCommand response = RemotingCommand.createResponseCommand(SendMessageResponseHeader.class); - final SendMessageResponseHeader responseHeader = (SendMessageResponseHeader) response.readCustomHeader(); - - response.setOpaque(request.getOpaque()); - - response.addExtField(MessageConst.PROPERTY_MSG_REGION, this.deFiBrokerController.getBrokerConfig().getRegionId()); - - log.debug("receive SendDirectMessage request command, " + request); - - final long startTimestamp = this.deFiBrokerController.getBrokerConfig().getStartAcceptSendRequestTimeStamp(); - if (this.deFiBrokerController.getMessageStore().now() < startTimestamp) { - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark(String.format("broker unable to service, until %s", UtilAll.timeMillisToHumanString2(startTimestamp))); - return response; - } - - response.setCode(-1); - super.msgCheck(ctx, requestHeader, response); - if (response.getCode() != -1) { - return response; - } - - final byte[] body = request.getBody(); - - int queueIdInt = requestHeader.getQueueId(); - TopicConfig topicConfig = this.deFiBrokerController.getTopicConfigManager().selectTopicConfig(requestHeader.getTopic()); - - if (queueIdInt < 0) { - queueIdInt = Math.abs(this.random.nextInt() % 99999999) % topicConfig.getWriteQueueNums(); - } - - int sysFlag = requestHeader.getSysFlag(); - - if (TopicFilterType.MULTI_TAG == topicConfig.getTopicFilterType()) { - sysFlag |= MessageSysFlag.MULTI_TAGS_FLAG; - } - - String newTopic = requestHeader.getTopic(); - if ((null != newTopic && newTopic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX))) { - - String groupName = newTopic.substring(MixAll.RETRY_GROUP_TOPIC_PREFIX.length()); - - SubscriptionGroupConfig subscriptionGroupConfig = - this.deFiBrokerController.getSubscriptionGroupManager().findSubscriptionGroupConfig(groupName); - if (null == subscriptionGroupConfig) { - response.setCode(ResponseCode.SUBSCRIPTION_GROUP_NOT_EXIST); - response.setRemark( - "subscription group not exist, " + groupName + " " + FAQUrl.suggestTodo(FAQUrl.SUBSCRIPTION_GROUP_NOT_EXIST)); - return response; - } - - int maxReconsumeTimes = subscriptionGroupConfig.getRetryMaxTimes(); - if (request.getVersion() >= MQVersion.Version.V3_4_9.ordinal()) { - maxReconsumeTimes = requestHeader.getMaxReconsumeTimes(); - } - int reconsumeTimes = requestHeader.getReconsumeTimes(); - if (reconsumeTimes >= maxReconsumeTimes) { - newTopic = MixAll.getDLQTopic(groupName); - queueIdInt = Math.abs(this.random.nextInt() % 99999999) % DLQ_NUMS_PER_GROUP; - topicConfig = this.deFiBrokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(newTopic, // - DLQ_NUMS_PER_GROUP, // - PermName.PERM_WRITE, 0 - ); - if (null == topicConfig) { - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("topic[" + newTopic + "] not exist"); - return response; - } - } - } - MessageExtBrokerInner msgInner = new MessageExtBrokerInner(); - msgInner.setTopic(newTopic); - msgInner.setBody(body); - msgInner.setFlag(requestHeader.getFlag()); - MessageAccessor.setProperties(msgInner, MessageDecoder.string2messageProperties(requestHeader.getProperties())); - msgInner.setPropertiesString(requestHeader.getProperties()); - msgInner.setTagsCode(MessageExtBrokerInner.tagsString2tagsCode(topicConfig.getTopicFilterType(), msgInner.getTags())); - - msgInner.setQueueId(queueIdInt); - msgInner.setSysFlag(sysFlag); - msgInner.setBornTimestamp(requestHeader.getBornTimestamp()); - msgInner.setBornHost(ctx.channel().remoteAddress()); - msgInner.setStoreHost(this.getStoreHost()); - msgInner.setReconsumeTimes(requestHeader.getReconsumeTimes() == null ? 0 : requestHeader.getReconsumeTimes()); - - if (this.deFiBrokerController.getBrokerConfig().isRejectTransactionMessage()) { - String traFlag = msgInner.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED); - if (traFlag != null) { - response.setCode(ResponseCode.NO_PERMISSION); - response.setRemark( - "the broker[" + this.deFiBrokerController.getBrokerConfig().getBrokerIP1() + "] sending transaction constant is forbidden"); - return response; - } - } - - ReplyMessageRequestHeader replyMessageRequestHeader = new ReplyMessageRequestHeader(); - replyMessageRequestHeader.setBornHost(ctx.channel().remoteAddress().toString()); - replyMessageRequestHeader.setStoreHost(this.getStoreHost().toString()); - replyMessageRequestHeader.setStoreTimestamp(arriveBrokerTime); - - replyMessageRequestHeader.setProducerGroup(requestHeader.getProducerGroup()); - replyMessageRequestHeader.setTopic(requestHeader.getTopic()); - replyMessageRequestHeader.setDefaultTopic(requestHeader.getDefaultTopic()); - replyMessageRequestHeader.setDefaultTopicQueueNums(requestHeader.getDefaultTopicQueueNums()); - replyMessageRequestHeader.setQueueId(requestHeader.getQueueId()); - replyMessageRequestHeader.setSysFlag(requestHeader.getSysFlag()); - replyMessageRequestHeader.setBornTimestamp(requestHeader.getBornTimestamp()); - replyMessageRequestHeader.setFlag(requestHeader.getFlag()); - replyMessageRequestHeader.setProperties(requestHeader.getProperties()); - replyMessageRequestHeader.setReconsumeTimes(requestHeader.getReconsumeTimes()); - replyMessageRequestHeader.setUnitMode(requestHeader.isUnitMode()); - - if (msgInner.getProperties() != null && DeFiBusConstant.REPLY.equals(msgInner.getProperties().get(DeFiBusConstant.KEY))) { - String senderId = msgInner.getProperties().get(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO); - if (senderId == null) { - log.warn("senderId is null, can not reply message"); - } else { - ClientChannelInfo clientChannelInfo = this.deFiBrokerController.getProducerManager().getClientChannel(senderId); - if (clientChannelInfo == null || clientChannelInfo.getChannel() == null || !clientChannelInfo.getChannel().isActive()) { - - if (System.currentTimeMillis() - replyMessageRequestHeader.getBornTimestamp() <= 1000) { - log.warn("try to push rr reply message:{} later for clientId:{}", msgInner, senderId); - processRequestLater(ctx, request); - return null; - } else { - log.warn("ignore rr reply message:{} after retry, no channel for this client:{}", msgInner, senderId); - } - - } else { - Map map = MessageDecoder.string2messageProperties(replyMessageRequestHeader.getProperties()); - map.put(DeFiBusMessageConst.LEAVE_TIME, String.valueOf(System.currentTimeMillis())); - replyMessageRequestHeader.setProperties(MessageDecoder.messageProperties2String(map)); - - try { - this.deFiBrokerController.getPushReplyMessageExecutor().submit(new Runnable() { - @Override public void run() { - boolean isPushSuccess = deFiBrokerController.getDeFiBusBroker2Client().pushRRReplyMessageToClient - (clientChannelInfo.getChannel(), replyMessageRequestHeader, msgInner); - if (isPushSuccess) { - deFiBrokerController.getBrokerStatsManager().incBrokerGetNums(1); - if (deFiBrokerController.getMessageStore() instanceof DeFiPluginMessageStore) { - DefaultMessageStore defaultMessageStore = (DefaultMessageStore) - ((DeFiPluginMessageStore) deFiBrokerController.getMessageStore()).getDefaultMessageStore(); - defaultMessageStore.getStoreStatsService().getGetMessageTransferedMsgCount().incrementAndGet(); - defaultMessageStore.getStoreStatsService().getSinglePutMessageTopicTimesTotal(requestHeader.getTopic()).incrementAndGet(); - } - } else { - log.warn("push reply msg to client failed. [{}]", msgInner); - } - } - }); - } catch (RejectedExecutionException e) { - log.warn("too many push rr rely requests, and system thread pool busy"); - } - } - } - } - - PutMessageResult putMessageResult = this.deFiBrokerController.getMessageStore().putMessage(msgInner); - - if (putMessageResult != null) { - boolean sendOK = true; - response.setCode(ResponseCode.SUCCESS); - - switch (putMessageResult.getPutMessageStatus()) { - case PUT_OK: - sendOK = true; - response.setCode(ResponseCode.SUCCESS); - break; - case FLUSH_DISK_TIMEOUT: - response.setCode(ResponseCode.FLUSH_DISK_TIMEOUT); - sendOK = true; - break; - case FLUSH_SLAVE_TIMEOUT: - response.setCode(ResponseCode.FLUSH_SLAVE_TIMEOUT); - sendOK = true; - break; - case SLAVE_NOT_AVAILABLE: - response.setCode(ResponseCode.SLAVE_NOT_AVAILABLE); - sendOK = true; - break; - - case CREATE_MAPEDFILE_FAILED: - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("create mapped file failed, server is busy or broken."); - break; - case MESSAGE_ILLEGAL: - case PROPERTIES_SIZE_EXCEEDED: - response.setCode(ResponseCode.MESSAGE_ILLEGAL); - response.setRemark( - "the message is illegal, maybe msg body or properties length not matched. msg body length limit 128k, msg properties length limit 32k."); - break; - case SERVICE_NOT_AVAILABLE: - response.setCode(ResponseCode.SERVICE_NOT_AVAILABLE); - response.setRemark( - "service not available now, maybe disk full, " + diskUtil() + ", maybe your broker machine memory too small."); - break; - case OS_PAGECACHE_BUSY: - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("[PC_SYNCHRONIZED]broker busy, start flow control for a while"); - break; - case UNKNOWN_ERROR: - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("UNKNOWN_ERROR"); - break; - - default: - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("UNKNOWN_ERROR DEFAULT"); - break; - } - - String owner = request.getExtFields().get(BrokerStatsManager.COMMERCIAL_OWNER); - if (sendOK) { - - this.deFiBrokerController.getBrokerStatsManager().incTopicPutNums(msgInner.getTopic()); - this.deFiBrokerController.getBrokerStatsManager().incTopicPutSize(msgInner.getTopic(), - putMessageResult.getAppendMessageResult().getWroteBytes()); - this.deFiBrokerController.getBrokerStatsManager().incBrokerPutNums(); - - response.setRemark(null); - - responseHeader.setMsgId(putMessageResult.getAppendMessageResult().getMsgId()); - responseHeader.setQueueId(queueIdInt); - responseHeader.setQueueOffset(putMessageResult.getAppendMessageResult().getLogicsOffset()); - - doResponse(ctx, request, response); - - if (hasSendMessageHook()) { - sendMessageContext.setMsgId(responseHeader.getMsgId()); - sendMessageContext.setQueueId(responseHeader.getQueueId()); - sendMessageContext.setQueueOffset(responseHeader.getQueueOffset()); - - int commercialBaseCount = deFiBrokerController.getBrokerConfig().getCommercialBaseCount(); - int wroteSize = putMessageResult.getAppendMessageResult().getWroteBytes(); - int incValue = (int) Math.ceil(wroteSize / BrokerStatsManager.SIZE_PER_COUNT) * commercialBaseCount; - - sendMessageContext.setCommercialSendStats(BrokerStatsManager.StatsType.SEND_SUCCESS); - sendMessageContext.setCommercialSendTimes(incValue); - sendMessageContext.setCommercialSendSize(wroteSize); - sendMessageContext.setCommercialOwner(owner); - } - return null; - } else { - if (hasSendMessageHook()) { - int wroteSize = request.getBody().length; - int incValue = (int) Math.ceil(wroteSize / BrokerStatsManager.SIZE_PER_COUNT); - - sendMessageContext.setCommercialSendStats(BrokerStatsManager.StatsType.SEND_FAILURE); - sendMessageContext.setCommercialSendTimes(incValue); - sendMessageContext.setCommercialSendSize(wroteSize); - sendMessageContext.setCommercialOwner(owner); - } - } - } else { - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("store putMessage return null"); - } - - return response; - } - - public SocketAddress getStoreHost() { - return storeHost; - } - - private String diskUtil() { - String storePathPhysic = this.deFiBrokerController.getMessageStoreConfig().getStorePathCommitLog(); - double physicRatio = UtilAll.getDiskPartitionSpaceUsedPercent(storePathPhysic); - - String storePathLogis = - StorePathConfigHelper.getStorePathConsumeQueue(this.deFiBrokerController.getMessageStoreConfig().getStorePathRootDir()); - double logisRatio = UtilAll.getDiskPartitionSpaceUsedPercent(storePathLogis); - - String storePathIndex = - StorePathConfigHelper.getStorePathIndex(this.deFiBrokerController.getMessageStoreConfig().getStorePathRootDir()); - double indexRatio = UtilAll.getDiskPartitionSpaceUsedPercent(storePathIndex); - - return String.format("CL: %5.2f CQ: %5.2f INDEX: %5.2f", physicRatio, logisRatio, indexRatio); - } - - public void processRequestLater(ChannelHandlerContext ctx, RemotingCommand request) { - ScheduledThreadPoolExecutor threadPoolExecutor = this.deFiBrokerController.getSendReplyScheduledExecutorService(); - if (threadPoolExecutor.getQueue().size() > this.deFiBrokerController.getDeFiBusBrokerConfig().getSendReplyThreadPoolQueueCapacity()) { - log.warn("Task rejected from ScheduledThreadPoolExecutor when try to push rr reply message again"); - return; - } - - //submit to threadpool 2 times to push the request per 100 ms - this.deFiBrokerController.getSendReplyScheduledExecutorService().schedule(new Runnable() { - @Override - public void run() { - deFiBrokerController.getSendReplyMessageExecutor().submit(new Runnable() { - @Override - public void run() { - try { - DeFiReplyMessageProcessor.this.processRequest(ctx, request); - } catch (Throwable e) { - log.warn("failed to processRequest", e); - } - } - }); - } - }, 100, TimeUnit.MILLISECONDS); - - } - -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiSendMessageProcessor.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiSendMessageProcessor.java deleted file mode 100644 index 71392775fe..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/processor/DeFiSendMessageProcessor.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.broker.client.DeFiProducerManager; -import cn.webank.defibus.broker.consumequeue.ConsumeQueueManager; -import cn.webank.defibus.broker.consumequeue.ConsumeQueueWaterMark; -import cn.webank.defibus.broker.consumequeue.MessageRedirectManager; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.protocol.DeFiBusResponseCode; -import io.netty.channel.ChannelHandlerContext; -import java.util.Map; -import org.apache.rocketmq.broker.BrokerController; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.processor.SendMessageProcessor; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.constant.LoggerName; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader; -import org.apache.rocketmq.remoting.common.RemotingUtil; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiSendMessageProcessor extends SendMessageProcessor { - private final static Logger LOG = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - private ConsumeQueueManager deFiQueueManager = ConsumeQueueManager.onlyInstance(); - - public DeFiSendMessageProcessor(BrokerController brokerController) { - super(brokerController); - } - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - SendMessageRequestHeader requestHeader = parseRequestHeader(request); - String Topic = requestHeader.getTopic(); - int queueIdInt = requestHeader.getQueueId(); - if (deFiQueueManager.getBrokerController().getDeFiBusBrokerConfig().isRejectSendWhenMaxDepth() - && Topic != null - && !Topic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX) - && !Topic.startsWith(MixAll.DLQ_GROUP_TOPIC_PREFIX) - && !Topic.contains(DeFiBusConstant.RR_REPLY_TOPIC) - && !Topic.startsWith(DeFiBusConstant.RMQ_SYS)) { - long maxQueueDepth = deFiQueueManager.getMaxQueueDepth(Topic); - double highWatermark = deFiQueueManager.getBrokerController().getDeFiBusBrokerConfig().getQueueDepthHighWatermark(); - ConsumeQueueWaterMark minConsumeQueueWaterMark - = deFiQueueManager.getMinAccumulated(Topic, queueIdInt); - if (minConsumeQueueWaterMark != null) { - long accumulate = minConsumeQueueWaterMark.getAccumulated(); - if (accumulate >= maxQueueDepth) { - if (System.currentTimeMillis() % 100 == 0) { - LOG.error("Quota exceed 100% for topic [{}] in queue [{}], current:[{}], max:[{}]", Topic, queueIdInt, accumulate, maxQueueDepth); - } - final RemotingCommand response = RemotingCommand.createResponseCommand(SendMessageResponseHeader.class); - response.setCode(DeFiBusResponseCode.CONSUME_DIFF_SPAN_TOO_LONG); - response.setRemark(" consume span too long, maybe has slow consumer, so send rejected"); - return response; - } else if (accumulate >= maxQueueDepth * highWatermark) { - if (System.currentTimeMillis() % 100 == 0) { - LOG.error("Quota exceed {}% for topic [{}] in queue [{}], current:[{}], max:[{}]", highWatermark * 100, Topic, queueIdInt, accumulate, maxQueueDepth); - } - } - } - } - if (RequestCode.SEND_MESSAGE_V2 == request.getCode() || RequestCode.SEND_MESSAGE == request.getCode()) { - Map properties = MessageDecoder.string2messageProperties(requestHeader.getProperties()); - DeFiProducerManager deFiProducerManager = (DeFiProducerManager) this.brokerController.getProducerManager(); - String sendId = properties.get(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO); - - if (sendId != null && deFiProducerManager.getClientChannel(sendId) == null) { - ClientChannelInfo clientChannelInfo = new ClientChannelInfo(ctx.channel(), sendId, request.getLanguage(), request.getVersion()); - deFiProducerManager.registerProducer(requestHeader.getProducerGroup(), clientChannelInfo); - } - } - - if (((DeFiBrokerController) brokerController).getDeFiBusBrokerConfig().isRedirectMessageEnable()) { - switch (request.getCode()) { - case RequestCode.CONSUMER_SEND_MSG_BACK: - break; - default: - Map properties = MessageDecoder.string2messageProperties(requestHeader.getProperties()); - String redirectFlag = properties.get(DeFiBusConstant.REDIRECT_FLAG); - //redirect message - MessageRedirectManager.RedirectResult redirectResult = ((DeFiBrokerController) brokerController).getMessageRedirectManager() - .redirectMessageToWhichQueue(requestHeader, redirectFlag); - switch (redirectResult.getStates()) { - case REDIRECT_OK: - log.debug("redirect message from queueId({}) to queueId({}), {}", requestHeader.getQueueId(), redirectResult.getRedirectQueueId(), requestHeader.getTopic()); - changeQueueIdInRequest(request, redirectResult.getRedirectQueueId()); - properties.put(DeFiBusConstant.REDIRECT, "true"); - updateProperties(request, MessageDecoder.messageProperties2String(properties)); - break; - case NO_REDIRECT_CONFIG: - properties.put(DeFiBusConstant.REDIRECT, "false"); - updateProperties(request, MessageDecoder.messageProperties2String(properties)); - break; - case NO_INSTANCE_FOUND: - RemotingCommand response = RemotingCommand.createResponseCommand(SendMessageResponseHeader.class); - response.setCode(ResponseCode.SYSTEM_ERROR); - response.setRemark("Redirect instance no found for [" + requestHeader.getTopic() + "] in [" - + RemotingUtil.socketAddress2String(getStoreHost()) + "] redirect flag: " + redirectFlag); - return response; - } - } - } - return super.processRequest(ctx, request); - } - - private void changeQueueIdInRequest(final RemotingCommand request, int queueId) { - switch (request.getCode()) { - case RequestCode.SEND_BATCH_MESSAGE: - case RequestCode.SEND_MESSAGE_V2: - request.getExtFields().put("e", String.valueOf(queueId)); - case RequestCode.SEND_MESSAGE: - request.getExtFields().put("queueId", String.valueOf(queueId)); - default: - break; - } - } - - private void updateProperties(final RemotingCommand request, String properties) { - switch (request.getCode()) { - case RequestCode.SEND_BATCH_MESSAGE: - case RequestCode.SEND_MESSAGE_V2: - request.getExtFields().put("i", properties); - case RequestCode.SEND_MESSAGE: - request.getExtFields().put("properties", properties); - default: - break; - } - } -} diff --git a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/topic/DeFiTopicConfigManager.java b/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/topic/DeFiTopicConfigManager.java deleted file mode 100644 index b895cbd8fd..0000000000 --- a/eventmesh-store/defibus-broker/src/main/java/cn/webank/defibus/broker/topic/DeFiTopicConfigManager.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package cn.webank.defibus.broker.topic; - -import cn.webank.defibus.common.protocol.DeFiBusTopicConfig; -import cn.webank.defibus.common.protocol.body.DeFiBusTopicConfigSerializeWrapper; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.rocketmq.broker.BrokerController; -import org.apache.rocketmq.broker.BrokerPathConfigHelper; -import org.apache.rocketmq.common.ConfigManager; -import org.apache.rocketmq.common.DataVersion; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.constant.LoggerName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiTopicConfigManager extends ConfigManager { - private static final Logger log = LoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); - - private final ConcurrentHashMap extTopicConfigTable = - new ConcurrentHashMap(1024); - private final DataVersion dataVersion = new DataVersion(); - private final Set systemTopicList = new HashSet(); - private transient BrokerController brokerController; - - public DeFiTopicConfigManager() { - } - - public DeFiTopicConfigManager(BrokerController brokerController) { - this.brokerController = brokerController; - { - // MixAll.SELF_TEST_TOPIC - String topic = MixAll.SELF_TEST_TOPIC; - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(topic); - this.systemTopicList.add(topic); - this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - } - - { - // MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC - if (this.brokerController.getBrokerConfig().isAutoCreateTopicEnable()) { - String topic = MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC; - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(topic); - this.systemTopicList.add(topic); - this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - } - } - { - // MixAll.BENCHMARK_TOPIC - String topic = MixAll.BENCHMARK_TOPIC; - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(topic); - this.systemTopicList.add(topic); - this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - } - { - - String topic = this.brokerController.getBrokerConfig().getBrokerClusterName(); - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(topic); - this.systemTopicList.add(topic); - this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - } - { - - String topic = this.brokerController.getBrokerConfig().getBrokerName(); - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(topic); - this.systemTopicList.add(topic); - this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - } - { - // MixAll.OFFSET_MOVED_EVENT - String topic = MixAll.OFFSET_MOVED_EVENT; - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(topic); - this.systemTopicList.add(topic); - this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - } - { - String rr_reply_topic = this.brokerController.getBrokerConfig().getBrokerClusterName() + "-rr-reply-topic"; - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(rr_reply_topic); - this.systemTopicList.add(rr_reply_topic); - this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - } - } - - public boolean isSystemTopic(final String topic) { - return this.systemTopicList.contains(topic); - } - - public Set getSystemTopic() { - return this.systemTopicList; - } - - public boolean isTopicCanSendMessage(final String topic) { - return !topic.equals(MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC); - } - - public void updateTopicConfig(final DeFiBusTopicConfig deFiBusTopicConfig) { - DeFiBusTopicConfig old = this.extTopicConfigTable.put(deFiBusTopicConfig.getTopicName(), deFiBusTopicConfig); - if (old != null) { - log.info("update ext topic config, old: " + old + " new: " + deFiBusTopicConfig); - } else { - log.info("create new ext topic, " + deFiBusTopicConfig); - } - - this.dataVersion.nextVersion(); - - this.persist(); - } - - public DeFiBusTopicConfig selectExtTopicConfig(final String topic) { - if (this.brokerController.getTopicConfigManager().selectTopicConfig(topic) == null) { - this.extTopicConfigTable.remove(topic); - this.persist(); - return null; - } - - //This scenario may exists in auto-create topics - if (this.extTopicConfigTable.get(topic) == null) { - extTopicConfigTable.put(topic, new DeFiBusTopicConfig(topic)); - this.persist(); - } - - return this.extTopicConfigTable.get(topic); - } - - public void deleteExtTopicConfig(final String topic) { - DeFiBusTopicConfig old = this.extTopicConfigTable.remove(topic); - if (old != null) { - log.info("delete topic config OK, topic: " + old); - this.dataVersion.nextVersion(); - this.persist(); - } else { - log.warn("delete topic config failed, topic: " + topic + " not exist"); - } - } - - public DeFiBusTopicConfigSerializeWrapper buildExtTopicConfigSerializeWrapper() { - DeFiBusTopicConfigSerializeWrapper ExtTopicConfigSerializeWrapper = new DeFiBusTopicConfigSerializeWrapper(); - ExtTopicConfigSerializeWrapper.setExtTopicConfigTable(this.extTopicConfigTable); - ExtTopicConfigSerializeWrapper.setDataVersion(this.dataVersion); - return ExtTopicConfigSerializeWrapper; - } - - @Override - public String encode() { - return encode(false); - } - - @Override - public String configFilePath() { - String configPath = BrokerPathConfigHelper.getTopicConfigPath(this.brokerController.getMessageStoreConfig() - .getStorePathRootDir()); - - return configPath.replaceAll("topics.json", "topicsExt.json"); - } - - @Override - public void decode(String jsonString) { - if (jsonString != null) { - DeFiBusTopicConfigSerializeWrapper extTopicConfigSerializeWrapper = - DeFiBusTopicConfigSerializeWrapper.fromJson(jsonString, DeFiBusTopicConfigSerializeWrapper.class); - if (extTopicConfigSerializeWrapper != null) { - this.extTopicConfigTable.putAll(extTopicConfigSerializeWrapper.getExtTopicConfigTable()); - this.dataVersion.assignNewOne(extTopicConfigSerializeWrapper.getDataVersion()); - this.printLoadDataWhenFirstBoot(extTopicConfigSerializeWrapper); - } - } - } - - public String encode(final boolean prettyFormat) { - //check consistency of TopicConfigManager and DeFiTopicConfigManager - boolean isChanged = false; - for (Map.Entry entry : this.brokerController.getTopicConfigManager().getTopicConfigTable().entrySet()) { - String topic = entry.getKey(); - if (this.extTopicConfigTable.get(topic) == null) { - this.extTopicConfigTable.put(topic, new DeFiBusTopicConfig(topic)); - isChanged = true; - } - } - if (isChanged) { - log.info("topicConfigManager is not consistent with extTopicConfigManager, auto fix it when encode"); - this.persist(); - } - - DeFiBusTopicConfigSerializeWrapper ExtTopicConfigSerializeWrapper = new DeFiBusTopicConfigSerializeWrapper(); - ExtTopicConfigSerializeWrapper.setExtTopicConfigTable(this.extTopicConfigTable); - ExtTopicConfigSerializeWrapper.setDataVersion(this.dataVersion); - return ExtTopicConfigSerializeWrapper.toJson(prettyFormat); - } - - private void printLoadDataWhenFirstBoot(final DeFiBusTopicConfigSerializeWrapper tcs) { - Iterator> it = tcs.getExtTopicConfigTable().entrySet().iterator(); - while (it.hasNext()) { - Entry next = it.next(); - log.info("load exist local topic, {}", next.getValue().toString()); - } - } - - public DataVersion getDataVersion() { - return dataVersion; - } - - public void clear() { - this.extTopicConfigTable.clear(); - } - - public void addAll(ConcurrentHashMap table) { - this.extTopicConfigTable.putAll(table); - } -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/BrokerFuseTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/BrokerFuseTest.java deleted file mode 100644 index 20d2d9c450..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/BrokerFuseTest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker; - -import cn.webank.defibus.broker.client.DeFiConsumerGroupInfo; -import cn.webank.defibus.broker.consumequeue.ConsumeQueueManager; -import cn.webank.defibus.broker.consumequeue.ConsumeQueueWaterMark; -import cn.webank.defibus.broker.processor.DeFiSendMessageProcessor; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.protocol.DeFiBusResponseCode; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.InetSocketAddress; -import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.broker.client.ConsumerManager; -import org.apache.rocketmq.broker.offset.ConsumerOffsetManager; -import org.apache.rocketmq.broker.topic.TopicConfigManager; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import static org.mockito.Matchers.anyLong; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(PowerMockRunner.class) -@PrepareForTest(ConsumeQueueManager.class) -public class BrokerFuseTest { - private DeFiSendMessageProcessor deFiSendMessageProcessor; - @Spy - private DeFiBrokerController brokerController = new DeFiBrokerController( - new BrokerConfig(), - new NettyServerConfig(), - new NettyClientConfig(), - new MessageStoreConfig(), - new DeFiBusBrokerConfig() - ); - - @Mock - private MessageStore messageStore; - @Mock - private ChannelHandlerContext handlerContext; - @Mock - private ConsumeQueueManager deFiQueueManager; - @Mock - private TopicConfigManager topicConfigManager; - - private String topic = "FooBar"; - private String producerGroup = "FooBarGroup"; - private String consumeGroup = "ConGroup"; - private int queueId = 1; - - @Before - public void init() { - brokerController.setMessageStore(messageStore); - when(messageStore.now()).thenReturn(System.currentTimeMillis()); - Channel mockChannel = mock(Channel.class); - when(mockChannel.remoteAddress()).thenReturn(new InetSocketAddress(1024)); - when(handlerContext.channel()).thenReturn(mockChannel); - when(messageStore.lookMessageByOffset(anyLong())).thenReturn(new MessageExt()); - } - - @Test - public void testProcessRequestFuse() throws Exception { - //fuse condition - ConsumeQueueWaterMark minWaterMark = new ConsumeQueueWaterMark(consumeGroup, topic, 1, 1000, 800); - PowerMockito.mockStatic(ConsumeQueueManager.class); - when(ConsumeQueueManager.onlyInstance()).thenReturn(deFiQueueManager); - when(deFiQueueManager.getMaxQueueDepth(topic)).thenReturn((long) 500); - when(deFiQueueManager.getMinAccumulated(topic, queueId)).thenReturn(minWaterMark); - when(deFiQueueManager.getBrokerController()).thenReturn(brokerController); - deFiSendMessageProcessor = new DeFiSendMessageProcessor(brokerController); - - //send message request - final RemotingCommand request = createSendMsgCommand(RequestCode.SEND_MESSAGE); - RemotingCommand response = deFiSendMessageProcessor.processRequest(handlerContext, request); - Assert.assertEquals(response.getCode(), DeFiBusResponseCode.CONSUME_DIFF_SPAN_TOO_LONG); - } - - @Test - public void testAutoUpdateDepth() throws Exception { - ConcurrentHashMap consumerTable = - new ConcurrentHashMap(1024); - DeFiConsumerGroupInfo deFiConsumerGroupInfo = - new DeFiConsumerGroupInfo(consumeGroup, - ConsumeType.CONSUME_ACTIVELY, - MessageModel.CLUSTERING, - ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); - consumerTable.put(consumeGroup, deFiConsumerGroupInfo); - SubscriptionData subscriptionData = new SubscriptionData(topic, "test"); - HashSet hashSet = new HashSet<>(); - hashSet.add(subscriptionData); - deFiConsumerGroupInfo.registerClientId(hashSet, "123"); - ConsumeQueueManager consumeQueueManager = ConsumeQueueManager.onlyInstance(); - consumeQueueManager.setBrokerController(brokerController); - ConsumerManager consumerManager = brokerController.getConsumerManager(); - ConsumerOffsetManager consumerOffsetManager = brokerController.getConsumerOffsetManager(); - consumerOffsetManager.commitOffset("resetByBroker", consumeGroup, topic, queueId, 100); - TopicConfig topicConfig = new TopicConfig(topic, 4, 4, 6); - - Assert.assertEquals(consumerOffsetManager.queryOffset(consumeGroup, topic, queueId), 100); - when(brokerController.getTopicConfigManager()).thenReturn(topicConfigManager); - when(topicConfigManager.selectTopicConfig(topic)).thenReturn(topicConfig); - - Field field = ConsumerManager.class.getDeclaredField("consumerTable"); - field.setAccessible(true); - field.set(consumerManager, consumerTable); - - Method method = ConsumeQueueManager.class.getDeclaredMethod("autoUpdateDepth", String.class, String.class, int.class, long.class, long.class); - method.setAccessible(true); - method.invoke(consumeQueueManager, consumeGroup, topic, queueId, 500, 1500); - Assert.assertEquals(consumerOffsetManager.queryOffset(consumeGroup, topic, queueId), 1500 - 500 * 0.65, 0); - - } - - private RemotingCommand createSendMsgCommand(int requestCode) { - SendMessageRequestHeader requestHeader = createSendMsgRequestHeader(); - - RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader); - request.setBody(new byte[] {'a'}); - request.makeCustomHeaderToNet(); - return request; - } - - private SendMessageRequestHeader createSendMsgRequestHeader() { - SendMessageRequestHeader requestHeader = new SendMessageRequestHeader(); - requestHeader.setProducerGroup(producerGroup); - requestHeader.setTopic(topic); - requestHeader.setDefaultTopic(MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC); - requestHeader.setDefaultTopicQueueNums(3); - requestHeader.setQueueId(queueId); - requestHeader.setSysFlag(0); - requestHeader.setBornTimestamp(System.currentTimeMillis()); - requestHeader.setFlag(124); - requestHeader.setReconsumeTimes(0); - return requestHeader; - } -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/DeFiBrokerControllerTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/DeFiBrokerControllerTest.java deleted file mode 100644 index e0c436cd6e..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/DeFiBrokerControllerTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker; - -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import java.io.File; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.UtilAll; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.After; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DeFiBrokerControllerTest { - @Test - public void testBrokerRestart() throws Exception { - DeFiBrokerController brokerController = new DeFiBrokerController( - new BrokerConfig(), - new NettyServerConfig(), - new NettyClientConfig(), - new MessageStoreConfig(), - new DeFiBusBrokerConfig()); - assertThat(brokerController.initialize()); - brokerController.start(); - brokerController.shutdown(); - } - - @After - public void destroy() { - UtilAll.deleteFile(new File(new MessageStoreConfig().getStorePathRootDir())); - } -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/DeFiBusBrokerStartupTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/DeFiBusBrokerStartupTest.java deleted file mode 100644 index f67ea674f6..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/DeFiBusBrokerStartupTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; - -public class DeFiBusBrokerStartupTest { - - private String storePathRootDir = "."; - - @Test - public void testProperties2SystemEnv() throws NoSuchMethodException, InvocationTargetException, - IllegalAccessException { - Properties properties = new Properties(); - Class clazz = DeFiBusBrokerStartup.class; - Method method = clazz.getDeclaredMethod("parsePropertie2SystemEnv", Properties.class); - method.setAccessible(true); - System.setProperty("rocketmq.namesrv.domain", "jmenv.tbsite.net"); - method.invoke(null, properties); - Assert.assertEquals("jmenv.tbsite.net", System.getProperty("rocketmq.namesrv.domain")); - } -} \ No newline at end of file diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/AdjustQueueNumStrategyTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/AdjustQueueNumStrategyTest.java deleted file mode 100644 index 09cd0c7d48..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/AdjustQueueNumStrategyTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package cn.webank.defibus.broker.client; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class AdjustQueueNumStrategyTest { - - private String topic = "AdjustQueue"; - private AdjustQueueNumStrategy adjustQueueNumStrategy; - @Spy - private DeFiBrokerController deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), new DeFiBusBrokerConfig()); - @Mock - private MessageStore messageStore; - - @Before - public void init() { - deFiBrokerController.setMessageStore(messageStore); - adjustQueueNumStrategy = new AdjustQueueNumStrategy(deFiBrokerController); - } - - @Test - public void testIsCanAdjustReadQueueSizeByFalse() { - deFiBrokerController.getTopicConfigManager().updateTopicConfig(createTopic()); - when(messageStore.getMaxOffsetInQueue(anyString(), anyInt())).thenReturn(1000L); - when(messageStore.getMessageStoreTimeStamp(anyString(), anyInt(), anyLong())).thenReturn(System.currentTimeMillis()); - boolean flag = adjustQueueNumStrategy.isCanAdjustReadQueueSize(topic, 3); - assertThat(flag).isFalse(); - } - - @Test - public void testIsCanAdjustReadQueueSizeByTrue() { - deFiBrokerController.getTopicConfigManager().updateTopicConfig(createTopic()); - boolean flag = adjustQueueNumStrategy.isCanAdjustReadQueueSize(topic, 4); - assertThat(flag).isTrue(); - } - - private TopicConfig createTopic() { - TopicConfig topicConfig = new TopicConfig(); - topicConfig.setTopicName(topic); - topicConfig.setWriteQueueNums(4); - topicConfig.setReadQueueNums(4); - return topicConfig; - } - -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/DeFiConsumerManagerTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/DeFiConsumerManagerTest.java deleted file mode 100644 index ac5164abb0..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/DeFiConsumerManagerTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.client; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.util.ReflectUtil; -import io.netty.channel.Channel; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; -import org.apache.rocketmq.broker.BrokerController; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ConsumerIdsChangeListener; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumerData; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.LanguageCode; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Spy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class DeFiConsumerManagerTest { - @Spy - private DeFiBrokerController deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), new DeFiBusBrokerConfig()); - private DeFiConsumerManager deFiConsumerManager; - ConsumerIdsChangeListener consumerIdsChangeListener = (ConsumerIdsChangeListener) ReflectUtil.getSimpleProperty(BrokerController.class, deFiBrokerController, "consumerIdsChangeListener"); - private AdjustQueueNumStrategy adjustQueueNumStrategy = new AdjustQueueNumStrategy(deFiBrokerController); - private String topic = "FooBar"; - private String group = "FooBarGroup"; - private ClientChannelInfo clientChannelInfo; - private String clientId = UUID.randomUUID().toString(); - private ConsumerData consumerData; - private Channel mockChannel; - - @Before - public void init() { - deFiConsumerManager = new DeFiConsumerManager(consumerIdsChangeListener, adjustQueueNumStrategy); - mockChannel = mock(Channel.class); - clientChannelInfo = new ClientChannelInfo(mockChannel, clientId, LanguageCode.JAVA, 100); - consumerData = createConsumerData(group, topic); - deFiConsumerManager.registerConsumer(consumerData.getGroupName(), - clientChannelInfo, - consumerData.getConsumeType(), - consumerData.getMessageModel(), - consumerData.getConsumeFromWhere(), - consumerData.getSubscriptionDataSet(), - false); - } - - @Test - public void testRegisterAndUnregisterConsumer() { - assertThat(deFiConsumerManager.getConsumerTable().size()).isEqualTo(1); - deFiConsumerManager.unregisterConsumer(consumerData.getGroupName(), clientChannelInfo, false); - assertThat(deFiConsumerManager.getConsumerTable().size()).isEqualTo(0); - } - - @Test - public void testDoChannelCloseEvent() { - assertThat(deFiConsumerManager.getConsumerTable().size()).isEqualTo(1); - deFiConsumerManager.doChannelCloseEvent("127.0.0.1", mockChannel); - assertThat(deFiConsumerManager.getConsumerTable().size()).isEqualTo(0); - } - - private ConsumerData createConsumerData(String group, String topic) { - ConsumerData consumerData = new ConsumerData(); - consumerData.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); - consumerData.setConsumeType(ConsumeType.CONSUME_PASSIVELY); - consumerData.setGroupName(group); - consumerData.setMessageModel(MessageModel.CLUSTERING); - Set subscriptionDataSet = new HashSet<>(); - SubscriptionData subscriptionData = new SubscriptionData(); - subscriptionData.setTopic(topic); - subscriptionData.setSubString("*"); - subscriptionData.setSubVersion(100L); - subscriptionDataSet.add(subscriptionData); - consumerData.setSubscriptionDataSet(subscriptionDataSet); - return consumerData; - } - -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/DeFiProducerManagerTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/DeFiProducerManagerTest.java deleted file mode 100644 index ab13d854f2..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/client/DeFiProducerManagerTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.client; - -import io.netty.channel.Channel; -import java.util.HashMap; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.remoting.protocol.LanguageCode; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiProducerManagerTest { - private DeFiProducerManager deFiProducerManager; - private String group = "FooBar"; - private ClientChannelInfo clientInfo; - - @Mock - private Channel channel; - - @Before - public void init() { - deFiProducerManager = new DeFiProducerManager(); - clientInfo = new ClientChannelInfo(channel, "ClientIdTest", LanguageCode.JAVA, 1); - - } - - @Test - public void doChannelCloseEvent() throws Exception { - deFiProducerManager.registerProducer(group, clientInfo); - assertThat(deFiProducerManager.getGroupChannelTable().get(group).get(channel)).isNotNull(); - - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isNotNull(); - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isEqualTo(clientInfo); - - deFiProducerManager.doChannelCloseEvent("127.0.0.1", channel); - assertThat(deFiProducerManager.getGroupChannelTable().get(group).get(channel)).isNull(); - - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isNull(); - } - - @Test - public void testRegisterProducer() throws Exception { - deFiProducerManager.registerProducer(group, clientInfo); - HashMap channelMap = deFiProducerManager.getGroupChannelTable().get(group); - assertThat(channelMap).isNotNull(); - assertThat(channelMap.get(channel)).isEqualTo(clientInfo); - - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isNotNull(); - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isEqualTo(clientInfo); - } - - @Test - public void unregisterProducer() throws Exception { - deFiProducerManager.registerProducer(group, clientInfo); - HashMap channelMap = deFiProducerManager.getGroupChannelTable().get(group); - assertThat(channelMap).isNotNull(); - assertThat(channelMap.get(channel)).isEqualTo(clientInfo); - - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isNotNull(); - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isEqualTo(clientInfo); - - deFiProducerManager.unregisterProducer(group, clientInfo); - channelMap = deFiProducerManager.getGroupChannelTable().get(group); - assertThat(channelMap).isNull(); - - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isNull(); - assertThat(deFiProducerManager.getProducerChannelTable().get(clientInfo.getClientId())).isNull(); - } - -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueManagerTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueManagerTest.java deleted file mode 100644 index c85d2e06df..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/consumequeue/ConsumeQueueManagerTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.consumequeue; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import io.netty.channel.Channel; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumerData; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.LanguageCode; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class ConsumeQueueManagerTest { - private ConsumeQueueManager consumeQueueManager = ConsumeQueueManager.onlyInstance(); - @Spy - private DeFiBrokerController deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), new DeFiBusBrokerConfig()); - @Mock - private MessageStore messageStore; - private final String group = "BarGroup"; - private final String topic = "BarTopic"; - private final int queueId = 0; - private final long offSet = 1024; - @Mock - private Channel channel; - private ClientChannelInfo clientChannelInfo; - private String clientId = UUID.randomUUID().toString(); - - @Before - public void init() { - deFiBrokerController.setMessageStore(messageStore); - consumeQueueManager.setBrokerController(deFiBrokerController); - } - - @Test - public void testRecordAndScanUnsubscribedTopic() { - consumeQueueManager.recordLastDeliverOffset(group, topic, queueId, offSet); - long deliverOffset = consumeQueueManager.queryDeliverOffset(group, topic, queueId); - assertThat(deliverOffset).isEqualTo(offSet); - consumeQueueManager.scanUnsubscribedTopic(); - long deliverOffsetNew = consumeQueueManager.queryDeliverOffset(group, topic, queueId); - assertThat(deliverOffsetNew).isEqualTo(-1); - } - - @Test - public void testGetMinAccumulated() throws Exception { - clientChannelInfo = new ClientChannelInfo(channel, clientId, LanguageCode.JAVA, 100); - ConsumerData consumerData = createConsumerData(group, topic); - deFiBrokerController.getConsumerManager().registerConsumer( - consumerData.getGroupName(), - clientChannelInfo, - consumerData.getConsumeType(), - consumerData.getMessageModel(), - consumerData.getConsumeFromWhere(), - consumerData.getSubscriptionDataSet(), - false); - deFiBrokerController.getConsumerOffsetManager().commitOffset(clientId, group, topic, queueId, offSet); - consumeQueueManager.setBrokerController(deFiBrokerController); - when(messageStore.getMaxOffsetInQueue(topic, queueId)).thenReturn(1025L); - ConsumeQueueWaterMark mark = consumeQueueManager.getMinAccumulated(topic, queueId); - assertThat(mark).isNotNull(); - assertThat(mark.getTopic()).isEqualTo(topic); - assertThat(mark.getConsumerGroup()).isEqualTo(group); - assertThat(mark.getAccumulated()).isEqualTo(1); - } - - private static ConsumerData createConsumerData(String group, String topic) { - ConsumerData consumerData = new ConsumerData(); - consumerData.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); - consumerData.setConsumeType(ConsumeType.CONSUME_PASSIVELY); - consumerData.setGroupName(group); - consumerData.setMessageModel(MessageModel.CLUSTERING); - Set subscriptionDataSet = new HashSet<>(); - SubscriptionData subscriptionData = new SubscriptionData(); - subscriptionData.setTopic(topic); - subscriptionData.setSubString("*"); - subscriptionData.setSubVersion(100L); - subscriptionDataSet.add(subscriptionData); - consumerData.setSubscriptionDataSet(subscriptionDataSet); - return consumerData; - } - -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/consumequeue/MessageRedirectManagerTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/consumequeue/MessageRedirectManagerTest.java deleted file mode 100644 index 1884b273cd..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/consumequeue/MessageRedirectManagerTest.java +++ /dev/null @@ -1,79 +0,0 @@ -package cn.webank.defibus.broker.consumequeue; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.DeFiBusConstant; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Before; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.spy; - -public class MessageRedirectManagerTest { - private DeFiBusBrokerConfig deFiBusBrokerConfig = new DeFiBusBrokerConfig(); - private MessageRedirectManager messageRedirectManager; - private DeFiBrokerController deFiBrokerController; - private String topic = "TestTopic"; - private String group = "TestGroup"; - private String clientId = UUID.randomUUID().toString(); - - - @Before - public void init() { - deFiBrokerController = spy(new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), deFiBusBrokerConfig)); - messageRedirectManager=new MessageRedirectManager(deFiBrokerController); - messageRedirectManager.updateConfigs(createRedirectConfItem()); - deFiBrokerController.getClientRebalanceResultManager().updateListenMap(group,topic,1,"127.0.0.1"); - } - @Test - public void testRedirectMessageToWhichQueue() throws Exception { - MessageRedirectManager.RedirectResult result = messageRedirectManager.redirectMessageToWhichQueue(createSendMsgRequestHeader(),"flag"); - assertThat(result.getStates()).isEqualTo(MessageRedirectManager.RedirectStates.REDIRECT_OK); - assertThat(result.getRedirectQueueId()).isEqualTo(1); - } - - - private List createRedirectConfItem(){ - List list = new ArrayList(); - MessageRedirectManager.RedirectConfItem item = new MessageRedirectManager.RedirectConfItem(); - item.setConsumerGroup(group); - item.setTopic(topic); - Set ips = new HashSet<>(); - ips.add("127.0.0.1"); - item.setIps(ips); - item.setRedirectFlag("flag"); - list.add(item); - return list ; - } - private SendMessageRequestHeader createSendMsgRequestHeader() { - SendMessageRequestHeader requestHeader = new SendMessageRequestHeader(); - requestHeader.setProducerGroup(group); - requestHeader.setTopic(topic); - requestHeader.setDefaultTopic(MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC); - requestHeader.setDefaultTopicQueueNums(3); - requestHeader.setQueueId(1); - requestHeader.setSysFlag(0); - requestHeader.setBornTimestamp(System.currentTimeMillis()); - requestHeader.setFlag(124); - Message msg = new Message(); - msg.putUserProperty(DeFiBusConstant.KEY, DeFiBusConstant.REPLY); - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO, clientId); - msg.setBody(new String("abcd").getBytes()); - requestHeader.setProperties(MessageDecoder.messageProperties2String(msg.getProperties())); - return requestHeader; - } - -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/monitor/QueueListeningMonitorTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/monitor/QueueListeningMonitorTest.java deleted file mode 100644 index c062162bbe..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/monitor/QueueListeningMonitorTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.monitor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import java.lang.reflect.Field; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; - -@RunWith(MockitoJUnitRunner.class) -public class QueueListeningMonitorTest { - private DeFiBrokerController deFiBrokerController; - - @Mock - QueueListeningMonitor queueListeningMonitor; - - @Before - public void init() throws Exception { - deFiBrokerController = new DeFiBrokerController( - new BrokerConfig(), - new NettyServerConfig(), - new NettyClientConfig(), - new MessageStoreConfig(), - new DeFiBusBrokerConfig()); - assertThat(deFiBrokerController.initialize()); - - Field field = DeFiBrokerController.class.getDeclaredField("queueListeningMonitor"); - field.setAccessible(true); - field.set(deFiBrokerController, queueListeningMonitor); - } - - @Test - public void testQueueListeningMonitorStart() throws Exception { - deFiBrokerController.start(); - verify(queueListeningMonitor).start(); - } - - @After - public void shutdown() { - deFiBrokerController.shutdown(); - } -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/plugin/DeFiPluginMessageStoreTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/plugin/DeFiPluginMessageStoreTest.java deleted file mode 100644 index f7eeb92351..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/plugin/DeFiPluginMessageStoreTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package cn.webank.defibus.broker.plugin; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import java.lang.reflect.Field; -import org.apache.rocketmq.broker.plugin.MessageStorePluginContext; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.store.AppendMessageResult; -import org.apache.rocketmq.store.AppendMessageStatus; -import org.apache.rocketmq.store.GetMessageResult; -import org.apache.rocketmq.store.GetMessageStatus; -import org.apache.rocketmq.store.MessageExtBrokerInner; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.PutMessageResult; -import org.apache.rocketmq.store.PutMessageStatus; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import static junit.framework.TestCase.assertTrue; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) -public class DeFiPluginMessageStoreTest { - - @Mock - private MessageStorePluginContext messageStorePluginContext; - @Spy - private DeFiBrokerController deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(),new DeFiBusBrokerConfig()); - @Mock - private MessageStore messageStore; - @Spy - private DeFiPluginMessageStore deFiPluginMessageStore =new DeFiPluginMessageStore(messageStorePluginContext,messageStore);; - - private String topic = "FooBar"; - private String group = "FooBarGroup"; - - @Before - public void init()throws Exception{ - Field field = DeFiPluginMessageStore.class.getDeclaredField("next"); - field.setAccessible(true); - field.set(deFiPluginMessageStore,messageStore); - deFiBrokerController.setMessageStore(messageStore); - deFiBrokerController.getConsumeQueueManager().getBrokerController().setMessageStore(messageStore); - deFiBrokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(topic,2,6,0); - deFiPluginMessageStore.start(); - } - - @Test - public void testPutMessage(){ - MessageExtBrokerInner inner = new MessageExtBrokerInner(); - when(messageStore.putMessage(inner)).thenReturn(new PutMessageResult(PutMessageStatus.PUT_OK, new AppendMessageResult(AppendMessageStatus.PUT_OK))); - PutMessageResult result = deFiPluginMessageStore.putMessage(inner); - assertThat(result.getPutMessageStatus()).isEqualTo(PutMessageStatus.PUT_OK); - assertTrue(result.getAppendMessageResult().isOk()); - } - - @Test - public void testGetMessage(){ - GetMessageResult getMessageResult = new GetMessageResult(); - getMessageResult.setStatus(GetMessageStatus.FOUND); - getMessageResult.setNextBeginOffset(1); - when(messageStore.getMessage(group,topic,1,0,0,null)).thenReturn(getMessageResult); - GetMessageResult result = deFiPluginMessageStore.getMessage(group,topic,1,0,0,null); - assertThat(result.getStatus()).isEqualTo(GetMessageStatus.FOUND); - assertThat(result.getNextBeginOffset()).isEqualTo(1); - } - - @After - public void shutdown(){ - deFiPluginMessageStore.shutdown(); - } - -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/plugin/PluginStoreStatServiceTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/plugin/PluginStoreStatServiceTest.java deleted file mode 100644 index 7fb14280e4..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/plugin/PluginStoreStatServiceTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.webank.defibus.broker.plugin; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class PluginStoreStatServiceTest { - - private PluginStoreStatService pluginStoreStatService = new PluginStoreStatService(); - - @Before - public void init() { - pluginStoreStatService.start(); - } - - @Test - public void testRecordPutTime() { - long value = 999; - while (true) { - pluginStoreStatService.recordPutTime(value); - value = value * 10; - if (value > 1000000000) - break; - } - pluginStoreStatService.printStoreStat(); - } - - @Test - public void testRecordGetTime() { - long value = 999; - while (true) { - pluginStoreStatService.recordGetTime(value); - value = value * 10; - if (value > 1000000000) - break; - } - pluginStoreStatService.printStoreStat(); - } - - @After - public void shutDown() { - pluginStoreStatService.shutdown(); - } -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiAdminBrokerProcessorTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiAdminBrokerProcessorTest.java deleted file mode 100644 index 39604c5c4f..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiAdminBrokerProcessorTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.admin.DeFiBusConsumeStats; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import io.netty.channel.ChannelHandlerContext; -import java.nio.ByteBuffer; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.TopicFilterType; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.CreateTopicRequestHeader; -import org.apache.rocketmq.common.protocol.header.GetConsumeStatsRequestHeader; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.remoting.protocol.RemotingSerializable; -import org.apache.rocketmq.store.MappedFile; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.SelectMappedBufferResult; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiAdminBrokerProcessorTest { - - private DeFiAdminBrokerProcessor deFiAdminBrokerProcessor; - - @Mock - private ChannelHandlerContext handlerContext; - - @Spy - private DeFiBrokerController - deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), - new MessageStoreConfig(), new DeFiBusBrokerConfig()); - - @Mock - private MessageStore messageStore; - - private String consumerGroup; - private String topic; - - @Before - public void init() { - deFiBrokerController.setMessageStore(messageStore); - deFiAdminBrokerProcessor = new DeFiAdminBrokerProcessor(deFiBrokerController); - consumerGroup = "tempGroup"; - topic = "testTopic"; - } - - @Test - public void testProcessRequestUpdateAndCreateTopic() throws RemotingCommandException { - RemotingCommand request = createCommand(RequestCode.UPDATE_AND_CREATE_TOPIC); - final RemotingCommand[] response = new RemotingCommand[1]; - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - response[0] = (RemotingCommand) invocation.getArguments()[0]; - return null; - } - }).when(handlerContext).writeAndFlush(any(Object.class)); - RemotingCommand responseToReturn = deFiAdminBrokerProcessor.processRequest(handlerContext, request); - if (responseToReturn != null) { - Assert.assertNull(response[0]); - response[0] = responseToReturn; - } - Assert.assertEquals(response[0].getCode(), ResponseCode.SUCCESS); - Assert.assertEquals(response[0].getOpaque(), request.getOpaque()); - } - - @Test - public void testProcessRequestUpdateAndCreateTopic_fail() throws RemotingCommandException { - RemotingCommand request = createCommand(RequestCode.UPDATE_AND_CREATE_TOPIC); - - RemotingCommand response = deFiAdminBrokerProcessor.processRequest(handlerContext, request); - } - - @Test - public void testProcessRequest_GET_CONSUME_STATS_V2() throws RemotingCommandException { - RemotingCommand request = createCommand(DeFiBusRequestCode.GET_CONSUME_STATS_V2); - deFiBrokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(topic, 1, 6, 0); - RemotingCommand response = deFiAdminBrokerProcessor.processRequest(handlerContext, request); - assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS); - DeFiBusConsumeStats consumerStats = RemotingSerializable.decode(response.getBody(), DeFiBusConsumeStats.class); - assertThat(consumerStats).isNotNull(); - } - - private SelectMappedBufferResult createSelectMappedBufferResult() { - SelectMappedBufferResult result = new SelectMappedBufferResult(0, ByteBuffer.allocate(1024), 0, new MappedFile()); - return result; - } - - private RemotingCommand createCommand(int requestCode) { - RemotingCommand request = null; - if (requestCode == RequestCode.UPDATE_AND_CREATE_TOPIC) { - request = RemotingCommand.createRequestCommand(requestCode, getCreateTopicRequestHeader()); - } else if (requestCode == DeFiBusRequestCode.GET_CONSUME_STATS_V2) { - request = RemotingCommand.createRequestCommand(requestCode, getConsumeStatsRequestHeader()); - } else if (requestCode == RequestCode.GET_BROKER_RUNTIME_INFO) { - request = RemotingCommand.createRequestCommand(requestCode, getConsumeStatsRequestHeader()); - } - request.setOpaque(1); - request.makeCustomHeaderToNet(); - return request; - } - - private GetConsumeStatsRequestHeader getConsumeStatsRequestHeader() { - GetConsumeStatsRequestHeader header = new GetConsumeStatsRequestHeader(); - header.setConsumerGroup(consumerGroup); - header.setTopic(topic); - return header; - } - - private CreateTopicRequestHeader getCreateTopicRequestHeader() { - CreateTopicRequestHeader header = new CreateTopicRequestHeader(); - header.setTopic(topic); - header.setDefaultTopic("DefaultCluster"); - header.setReadQueueNums(1); - header.setWriteQueueNums(1); - header.setPerm(6); - header.setTopicFilterType(TopicFilterType.SINGLE_TAG.toString()); - header.setTopicSysFlag(1); - return header; - } -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiClientManageProcessorTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiClientManageProcessorTest.java deleted file mode 100644 index fe73c0dc15..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiClientManageProcessorTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.protocol.header.GetConsumerListByGroupAndTopicRequestHeader; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.broker.client.ConsumerGroupInfo; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.GetConsumerListByGroupResponseBody; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumerData; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.LanguageCode; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.remoting.protocol.RemotingSerializable; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiClientManageProcessorTest { - private DeFiClientManageProcessor deFiClientManageProcessor; - @Spy - private DeFiBrokerController deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), new DeFiBusBrokerConfig()); - @Mock - private ChannelHandlerContext handlerContext; - @Mock - private Channel channel; - - private ClientChannelInfo clientChannelInfo; - private String clientId = UUID.randomUUID().toString(); - private String group = "FooBarGroup"; - private String topic = "FooBar"; - - @Before - public void init() { - // when(handlerContext.channel()).thenReturn(channel); - deFiClientManageProcessor = new DeFiClientManageProcessor(deFiBrokerController); - clientChannelInfo = new ClientChannelInfo(channel, clientId, LanguageCode.JAVA, 100); - ConsumerData consumerData = createConsumerData(group, topic); - deFiBrokerController.getConsumerManager().registerConsumer( - consumerData.getGroupName(), - clientChannelInfo, - consumerData.getConsumeType(), - consumerData.getMessageModel(), - consumerData.getConsumeFromWhere(), - consumerData.getSubscriptionDataSet(), - false); - } - - @Test - public void processRequest_GetConsumerListByGroupAndTopic() throws Exception { - ConsumerGroupInfo consumerGroupInfo = deFiBrokerController.getConsumerManager().getConsumerGroupInfo(group); - assertThat(consumerGroupInfo).isNotNull(); - - RemotingCommand request = GetConsumerListCommand(); - RemotingCommand response = deFiClientManageProcessor.processRequest(handlerContext, request); - assertThat(response).isNotNull(); - assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS); - GetConsumerListByGroupResponseBody body = RemotingSerializable.decode(response.getBody(), GetConsumerListByGroupResponseBody.class); - List clientIdList = body.getConsumerIdList(); - assertThat(clientIdList).isNotNull(); - assertThat(clientIdList.get(0)).isEqualTo(clientId); - } - - @Test - public void processRequest_GetConsumerListByGroupAndTopicIsNull() throws Exception { - ConsumerGroupInfo consumerGroupInfo = deFiBrokerController.getConsumerManager().getConsumerGroupInfo(group); - assertThat(consumerGroupInfo).isNotNull(); - - RemotingCommand request = GetConsumerListCommandWithNoTopic(); - RemotingCommand response = response = deFiClientManageProcessor.processRequest(handlerContext, request); - assertThat(response).isNotNull(); - assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS); - GetConsumerListByGroupResponseBody body = RemotingSerializable.decode(response.getBody(), GetConsumerListByGroupResponseBody.class); - List clientIdList = body.getConsumerIdList(); - assertThat(clientIdList).isNotNull(); - assertThat(clientIdList.get(0)).isEqualTo(clientId); - } - - private RemotingCommand GetConsumerListCommand() { - GetConsumerListByGroupAndTopicRequestHeader requestHeader = new GetConsumerListByGroupAndTopicRequestHeader(); - requestHeader.setConsumerGroup(group); - requestHeader.setTopic(topic); - RemotingCommand request = RemotingCommand.createRequestCommand(DeFiBusRequestCode.GET_CONSUMER_LIST_BY_GROUP_AND_TOPIC, requestHeader); - request.setLanguage(LanguageCode.JAVA); - request.setVersion(100); - request.makeCustomHeaderToNet(); - return request; - } - - private RemotingCommand GetConsumerListCommandWithNoTopic() { - GetConsumerListByGroupAndTopicRequestHeader requestHeader = new GetConsumerListByGroupAndTopicRequestHeader(); - requestHeader.setConsumerGroup(group); - RemotingCommand request = RemotingCommand.createRequestCommand(DeFiBusRequestCode.GET_CONSUMER_LIST_BY_GROUP_AND_TOPIC, requestHeader); - request.setLanguage(LanguageCode.JAVA); - request.setVersion(100); - request.makeCustomHeaderToNet(); - return request; - } - - static ConsumerData createConsumerData(String group, String topic) { - ConsumerData consumerData = new ConsumerData(); - consumerData.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); - consumerData.setConsumeType(ConsumeType.CONSUME_PASSIVELY); - consumerData.setGroupName(group); - consumerData.setMessageModel(MessageModel.CLUSTERING); - Set subscriptionDataSet = new HashSet<>(); - SubscriptionData subscriptionData = new SubscriptionData(); - subscriptionData.setTopic(topic); - subscriptionData.setSubString("*"); - subscriptionData.setSubVersion(100L); - subscriptionDataSet.add(subscriptionData); - consumerData.setSubscriptionDataSet(subscriptionDataSet); - return consumerData; - } -} \ No newline at end of file diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiPullMessageProcessorTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiPullMessageProcessorTest.java deleted file mode 100644 index 5a6d81ce97..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiPullMessageProcessorTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.PullMessageRequestHeader; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType; -import org.apache.rocketmq.common.protocol.heartbeat.ConsumerData; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; -import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.LanguageCode; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiPullMessageProcessorTest { - private DeFiPullMessageProcessor deFiPullMessageProcessor; - @Spy - private DeFiBrokerController deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), new DeFiBusBrokerConfig()); - @Mock - private ChannelHandlerContext handlerContext; - @Mock - private MessageStore messageStore; - private ClientChannelInfo clientChannelInfo; - private String group = "FooBarGroup"; - private String topic = "FooBar"; - private String clientId = UUID.randomUUID().toString(); - - @Before - public void init() { - deFiBrokerController.setMessageStore(messageStore); - deFiPullMessageProcessor = new DeFiPullMessageProcessor(deFiBrokerController); - Channel mockChannel = mock(Channel.class); - when(handlerContext.channel()).thenReturn(mockChannel); - deFiBrokerController.getTopicConfigManager().getTopicConfigTable().put(topic, new TopicConfig()); - clientChannelInfo = new ClientChannelInfo(mockChannel, clientId, LanguageCode.JAVA, 100); - ConsumerData consumerData = createConsumerData(group, topic); - deFiBrokerController.getConsumerManager().registerConsumer( - consumerData.getGroupName(), - clientChannelInfo, - consumerData.getConsumeType(), - consumerData.getMessageModel(), - consumerData.getConsumeFromWhere(), - consumerData.getSubscriptionDataSet(), - false); - } - - @Test - public void testProcessRequest_SubNotLatest() throws RemotingCommandException { - final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE); - request.addExtField("subVersion", String.valueOf(101)); - RemotingCommand response = deFiPullMessageProcessor.processRequest(handlerContext, request); - assertThat(response).isNotNull(); - assertThat(response.getCode()).isEqualTo(ResponseCode.PULL_NOT_FOUND); - assertThat(response.getRemark()).contains("subscription not latest"); - } - - private RemotingCommand createPullMsgCommand(int requestCode) { - PullMessageRequestHeader requestHeader = new PullMessageRequestHeader(); - requestHeader.setCommitOffset(123L); - requestHeader.setConsumerGroup(group); - requestHeader.setMaxMsgNums(100); - requestHeader.setQueueId(1); - requestHeader.setQueueOffset(456L); - requestHeader.setSubscription("*"); - requestHeader.setTopic(topic); - requestHeader.setSysFlag(0); - requestHeader.setSubVersion(100L); - RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader); - request.makeCustomHeaderToNet(); - return request; - } - - static ConsumerData createConsumerData(String group, String topic) { - ConsumerData consumerData = new ConsumerData(); - consumerData.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); - consumerData.setConsumeType(ConsumeType.CONSUME_PASSIVELY); - consumerData.setGroupName(group); - consumerData.setMessageModel(MessageModel.CLUSTERING); - Set subscriptionDataSet = new HashSet<>(); - SubscriptionData subscriptionData = new SubscriptionData(); - subscriptionData.setTopic(topic); - subscriptionData.setSubString("*"); - subscriptionData.setSubVersion(100L); - subscriptionDataSet.add(subscriptionData); - consumerData.setSubscriptionDataSet(subscriptionDataSet); - return consumerData; - } -} \ No newline at end of file diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiReplyMessageProcessorTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiReplyMessageProcessorTest.java deleted file mode 100644 index fb5855213a..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiReplyMessageProcessorTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.broker.client.DeFiProducerManager; -import cn.webank.defibus.broker.net.DeFiBusBroker2Client; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import java.net.InetSocketAddress; -import java.util.UUID; -import org.apache.rocketmq.broker.client.ClientChannelInfo; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.store.AppendMessageResult; -import org.apache.rocketmq.store.AppendMessageStatus; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.PutMessageResult; -import org.apache.rocketmq.store.PutMessageStatus; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -public class DeFiReplyMessageProcessorTest { - private DeFiBusBrokerConfig deFiBusBrokerConfig = new DeFiBusBrokerConfig(); - private DeFiReplyMessageProcessor deFiReplyMessageProcessor; - private ChannelHandlerContext channelHandlerContext; - private DeFiBrokerController deFiBrokerController; - private MessageStore messageStore; - private String topic = "TestTopic"; - private String group = "TestGroup"; - private String clientId = UUID.randomUUID().toString(); - - @Before - public void init() { - deFiBrokerController = spy(new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), deFiBusBrokerConfig)); - channelHandlerContext = mock(ChannelHandlerContext.class); - messageStore = mock(MessageStore.class); - DeFiBusBroker2Client broker2Client = mock(DeFiBusBroker2Client.class); - when(this.deFiBrokerController.getDeFiBusBroker2Client()).thenReturn(broker2Client); - when(broker2Client.pushRRReplyMessageToClient(any(), any(), any())).thenReturn(true); - Channel channel = mock(Channel.class); - when(channel.isActive()).thenReturn(true); - ClientChannelInfo channelInfo = mock(ClientChannelInfo.class); - when(channelInfo.getChannel()).thenReturn(channel); - DeFiProducerManager mockProducer = mock(DeFiProducerManager.class); - when(mockProducer.getClientChannel(anyString())).thenReturn(channelInfo); - when(this.deFiBrokerController.getProducerManager()).thenReturn(mockProducer); - this.deFiBrokerController.setMessageStore(this.messageStore); - when(this.messageStore.now()).thenReturn(System.currentTimeMillis()); - AppendMessageResult appendMessageResult = new AppendMessageResult(AppendMessageStatus.PUT_OK, 0, 0, "00000000000000000000000000000000", messageStore.now(), 0L, 0); - when(this.messageStore.putMessage(any())).thenReturn(new PutMessageResult(PutMessageStatus.PUT_OK, appendMessageResult)); - when(channel.remoteAddress()).thenReturn(new InetSocketAddress(1024)); - when(channelHandlerContext.channel()).thenReturn(channel); - deFiReplyMessageProcessor = new DeFiReplyMessageProcessor(this.deFiBrokerController); - } - - @Test - public void assertReplyResult() throws RemotingCommandException { - final RemotingCommand request = createReplyMsgCommand(DeFiBusRequestCode.SEND_DIRECT_MESSAGE); - final RemotingCommand[] response = new RemotingCommand[1]; - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - response[0] = (RemotingCommand) invocation.getArguments()[0]; - return null; - } - }).when(channelHandlerContext).writeAndFlush(any(Object.class)); - RemotingCommand responseToReturn = deFiReplyMessageProcessor.processRequest(channelHandlerContext, request); - if (responseToReturn != null) { - Assert.assertNull(response[0]); - response[0] = responseToReturn; - } - Assert.assertEquals(response[0].getCode(), ResponseCode.SUCCESS); - Assert.assertEquals(response[0].getOpaque(), request.getOpaque()); - } - - private SendMessageRequestHeader createSendMsgRequestHeader() { - SendMessageRequestHeader requestHeader = new SendMessageRequestHeader(); - requestHeader.setProducerGroup(group); - requestHeader.setTopic(topic); - requestHeader.setDefaultTopic(MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC); - requestHeader.setDefaultTopicQueueNums(3); - requestHeader.setQueueId(1); - requestHeader.setSysFlag(0); - requestHeader.setBornTimestamp(System.currentTimeMillis()); - requestHeader.setFlag(124); - Message msg = new Message(); - msg.putUserProperty(DeFiBusConstant.KEY, DeFiBusConstant.REPLY); - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO, clientId); - msg.setBody(new String("abcd").getBytes()); - requestHeader.setProperties(MessageDecoder.messageProperties2String(msg.getProperties())); - return requestHeader; - } - - private RemotingCommand createReplyMsgCommand(int requestCode) { - SendMessageRequestHeader requestHeader = createSendMsgRequestHeader(); - RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader); - request.makeCustomHeaderToNet(); - return request; - } -} diff --git a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiSendMessageProcessorTest.java b/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiSendMessageProcessorTest.java deleted file mode 100644 index 3e4f99ec85..0000000000 --- a/eventmesh-store/defibus-broker/src/test/java/cn/webank/defibus/broker/processor/DeFiSendMessageProcessorTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package cn.webank.defibus.broker.processor; - -import cn.webank.defibus.broker.DeFiBrokerController; -import cn.webank.defibus.common.DeFiBusBrokerConfig; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import java.net.InetSocketAddress; -import org.apache.rocketmq.broker.transaction.TransactionalMessageService; -import org.apache.rocketmq.common.BrokerConfig; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.protocol.RequestCode; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.NettyServerConfig; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.store.AppendMessageResult; -import org.apache.rocketmq.store.AppendMessageStatus; -import org.apache.rocketmq.store.MessageExtBrokerInner; -import org.apache.rocketmq.store.MessageStore; -import org.apache.rocketmq.store.PutMessageResult; -import org.apache.rocketmq.store.PutMessageStatus; -import org.apache.rocketmq.store.config.MessageStoreConfig; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiSendMessageProcessorTest { - private DeFiSendMessageProcessor deFiSendMessageProcessor; - @Mock - private ChannelHandlerContext handlerContext; - @Spy - private DeFiBrokerController deFiBrokerController = new DeFiBrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig(), new DeFiBusBrokerConfig()); - @Mock - private MessageStore messageStore; - - @Mock - private TransactionalMessageService transactionMsgService; - - private String topic = "FooBar"; - private String group = "FooBarGroup"; - - @Before - public void init() { - deFiBrokerController.setMessageStore(messageStore); - deFiBrokerController.getConsumeQueueManager().getBrokerController().setMessageStore(messageStore); - deFiBrokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(topic, 2, 6, 0); - when(messageStore.now()).thenReturn(System.currentTimeMillis()); - Channel mockChannel = mock(Channel.class); - when(mockChannel.remoteAddress()).thenReturn(new InetSocketAddress(1024)); - when(handlerContext.channel()).thenReturn(mockChannel); - deFiSendMessageProcessor = new DeFiSendMessageProcessor(deFiBrokerController); - } - - @Test - public void testProcessRequest() throws RemotingCommandException { - when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.PUT_OK, new AppendMessageResult(AppendMessageStatus.PUT_OK))); - assertPutResult(ResponseCode.SUCCESS); - } - - private SendMessageRequestHeader createSendMsgRequestHeader() { - SendMessageRequestHeader requestHeader = new SendMessageRequestHeader(); - requestHeader.setProducerGroup(group); - requestHeader.setTopic(topic); - requestHeader.setDefaultTopic(MixAll.AUTO_CREATE_TOPIC_KEY_TOPIC); - requestHeader.setDefaultTopicQueueNums(3); - requestHeader.setQueueId(1); - requestHeader.setSysFlag(0); - requestHeader.setBornTimestamp(System.currentTimeMillis()); - requestHeader.setFlag(124); - requestHeader.setReconsumeTimes(0); - return requestHeader; - } - - private RemotingCommand createSendMsgCommand(int requestCode) { - SendMessageRequestHeader requestHeader = createSendMsgRequestHeader(); - - RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader); - request.setBody(new byte[] {'a'}); - request.makeCustomHeaderToNet(); - return request; - } - - private void assertPutResult(int responseCode) throws RemotingCommandException { - final RemotingCommand request = createSendMsgCommand(RequestCode.SEND_MESSAGE); - final RemotingCommand[] response = new RemotingCommand[1]; - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - response[0] = invocation.getArgument(0); - return null; - } - }).when(handlerContext).writeAndFlush(any(Object.class)); - RemotingCommand responseToReturn = deFiSendMessageProcessor.processRequest(handlerContext, request); - if (responseToReturn != null) { - assertThat(response[0]).isNull(); - response[0] = responseToReturn; - } - assertThat(response[0].getCode()).isEqualTo(responseCode); - assertThat(response[0].getOpaque()).isEqualTo(request.getOpaque()); - } -} \ No newline at end of file diff --git a/eventmesh-store/defibus-client/.gitignore b/eventmesh-store/defibus-client/.gitignore deleted file mode 100644 index c1285b3799..0000000000 --- a/eventmesh-store/defibus-client/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -/bin/ -/.git/ -/.gradle/ -/.settings/ -/logs -.DS_Store -.*.swp -*.ipr -*.iml -*.iws -*.class -*.log -.idea -build -.classpath -.project -/test-output/ -/dist -/.pmd -/classes -/logs -/out \ No newline at end of file diff --git a/eventmesh-store/defibus-client/build.gradle b/eventmesh-store/defibus-client/build.gradle deleted file mode 100644 index 6c00fedfd6..0000000000 --- a/eventmesh-store/defibus-client/build.gradle +++ /dev/null @@ -1,27 +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. - */ - -List Log = [ - "org.slf4j:slf4j-log4j12:1.7.12", - "log4j:log4j:1.2.17" -] - -dependencies { - compile project(":defibus-common") - compile "org.apache.rocketmq:rocketmq-client:$project.rocketmqVersion" - testCompile Log -} \ No newline at end of file diff --git a/eventmesh-store/defibus-client/conf/checkstyle.xml b/eventmesh-store/defibus-client/conf/checkstyle.xml deleted file mode 100644 index 3d024111bc..0000000000 --- a/eventmesh-store/defibus-client/conf/checkstyle.xml +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/DeFiBusClientManager.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/DeFiBusClientManager.java deleted file mode 100644 index 1c76d16caf..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/DeFiBusClientManager.java +++ /dev/null @@ -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. - */ - -package cn.webank.defibus.client; - -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.common.util.ReflectUtil; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.rocketmq.client.ClientConfig; -import org.apache.rocketmq.client.impl.MQClientManager; -import org.apache.rocketmq.remoting.RPCHook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusClientManager { - private static DeFiBusClientManager instance = new DeFiBusClientManager(); - private AtomicInteger factoryIndexGenerator = new AtomicInteger(); - private ConcurrentHashMap factoryTable; - - public static final Logger LOGGER = LoggerFactory.getLogger(DeFiBusClientManager.class); - - @SuppressWarnings("unchecked") - private DeFiBusClientManager() { - try { - //factoryTable, shared by all producer and consumer - //same clientId will return the same MQClientInstance - //In order to set our own deFiclient instance to all producer and consumer, need to get the pointer of this table - factoryTable = (ConcurrentHashMap) ReflectUtil.getSimpleProperty(MQClientManager.class, - MQClientManager.getInstance(), "factoryTable"); - } catch (Exception e) { - LOGGER.warn("failed to initialize factory in mqclient manager.", e); - } - } - - public static DeFiBusClientManager getInstance() { - return instance; - } - - public synchronized DeFiBusClientInstance getAndCreateDeFiBusClientInstance(final ClientConfig clientConfig, - RPCHook rpcHook) { - - String clientId = clientConfig.buildMQClientId(); - DeFiBusClientInstance instance = this.factoryTable.get(clientId); - if (null == instance) { - instance = - new DeFiBusClientInstance(clientConfig.cloneClientConfig(), - this.factoryIndexGenerator.getAndIncrement(), clientId, rpcHook); - DeFiBusClientInstance prev = this.factoryTable.putIfAbsent(clientId, instance); - if (prev != null) { - instance = prev; - LOGGER.warn("Returned Previous MQClientInstance for clientId:[{}]", clientId); - } else { - LOGGER.info("new instance activate. " + clientId); - } - } - return instance; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/common/DeFiBusClientConfig.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/common/DeFiBusClientConfig.java deleted file mode 100644 index 73e035364f..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/common/DeFiBusClientConfig.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.common; - -import cn.webank.defibus.common.DeFiBusVersion; -import org.apache.rocketmq.remoting.RPCHook; - -public class DeFiBusClientConfig { - //default mq producer - private String producerGroup = "DefaultProducerGroup"; - private int retryTimesWhenSendFailed = 2; - private int retryTimesWhenSendAsyncFailed = 2; - - private int pubWindowSize = 65535; //clientAsyncSemaphoreValue - - //default mq push consumer - private String consumerGroup = "DefaultConsumerGroup"; - private int consumeConcurrentlyMaxSpan = 2000; - private long pullInterval = 0; - private int consumeMessageBatchMaxSize = 1; - private int pullBatchSize = 32; - private int maxReconsumeTimes = 3; - private long consumeTimeout = 15; - - private int ackWindowSize = 1000; //pullThresholdForQueue - private int threadPoolCoreSize = 24; //consumeThreadMin - private int threadPoolMaxSize = 72; //consumeThreadMax - private int ackTime = 5000; //persistConsumerOffsetInterval - - //rmq client config - private String namesrvAddr = null; - private int pollNameServerInterval = 1000 * 5; - private int heartbeatBrokerInterval = 1000 * 10; - - private int consumeRequestQueueCapacity = 10000; - private String wsAddr = null; - private String clusterPrefix = null; - private final int version = DeFiBusVersion.CURRENT_VERSION; - private final RPCHook rpcHook = null; - private long queueIsolateTimeMillis = 60 * 1000L; - - private long pullTimeDelayMillsWhenExcept = 0; - private long pullTimeDelayMillsWhenFlowControl = 50; - private long pullTimeDelayMillsWhenSuspend = 500; - - private int minMqNumWhenSendLocal = 1; - - public String getProducerGroup() { - return producerGroup; - } - - public void setProducerGroup(String producerGroup) { - this.producerGroup = producerGroup; - } - - public int getRetryTimesWhenSendFailed() { - return retryTimesWhenSendFailed; - } - - public void setRetryTimesWhenSendFailed(int retryTimesWhenSendFailed) { - this.retryTimesWhenSendFailed = retryTimesWhenSendFailed; - } - - public int getRetryTimesWhenSendAsyncFailed() { - return retryTimesWhenSendAsyncFailed; - } - - public void setRetryTimesWhenSendAsyncFailed(int retryTimesWhenSendAsyncFailed) { - this.retryTimesWhenSendAsyncFailed = retryTimesWhenSendAsyncFailed; - } - - public int getPubWindowSize() { - return pubWindowSize; - } - - public void setPubWindowSize(int pubWindowSize) { - this.pubWindowSize = pubWindowSize; - } - - public String getConsumerGroup() { - return consumerGroup; - } - - public void setConsumerGroup(String consumerGroup) { - this.consumerGroup = consumerGroup; - } - - public int getConsumeConcurrentlyMaxSpan() { - return consumeConcurrentlyMaxSpan; - } - - public void setConsumeConcurrentlyMaxSpan(int consumeConcurrentlyMaxSpan) { - this.consumeConcurrentlyMaxSpan = consumeConcurrentlyMaxSpan; - } - - public long getPullInterval() { - return pullInterval; - } - - public void setPullInterval(long pullInterval) { - this.pullInterval = pullInterval; - } - - public int getConsumeMessageBatchMaxSize() { - return consumeMessageBatchMaxSize; - } - - public void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) { - this.consumeMessageBatchMaxSize = consumeMessageBatchMaxSize; - } - - public int getPullBatchSize() { - return pullBatchSize; - } - - public void setPullBatchSize(int pullBatchSize) { - this.pullBatchSize = pullBatchSize; - } - - public int getMaxReconsumeTimes() { - return maxReconsumeTimes; - } - - public void setMaxReconsumeTimes(int maxReconsumeTimes) { - this.maxReconsumeTimes = maxReconsumeTimes; - } - - public long getConsumeTimeout() { - return consumeTimeout; - } - - public void setConsumeTimeout(long consumeTimeout) { - this.consumeTimeout = consumeTimeout; - } - - public int getAckWindowSize() { - return ackWindowSize; - } - - public void setAckWindowSize(int ackWindowSize) { - this.ackWindowSize = ackWindowSize; - } - - public int getThreadPoolCoreSize() { - return threadPoolCoreSize; - } - - public void setThreadPoolCoreSize(int threadPoolCoreSize) { - this.threadPoolCoreSize = threadPoolCoreSize; - } - - public int getThreadPoolMaxSize() { - return threadPoolMaxSize; - } - - public void setThreadPoolMaxSize(int threadPoolMaxSize) { - this.threadPoolMaxSize = threadPoolMaxSize; - } - - public int getAckTime() { - return ackTime; - } - - public void setAckTime(int ackTime) { - this.ackTime = ackTime; - } - - public String getNamesrvAddr() { - return namesrvAddr; - } - - public void setNamesrvAddr(String namesrvAddr) { - this.namesrvAddr = namesrvAddr; - } - - public int getPollNameServerInterval() { - return pollNameServerInterval; - } - - public void setPollNameServerInterval(int pollNameServerInterval) { - this.pollNameServerInterval = pollNameServerInterval; - } - - public int getHeartbeatBrokerInterval() { - return heartbeatBrokerInterval; - } - - public void setHeartbeatBrokerInterval(int heartbeatBrokerInterval) { - this.heartbeatBrokerInterval = heartbeatBrokerInterval; - } - - public int getConsumeRequestQueueCapacity() { - return consumeRequestQueueCapacity; - } - - public void setConsumeRequestQueueCapacity(int consumeRequestQueueCapacity) { - this.consumeRequestQueueCapacity = consumeRequestQueueCapacity; - } - - public String getWsAddr() { - return wsAddr; - } - - public void setWsAddr(String wsAddr) { - this.wsAddr = wsAddr; - } - - public int getVersion() { - return version; - } - - public RPCHook getRpcHook() { - return rpcHook; - } - - public long getQueueIsolateTimeMillis() { - return queueIsolateTimeMillis; - } - - public void setQueueIsolateTimeMillis(long queueIsolateTimeMillis) { - this.queueIsolateTimeMillis = queueIsolateTimeMillis; - } - - public String getClusterPrefix() { - return clusterPrefix; - } - - public void setClusterPrefix(String clusterPrefix) { - if (clusterPrefix != null) { - String tmp = clusterPrefix.toUpperCase().trim().replace(" ", ""); - if (tmp.length() > 0) - this.clusterPrefix = tmp; - } - } - - public long getPullTimeDelayMillsWhenExcept() { - return pullTimeDelayMillsWhenExcept; - } - - public void setPullTimeDelayMillsWhenExcept(long pullTimeDelayMillsWhenExcept) { - this.pullTimeDelayMillsWhenExcept = pullTimeDelayMillsWhenExcept; - } - - public long getPullTimeDelayMillsWhenFlowControl() { - return pullTimeDelayMillsWhenFlowControl; - } - - public void setPullTimeDelayMillsWhenFlowControl(long pullTimeDelayMillsWhenFlowControl) { - this.pullTimeDelayMillsWhenFlowControl = pullTimeDelayMillsWhenFlowControl; - } - - public long getPullTimeDelayMillsWhenSuspend() { - return pullTimeDelayMillsWhenSuspend; - } - - public void setPullTimeDelayMillsWhenSuspend(long pullTimeDelayMillsWhenSuspend) { - this.pullTimeDelayMillsWhenSuspend = pullTimeDelayMillsWhenSuspend; - } - - public int getMinMqNumWhenSendLocal() { - return minMqNumWhenSendLocal; - } - - public void setMinMqNumWhenSendLocal(int minMqNumWhenSendLocal) { - this.minMqNumWhenSendLocal = minMqNumWhenSendLocal; - } - - @Override public String toString() { - return "DeFiBusClientConfig{" + - "producerGroup='" + producerGroup + '\'' + - ", retryTimesWhenSendFailed=" + retryTimesWhenSendFailed + - ", retryTimesWhenSendAsyncFailed=" + retryTimesWhenSendAsyncFailed + - ", pubWindowSize=" + pubWindowSize + - ", consumerGroup='" + consumerGroup + '\'' + - ", consumeConcurrentlyMaxSpan=" + consumeConcurrentlyMaxSpan + - ", pullInterval=" + pullInterval + - ", consumeMessageBatchMaxSize=" + consumeMessageBatchMaxSize + - ", pullBatchSize=" + pullBatchSize + - ", maxReconsumeTimes=" + maxReconsumeTimes + - ", consumeTimeout=" + consumeTimeout + - ", ackWindowSize=" + ackWindowSize + - ", threadPoolCoreSize=" + threadPoolCoreSize + - ", threadPoolMaxSize=" + threadPoolMaxSize + - ", ackTime=" + ackTime + - ", namesrvAddr='" + namesrvAddr + '\'' + - ", pollNameServerInterval=" + pollNameServerInterval + - ", heartbeatBrokerInterval=" + heartbeatBrokerInterval + - ", consumeRequestQueueCapacity=" + consumeRequestQueueCapacity + - ", wsAddr='" + wsAddr + '\'' + - ", clusterPrefix='" + clusterPrefix + '\'' + - ", version=" + version + - ", rpcHook=" + rpcHook + - ", queueIsolateTimeMillis=" + queueIsolateTimeMillis + - ", pullTimeDelayMillsWhenExcept=" + pullTimeDelayMillsWhenExcept + - ", pullTimeDelayMillsWhenFlowControl=" + pullTimeDelayMillsWhenFlowControl + - ", pullTimeDelayMillsWhenSuspend=" + pullTimeDelayMillsWhenSuspend + - ", minMqNumWhenSendLocal=" + minMqNumWhenSendLocal + - '}'; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/common/DeFiBusClientUtil.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/common/DeFiBusClientUtil.java deleted file mode 100644 index 664f495a94..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/common/DeFiBusClientUtil.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.common; - -import cn.webank.defibus.common.DeFiBusConstant; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageExt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusClientUtil { - public static final Logger LOGGER = LoggerFactory.getLogger(DeFiBusClientUtil.class); - - public static Message createReplyMessage(MessageExt sourceMsg, byte[] content) { - String cluster = sourceMsg.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_CLUSTER); - String replyTopic = DeFiBusConstant.RR_REPLY_TOPIC; - if (!StringUtils.isEmpty(cluster)) { - replyTopic = cluster + "-" + replyTopic; - } else { - LOGGER.warn("no cluster info from message, can not reply"); - return null; - } - - Message msg = new Message(); - msg.setTopic(replyTopic);//回程topic - msg.setBody(content);//body - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO, sourceMsg.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO));//回给谁 - msg.putUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID, sourceMsg.getUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID));//原uniqueId - String sourceBroker = sourceMsg.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_BROKER); - if (!StringUtils.isEmpty(sourceBroker)) { - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_BROKER, sourceBroker);//消息从哪个broker来 - } - - return msg; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/DeFiBusClientAPIImpl.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/DeFiBusClientAPIImpl.java deleted file mode 100644 index a14abe5718..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/DeFiBusClientAPIImpl.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl; - -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.protocol.body.GetConsumerListByGroupAndTopicResponseBody; -import cn.webank.defibus.common.protocol.header.GetConsumerListByGroupAndTopicRequestHeader; -import cn.webank.defibus.common.util.ReflectUtil; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.rocketmq.client.ClientConfig; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.client.hook.SendMessageContext; -import org.apache.rocketmq.client.impl.ClientRemotingProcessor; -import org.apache.rocketmq.client.impl.CommunicationMode; -import org.apache.rocketmq.client.impl.MQClientAPIImpl; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; -import org.apache.rocketmq.client.impl.producer.TopicPublishInfo; -import org.apache.rocketmq.client.producer.SendCallback; -import org.apache.rocketmq.client.producer.SendResult; -import org.apache.rocketmq.client.producer.SendStatus; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageClientIDSetter; -import org.apache.rocketmq.common.message.MessageConst; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.namesrv.TopAddressing; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeaderV2; -import org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader; -import org.apache.rocketmq.remoting.InvokeCallback; -import org.apache.rocketmq.remoting.RPCHook; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.exception.RemotingConnectException; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.apache.rocketmq.remoting.exception.RemotingSendRequestException; -import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; -import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.ResponseFuture; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusClientAPIImpl extends MQClientAPIImpl { - public static final Logger LOGGER = LoggerFactory.getLogger(DeFiBusClientAPIImpl.class); - private static boolean sendSmartMsg = - Boolean.parseBoolean(System.getProperty("org.apache.rocketmq.client.sendSmartMsg", "true")); - private TopAddressing topAddressing; - - public DeFiBusClientAPIImpl(NettyClientConfig nettyClientConfig, - ClientRemotingProcessor clientRemotingProcessor, - RPCHook rpcHook, - ClientConfig clientConfig) { - - super(nettyClientConfig, clientRemotingProcessor, rpcHook, clientConfig); - - } - - public void setWsAddr(String wsAddr) { - try { - topAddressing = (TopAddressing) ReflectUtil.getSimpleProperty(MQClientAPIImpl.class, this, "topAddressing"); - ReflectUtil.setSimpleProperty(TopAddressing.class, topAddressing, "wsAddr", wsAddr); - LOGGER.debug("activate configure center, address: " + wsAddr); - } catch (Exception e) { - LOGGER.warn("Error when set ws address. configure center may not work.", e); - } - } - - @Override - public SendResult sendMessage(// - final String addr, // 1 - final String brokerName, // 2 - final Message msg, // 3 - final SendMessageRequestHeader requestHeader, // 4 - final long timeoutMillis, // 5 - final CommunicationMode communicationMode, // 6 - final SendCallback sendCallback, // 7 - final TopicPublishInfo topicPublishInfo, // 8 - final MQClientInstance instance, // 9 - final int retryTimesWhenSendFailed, // 10 - final SendMessageContext context, // 11 - final DefaultMQProducerImpl producer // 12 - ) throws RemotingException, MQBrokerException, InterruptedException { - RemotingCommand request = null; - if (DeFiBusConstant.REPLY.equals(msg.getProperties().get(DeFiBusConstant.KEY)) || - DeFiBusConstant.DIRECT.equals(msg.getProperties().get(DeFiBusConstant.KEY))) { - if (sendSmartMsg) { - SendMessageRequestHeaderV2 requestHeaderV2 = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV2(requestHeader); - request = RemotingCommand.createRequestCommand(DeFiBusRequestCode.SEND_DIRECT_MESSAGE_V2, requestHeaderV2); - } else { - request = RemotingCommand.createRequestCommand(DeFiBusRequestCode.SEND_DIRECT_MESSAGE, requestHeader); - } - request.setBody(msg.getBody()); - final AtomicInteger times = new AtomicInteger(); - this.sendMessageAsync(addr, brokerName, msg, timeoutMillis, request, sendCallback, topicPublishInfo, instance, - retryTimesWhenSendFailed, times, context, producer); - return null; - - } else { - return super.sendMessage(addr, brokerName, msg, requestHeader, timeoutMillis, communicationMode, sendCallback, topicPublishInfo, instance, retryTimesWhenSendFailed, context, producer); - } - } - - private void sendMessageAsync(// - final String addr, // - final String brokerName, // - final Message msg, // - final long timeoutMillis, // - final RemotingCommand request, // - final SendCallback sendCallback, // - final TopicPublishInfo topicPublishInfo, // - final MQClientInstance instance, // - final int retryTimesWhenSendFailed, // - final AtomicInteger times, // - final SendMessageContext context, // - final DefaultMQProducerImpl producer // - ) throws InterruptedException, RemotingException { - super.getRemotingClient().invokeAsync(addr, request, timeoutMillis, new InvokeCallback() { - @Override - public void operationComplete(ResponseFuture responseFuture) { - RemotingCommand response = responseFuture.getResponseCommand(); - if (null == sendCallback && response != null) { - - try { - SendResult sendResult = processSendResponse(brokerName, msg, response); - if (context != null && sendResult != null) { - context.setSendResult(sendResult); - context.getProducer().executeSendMessageHookAfter(context); - } - } catch (Throwable e) { - // - } - - producer.updateFaultItem(brokerName, System.currentTimeMillis() - responseFuture.getBeginTimestamp(), false); - return; - } - - if (response != null) { - try { - SendResult sendResult = processSendResponse(brokerName, msg, response); - assert sendResult != null; - if (context != null) { - context.setSendResult(sendResult); - context.getProducer().executeSendMessageHookAfter(context); - } - - try { - sendCallback.onSuccess(sendResult); - } catch (Throwable e) { - } - - producer.updateFaultItem(brokerName, System.currentTimeMillis() - responseFuture.getBeginTimestamp(), false); - } catch (Exception e) { - producer.updateFaultItem(brokerName, System.currentTimeMillis() - responseFuture.getBeginTimestamp(), true); - onExceptionImpl(brokerName, msg, 0L, request, sendCallback, topicPublishInfo, instance, - retryTimesWhenSendFailed, times, e, context, false, producer); - } - } else { - producer.updateFaultItem(brokerName, System.currentTimeMillis() - responseFuture.getBeginTimestamp(), true); - if (!responseFuture.isSendRequestOK()) { - MQClientException ex = new MQClientException("send request failed", responseFuture.getCause()); - onExceptionImpl(brokerName, msg, 0L, request, sendCallback, topicPublishInfo, instance, - retryTimesWhenSendFailed, times, ex, context, true, producer); - } else if (responseFuture.isTimeout()) { - MQClientException ex = new MQClientException("wait response timeout " + responseFuture.getTimeoutMillis() + "ms", - responseFuture.getCause()); - onExceptionImpl(brokerName, msg, 0L, request, sendCallback, topicPublishInfo, instance, - retryTimesWhenSendFailed, times, ex, context, true, producer); - } else { - MQClientException ex = new MQClientException("unknow reseaon", responseFuture.getCause()); - onExceptionImpl(brokerName, msg, 0L, request, sendCallback, topicPublishInfo, instance, - retryTimesWhenSendFailed, times, ex, context, true, producer); - } - } - } - }); - } - - private void onExceptionImpl(final String brokerName, // - final Message msg, // - final long timeoutMillis, // - final RemotingCommand request, // - final SendCallback sendCallback, // - final TopicPublishInfo topicPublishInfo, // - final MQClientInstance instance, // - final int timesTotal, // - final AtomicInteger curTimes, // - final Exception e, // - final SendMessageContext context, // - final boolean needRetry, // - final DefaultMQProducerImpl producer // 12 - ) { - int tmp = curTimes.incrementAndGet(); - if (needRetry && tmp <= timesTotal) { - String retryBrokerName = brokerName;//by default, it will send to the same broker - if (topicPublishInfo != null) { //select one message queue accordingly, in order to determine which broker to send - MessageQueue mqChosen = producer.selectOneMessageQueue(topicPublishInfo, brokerName); - retryBrokerName = mqChosen.getBrokerName(); - } - String addr = instance.findBrokerAddressInPublish(retryBrokerName); - LOGGER.info("async send msg by retry {} times. topic={}, brokerAddr={}, brokerName={}", tmp, msg.getTopic(), addr, - retryBrokerName); - try { - request.setOpaque(RemotingCommand.createNewRequestId()); - sendMessageAsync(addr, retryBrokerName, msg, timeoutMillis, request, sendCallback, topicPublishInfo, instance, - timesTotal, curTimes, context, producer); - } catch (InterruptedException e1) { - onExceptionImpl(retryBrokerName, msg, timeoutMillis, request, sendCallback, topicPublishInfo, instance, timesTotal, curTimes, e1, - context, false, producer); - } catch (RemotingConnectException e1) { - producer.updateFaultItem(brokerName, 3000, true); - onExceptionImpl(retryBrokerName, msg, timeoutMillis, request, sendCallback, topicPublishInfo, instance, timesTotal, curTimes, e1, - context, true, producer); - } catch (RemotingTooMuchRequestException e1) { - onExceptionImpl(retryBrokerName, msg, timeoutMillis, request, sendCallback, topicPublishInfo, instance, timesTotal, curTimes, e1, - context, false, producer); - } catch (RemotingException e1) { - producer.updateFaultItem(brokerName, 3000, true); - onExceptionImpl(retryBrokerName, msg, timeoutMillis, request, sendCallback, topicPublishInfo, instance, timesTotal, curTimes, e1, - context, true, producer); - } - } else { - - if (context != null) { - context.setException(e); - context.getProducer().executeSendMessageHookAfter(context); - } - - try { - sendCallback.onException(e); - } catch (Exception ignored) { - } - } - } - - private SendResult processSendResponse(// - final String brokerName, // - final Message msg, // - final RemotingCommand response// - ) throws MQBrokerException, RemotingCommandException { - switch (response.getCode()) { - case ResponseCode.FLUSH_DISK_TIMEOUT: - LOGGER.warn("publish success, but flush disk timeout " + response.getRemark()); - case ResponseCode.FLUSH_SLAVE_TIMEOUT: - LOGGER.warn("publish success, but flush slave timeout " + response.getRemark()); - case ResponseCode.SLAVE_NOT_AVAILABLE: { - LOGGER.warn("publish success, but slave is not available " + response.getRemark()); - } - case ResponseCode.SUCCESS: { - SendStatus sendStatus = SendStatus.SEND_OK; - switch (response.getCode()) { - case ResponseCode.FLUSH_DISK_TIMEOUT: - sendStatus = SendStatus.FLUSH_DISK_TIMEOUT; - break; - case ResponseCode.FLUSH_SLAVE_TIMEOUT: - sendStatus = SendStatus.FLUSH_SLAVE_TIMEOUT; - break; - case ResponseCode.SLAVE_NOT_AVAILABLE: - sendStatus = SendStatus.SLAVE_NOT_AVAILABLE; - break; - case ResponseCode.SUCCESS: - sendStatus = SendStatus.SEND_OK; - break; - default: - assert false; - break; - } - - SendMessageResponseHeader responseHeader = - (SendMessageResponseHeader) response.decodeCommandCustomHeader(SendMessageResponseHeader.class); - - MessageQueue messageQueue = new MessageQueue(msg.getTopic(), brokerName, responseHeader.getQueueId()); - - SendResult sendResult = new SendResult(sendStatus, - MessageClientIDSetter.getUniqID(msg), - responseHeader.getMsgId(), messageQueue, responseHeader.getQueueOffset()); - sendResult.setTransactionId(responseHeader.getTransactionId()); - String regionId = response.getExtFields().get(MessageConst.PROPERTY_MSG_REGION); - if (regionId == null || regionId.isEmpty()) { - regionId = "DefaultRegion"; - } - sendResult.setRegionId(regionId); - return sendResult; - } - default: - break; - } - - throw new MQBrokerException(response.getCode(), response.getRemark()); - } - - public List getConsumerIdListByGroupAndTopic( - final String addr, - final String consumerGroup, - final String topic, - final long timeoutMillis) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, - MQBrokerException, InterruptedException { - GetConsumerListByGroupAndTopicRequestHeader requestHeader = new GetConsumerListByGroupAndTopicRequestHeader(); - requestHeader.setConsumerGroup(consumerGroup); - requestHeader.setTopic(topic); - RemotingCommand request = RemotingCommand.createRequestCommand(DeFiBusRequestCode.GET_CONSUMER_LIST_BY_GROUP_AND_TOPIC, requestHeader); - - RemotingCommand response = this.getRemotingClient().invokeSync(MixAll.brokerVIPChannel(false, addr), - request, timeoutMillis); - assert response != null; - switch (response.getCode()) { - case ResponseCode.SUCCESS: { - if (response.getBody() != null) { - GetConsumerListByGroupAndTopicResponseBody body = - GetConsumerListByGroupAndTopicResponseBody.decode(response.getBody(), GetConsumerListByGroupAndTopicResponseBody.class); - return body.getConsumerIdList(); - } - } - default: - break; - } - - throw new MQBrokerException(response.getCode(), response.getRemark()); - } - -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/DeFiBusClientRemotingProcessor.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/DeFiBusClientRemotingProcessor.java deleted file mode 100644 index 4feace3705..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/DeFiBusClientRemotingProcessor.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl; - -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.client.impl.producer.RRResponseFuture; -import cn.webank.defibus.client.impl.producer.ResponseTable; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.message.DeFiBusMessageConst; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.protocol.header.NotifyTopicChangedRequestHeader; -import cn.webank.defibus.common.protocol.header.ReplyMessageRequestHeader; -import io.netty.channel.ChannelHandlerContext; -import java.io.IOException; -import java.net.InetSocketAddress; -import org.apache.rocketmq.common.UtilAll; -import org.apache.rocketmq.common.message.MessageAccessor; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.common.sysflag.MessageSysFlag; -import org.apache.rocketmq.remoting.common.RemotingHelper; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.netty.NettyRequestProcessor; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusClientRemotingProcessor implements NettyRequestProcessor { - public static final Logger LOGGER = LoggerFactory.getLogger(DeFiBusClientRemotingProcessor.class); - private final DeFiBusClientInstance mqClientFactory; - - public DeFiBusClientRemotingProcessor(final DeFiBusClientInstance mqClientFactory) { - this.mqClientFactory = mqClientFactory; - } - - @Override - public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { - switch (request.getCode()) { - case DeFiBusRequestCode.PUSH_RR_REPLY_MSG_TO_CLIENT: - return this.receiveRRReplyMsg(ctx, request); - case DeFiBusRequestCode.NOTIFY_WHEN_TOPIC_CONFIG_CHANGE: - return this.notifyWhenTopicConfigChange(ctx, request); - default: - break; - } - return null; - } - - private RemotingCommand receiveRRReplyMsg(ChannelHandlerContext ctx, - RemotingCommand request) throws RemotingCommandException { - long receiveTime = System.currentTimeMillis(); - ReplyMessageRequestHeader requestHeader = (ReplyMessageRequestHeader) request.decodeCommandCustomHeader(ReplyMessageRequestHeader.class); - - try { - MessageExt msg = new MessageExt(); - msg.setTopic(requestHeader.getTopic()); - msg.setQueueId(requestHeader.getQueueId()); - msg.setStoreTimestamp(requestHeader.getStoreTimestamp()); - - if (requestHeader.getBornHost() != null) { - String[] bornHostArr = requestHeader.getBornHost().split("/"); - String bornHost/*ip:port*/ = bornHostArr[bornHostArr.length - 1]; - String[] host = bornHost.split(":"); - if (host.length == 2) - msg.setBornHost(new InetSocketAddress(host[0], Integer.parseInt(host[1]))); - } - - if (requestHeader.getStoreHost() != null) { - String[] storeHostArr = requestHeader.getStoreHost().split("/"); - String storeHost = storeHostArr[storeHostArr.length - 1]; - String[] host = storeHost.split(":"); - if (host.length == 2) - msg.setStoreHost(new InetSocketAddress(host[0], Integer.parseInt(host[1]))); - } - - byte[] body = request.getBody(); - if ((requestHeader.getSysFlag() & MessageSysFlag.COMPRESSED_FLAG) == MessageSysFlag.COMPRESSED_FLAG) { - try { - body = UtilAll.uncompress(body); - } catch (IOException e) { - LOGGER.warn("err when uncompress constant", e); - } - } - msg.setBody(body); - msg.setFlag(requestHeader.getFlag()); - MessageAccessor.setProperties(msg, MessageDecoder.string2messageProperties(requestHeader.getProperties())); - - MessageAccessor.putProperty(msg, DeFiBusMessageConst.ARRIVE_TIME, String.valueOf(receiveTime)); - msg.setBornTimestamp(requestHeader.getBornTimestamp()); - msg.setReconsumeTimes(requestHeader.getReconsumeTimes() == null ? 0 : requestHeader.getReconsumeTimes()); - processResponse(msg); - - } catch (Exception e) { - LOGGER.warn("unknown err when receiveRRReplyMsg", e); - } - - return null; - } - - private void processResponse(MessageExt msg) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("receive reply message :{}", msg); - } - final String uniqueId = msg.getUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID); - - RRResponseFuture rrResponseFuture = ResponseTable.getRrResponseFurtureConcurrentHashMap().get(uniqueId); - if (rrResponseFuture != null && !rrResponseFuture.release()) { - if (rrResponseFuture.getRrCallback() != null) { - rrResponseFuture.getRrCallback().onSuccess(msg); - ResponseTable.getRrResponseFurtureConcurrentHashMap().remove(uniqueId); - } else { - rrResponseFuture.putResponse(msg); - } - } else { - LOGGER.warn("receive reply message {} , but requester has gone away", msg.toString()); - } - } - - private RemotingCommand notifyWhenTopicConfigChange(ChannelHandlerContext ctx, RemotingCommand request) { - try { - final NotifyTopicChangedRequestHeader requestHeader = - (NotifyTopicChangedRequestHeader) request.decodeCommandCustomHeader(NotifyTopicChangedRequestHeader.class); - LOGGER.info("receive broker's notification[{}], topic: {} config changed, update topic route info from nameserver immediately", - RemotingHelper.parseChannelRemoteAddr(ctx.channel()), - requestHeader.getTopic()); - this.mqClientFactory.updateTopicRouteInfoFromNameServer(requestHeader.getTopic()); - this.mqClientFactory.rebalanceImmediately(); - } catch (Exception e) { - LOGGER.warn("notifyWhenTopicConfigChange failed", RemotingHelper.exceptionSimpleDesc(e)); - } - return null; - } - - @Override - public boolean rejectRequest() { - return false; - } -} \ No newline at end of file diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/consumer/DeFiBusPullMessageService.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/consumer/DeFiBusPullMessageService.java deleted file mode 100644 index afbf3a4e22..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/consumer/DeFiBusPullMessageService.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.consumer; - -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.common.util.ReflectUtil; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl; -import org.apache.rocketmq.client.impl.consumer.MQConsumerInner; -import org.apache.rocketmq.client.impl.consumer.PullMessageService; -import org.apache.rocketmq.client.impl.consumer.PullRequest; -import org.apache.rocketmq.client.log.ClientLogger; -import org.apache.rocketmq.common.utils.ThreadUtils; -import org.apache.rocketmq.logging.InternalLogger; - -public class DeFiBusPullMessageService extends PullMessageService { - private final InternalLogger log = ClientLogger.getLog(); - private final DeFiBusClientInstance mQClientFactory; - private final LinkedBlockingQueue pullRequestQueue; - private final BrokerHealthyManager brokerHealthyManager; - - private final ExecutorService executorService = Executors.newSingleThreadExecutor( - new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - return new Thread(r, "DeFiBusPullMessageRetryThread"); - } - }); - - public DeFiBusPullMessageService(DeFiBusClientInstance deFiBusClientInstance) { - super(deFiBusClientInstance); - this.mQClientFactory = deFiBusClientInstance; - this.brokerHealthyManager = new BrokerHealthyManager(); - - pullRequestQueue = (LinkedBlockingQueue) ReflectUtil.getSimpleProperty(PullMessageService.class, this, "pullRequestQueue"); - } - - private void pullMessage(final PullRequest pullRequest) { - final MQConsumerInner consumer = this.mQClientFactory.selectConsumer(pullRequest.getConsumerGroup()); - if (consumer != null) { - long beginPullRequestTime = System.currentTimeMillis(); - - DefaultMQPushConsumerImpl impl = (DefaultMQPushConsumerImpl) consumer; - log.debug("begin Pull Message, {}", pullRequest); - impl.pullMessage(pullRequest); - - long rt = System.currentTimeMillis() - beginPullRequestTime; - if (rt >= brokerHealthyManager.getIsolateThreshold()) { - brokerHealthyManager.isolateBroker(pullRequest.getMessageQueue().getBrokerName()); - } - } else { - log.warn("No matched consumer for the PullRequest {}, drop it", pullRequest); - } - } - - private void pullMessageWithHealthyManage(final PullRequest pullRequest) { - boolean brokerAvailable = brokerHealthyManager.isBrokerAvailable(pullRequest.getMessageQueue().getBrokerName()); - if (brokerAvailable) { - pullMessage(pullRequest); - } else { - runInRetryThread(pullRequest); - } - } - - @Override - public void run() { - log.info(this.getServiceName() + " service started"); - - while (!this.isStopped()) { - try { - PullRequest pullRequest = this.pullRequestQueue.take(); - this.pullMessageWithHealthyManage(pullRequest); - } catch (InterruptedException ignored) { - } catch (Exception e) { - log.error("Pull Message Service Run Method exception", e); - } - } - - log.info(this.getServiceName() + " service end"); - } - - private void runInRetryThread(PullRequest pullRequest) { - try { - executorService.submit(new Runnable() { - @Override - public void run() { - pullMessage(pullRequest); - } - }); - } catch (Exception ex) { - log.info("execute pull message in retry thread fail.", ex); - super.executePullRequestLater(pullRequest, 100); - } - } - - @Override - public void shutdown(boolean interrupt) { - super.shutdown(interrupt); - ThreadUtils.shutdownGracefully(this.executorService, 1000, TimeUnit.MILLISECONDS); - } - - @Override - public String getServiceName() { - return DeFiBusPullMessageService.class.getSimpleName(); - } - - class BrokerHealthyManager { - private final ConcurrentHashMap isolatedBroker = new ConcurrentHashMap<>(); - private long isolateThreshold = 500; - private long ISOLATE_TIMEOUT = 5 * 60 * 1000; - - public boolean isBrokerAvailable(String brokerName) { - boolean brokerIsolated = isolatedBroker.containsKey(brokerName); - if (brokerIsolated) { - boolean isolatedTimeout = System.currentTimeMillis() - isolatedBroker.get(brokerName) > ISOLATE_TIMEOUT; - if (isolatedTimeout) { - removeIsolateBroker(brokerName); - return true; - } else { - return false; - } - } else { - return true; - } - } - - public void removeIsolateBroker(String brokerName) { - Long val = isolatedBroker.remove(brokerName); - if (!isolatedBroker.containsKey(brokerName)) { - log.info("remove isolated broker success, brokerName: {} isolate time: {}", brokerName, val); - } - } - - public void isolateBroker(String brokerName) { - isolatedBroker.put(brokerName, System.currentTimeMillis()); - if (isolatedBroker.containsKey(brokerName)) { - log.info("isolate broker for slow pull message success, {}", brokerName); - } - } - - public long getIsolateThreshold() { - return isolateThreshold; - } - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/factory/DeFiBusClientInstance.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/factory/DeFiBusClientInstance.java deleted file mode 100644 index 888d3838e1..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/factory/DeFiBusClientInstance.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.factory; - -import cn.webank.defibus.client.impl.DeFiBusClientAPIImpl; -import cn.webank.defibus.client.impl.DeFiBusClientRemotingProcessor; -import cn.webank.defibus.client.impl.consumer.DeFiBusPullMessageService; -import cn.webank.defibus.common.protocol.DeFiBusRequestCode; -import cn.webank.defibus.common.util.ReflectUtil; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.commons.lang3.RandomUtils; -import org.apache.rocketmq.client.ClientConfig; -import org.apache.rocketmq.client.impl.ClientRemotingProcessor; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.common.protocol.route.BrokerData; -import org.apache.rocketmq.common.protocol.route.TopicRouteData; -import org.apache.rocketmq.remoting.RPCHook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusClientInstance extends MQClientInstance { - private static final Logger LOGGER = LoggerFactory.getLogger(DeFiBusClientInstance.class); - private final ClientConfig clientConfig; - private DeFiBusClientAPIImpl deFiClientAPI; - private ClientRemotingProcessor clientRemotingProcessor; - private DeFiBusClientRemotingProcessor deFiClientRemotingProcessor; - private ExecutorService executorService; - private ScheduledExecutorService scheduledExecutorService; - - public DeFiBusClientInstance(ClientConfig clientConfig, int instanceIndex, String clientId) { - this(clientConfig, instanceIndex, clientId, null); - } - - public DeFiBusClientInstance(ClientConfig clientConfig, int instanceIndex, String clientId, RPCHook rpcHook) { - super(clientConfig, instanceIndex, clientId, rpcHook); - this.clientConfig = clientConfig; - try { - clientRemotingProcessor = (ClientRemotingProcessor) ReflectUtil.getSimpleProperty(MQClientInstance.class, this, "clientRemotingProcessor"); - - deFiClientRemotingProcessor = new DeFiBusClientRemotingProcessor(this); - - deFiClientAPI = new DeFiBusClientAPIImpl( - super.getNettyClientConfig(), - clientRemotingProcessor, - rpcHook, - clientConfig); - - ReflectUtil.setSimpleProperty(MQClientInstance.class, this, "mQClientAPIImpl", deFiClientAPI); - - DeFiBusPullMessageService deFiBusPullMessageService = new DeFiBusPullMessageService(this); - ReflectUtil.setSimpleProperty(MQClientInstance.class, this, "pullMessageService", deFiBusPullMessageService); - - if (this.clientConfig.getNamesrvAddr() != null) { - this.deFiClientAPI.updateNameServerAddressList(this.clientConfig.getNamesrvAddr()); - LOGGER.info("user specified name server address: {}", this.clientConfig.getNamesrvAddr()); - } - - executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() { - private AtomicInteger threadIndex = new AtomicInteger(0); - - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r, "deFiClientThread_" + this.threadIndex.getAndIncrement()); - t.setDaemon(true); - return t; - } - }); - - scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r, "deFiClientScheduledThread_"); - t.setDaemon(true); - return t; - } - }); - - super.getMQClientAPIImpl().getRemotingClient() - .registerProcessor(DeFiBusRequestCode.PUSH_RR_REPLY_MSG_TO_CLIENT, deFiClientRemotingProcessor, executorService); - super.getMQClientAPIImpl().getRemotingClient() - .registerProcessor(DeFiBusRequestCode.NOTIFY_WHEN_TOPIC_CONFIG_CHANGE, deFiClientRemotingProcessor, executorService); - } catch (Exception e) { - LOGGER.warn("failed to initialize factory in mqclient manager.", e); - } - - } - - @Override - public void shutdown() { - this.scheduledExecutorService.shutdown(); - super.shutdown(); - this.executorService.shutdown(); - } - - public ExecutorService getExecutorService() { - return executorService; - } - - public ScheduledExecutorService getScheduledExecutorService() { - return scheduledExecutorService; - } - - @Override - public List findConsumerIdList(final String topic, final String group) { - String brokerAddr = this.findBrokerAddrByTopic(topic); - if (null == brokerAddr) { - this.updateTopicRouteInfoFromNameServer(topic); - brokerAddr = this.findBrokerAddrByTopic(topic); - } - - if (null != brokerAddr) { - try { - LOGGER.debug("findConsumerIdList of {} from broker {}", topic, brokerAddr); - List cidList = deFiClientAPI.getConsumerIdListByGroupAndTopic(brokerAddr, group, topic, 3000); - if (cidList != null && !cidList.isEmpty()) { - return cidList; - } - } catch (Exception e) { - LOGGER.warn("getConsumerIdListByGroup failed, " + brokerAddr + " " + group + ", retry immediately"); - } - - String lastSelected = brokerAddr; - brokerAddr = this.findAnotherBrokerAddrByTopic(topic, lastSelected); - if (null == brokerAddr) { - this.updateTopicRouteInfoFromNameServer(topic); - brokerAddr = this.findAnotherBrokerAddrByTopic(topic, lastSelected); - } - if (null != brokerAddr) { - try { - LOGGER.debug("findConsumerIdList of {} from broker {}", topic, brokerAddr); - List cidList = deFiClientAPI.getConsumerIdListByGroupAndTopic(brokerAddr, group, topic, 3000); - return cidList; - } catch (Exception e) { - LOGGER.warn("getConsumerIdListByGroup failed, " + brokerAddr + " " + group + ", after retry ", e); - } - } - } - - return null; - } - - private String findAnotherBrokerAddrByTopic(String topic, String lastSelected) { - TopicRouteData topicRouteData = this.getTopicRouteTable().get(topic); - if (topicRouteData != null && topicRouteData.getBrokerDatas() != null) { - List allBrokers = topicRouteData.getBrokerDatas(); - for (BrokerData bd : allBrokers) { - if (!bd.selectBrokerAddr().equals(lastSelected)) { - String addr = bd.selectBrokerAddr(); - LOGGER.debug("find another broker addr by topic [{}], find addr: {}, lastSelected: {}", topic, addr, lastSelected); - return addr; - } - } - - if (!allBrokers.isEmpty()) { - int index = RandomUtils.nextInt(0, allBrokers.size()); - BrokerData bd = allBrokers.get(index % allBrokers.size()); - String addr = bd.selectBrokerAddr(); - LOGGER.debug("find any broker addr by topic [{}], find addr: {}, lastSelected: {}", topic, addr, lastSelected); - return addr; - } - } - return null; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/hook/DeFiBusClientHookFactory.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/hook/DeFiBusClientHookFactory.java deleted file mode 100644 index 8b2c74d3b8..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/hook/DeFiBusClientHookFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.hook; - -import org.apache.rocketmq.remoting.RPCHook; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusClientHookFactory { - private static final Logger LOGGER = LoggerFactory.getLogger(DeFiBusClientHookFactory.class); - - public static RPCHook createRPCHook(final RPCHook rpcHook) { - return new RPCHook() { - @Override - public void doBeforeRequest(String remoteAddr, RemotingCommand request) { - if (rpcHook != null) { - rpcHook.doBeforeRequest(remoteAddr, request); - } - } - - @Override - public void doAfterResponse(String remoteAddr, RemotingCommand request, RemotingCommand response) { - } - }; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/DeFiBusProducerImpl.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/DeFiBusProducerImpl.java deleted file mode 100644 index f5e7b01a05..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/DeFiBusProducerImpl.java +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.DeFiBusErrorCode; -import cn.webank.defibus.common.exception.DeFiBusException; -import cn.webank.defibus.common.protocol.DeFiBusResponseCode; -import cn.webank.defibus.common.util.DeFiBusRequestIDUtil; -import cn.webank.defibus.producer.DeFiBusProducer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.client.Validators; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.client.producer.DefaultMQProducer; -import org.apache.rocketmq.client.producer.SendCallback; -import org.apache.rocketmq.client.producer.SendResult; -import org.apache.rocketmq.common.ServiceState; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageBatch; -import org.apache.rocketmq.common.message.MessageClientIDSetter; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.body.ClusterInfo; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusProducerImpl { - public static final Logger LOGGER = LoggerFactory.getLogger(DeFiBusProducerImpl.class); - - private DeFiBusProducer deFiBusProducer; - private HealthyMessageQueueSelector messageQueueSelector; - private ScheduledExecutorService scheduledExecutorService; - private ExecutorService executorService = null; - private ConcurrentHashMap topicInitMap = new ConcurrentHashMap(); - private ClusterInfo clusterInfo; - - public DeFiBusProducerImpl(DeFiBusProducer deFiBusProducer, DeFiBusClientConfig deFiBusClientConfig, - DeFiBusClientInstance deFiBusClientInstance) { - this.deFiBusProducer = deFiBusProducer; - this.messageQueueSelector = new HealthyMessageQueueSelector(new MessageQueueHealthManager(deFiBusClientConfig.getQueueIsolateTimeMillis()), - deFiBusClientConfig.getMinMqNumWhenSendLocal()); - - executorService = deFiBusClientInstance.getExecutorService(); - scheduledExecutorService = deFiBusClientInstance.getScheduledExecutorService(); - - scheduledExecutorService.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - cleanExpiredRRRequest(); - } - }, 0, 1000, TimeUnit.MILLISECONDS); - - } - - private void cleanExpiredRRRequest() { - try { - List expiredRRRequest = new ArrayList(); - - Iterator> it = ResponseTable.getRrResponseFurtureConcurrentHashMap().entrySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - String rId = entry.getKey(); - RRResponseFuture responseFurture = entry.getValue(); - if (responseFurture.getExpiredTime() + 1000L <= System.currentTimeMillis()) { - it.remove(); - expiredRRRequest.add(responseFurture); - LOGGER.warn("remove timeout request " + rId); - } - } - - for (final RRResponseFuture responseFuture : expiredRRRequest) { - executorService.submit(new Runnable() { - @Override - public void run() { - if (!responseFuture.release()) { - Throwable throwable = new DeFiBusException(DeFiBusErrorCode.RR_REQUEST_TIMEOUT, "remove timeout request, deadline: " + responseFuture.getExpiredTime()); - responseFuture.getRrCallback().onException(throwable); - } - } - }); - } - } catch (Throwable ignore) { - LOGGER.warn("cleanExpiredRRRequest failed ,{}", ignore.getMessage()); - } - } - - public void reply( - Message replyMsg, - final SendCallback sendCallback) throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - replyMsg.putUserProperty(DeFiBusConstant.KEY, DeFiBusConstant.REPLY); - replyMsg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL, String.valueOf(deFiBusProducer.getDefaultMQProducer().getSendMsgTimeout())); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Reply message: {} ", replyMsg.toString()); - } - final String requestId = replyMsg.getUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID); - if (requestId == null) { - LOGGER.warn("rr request id is null, can not reply"); - } - publish(replyMsg, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - if (sendCallback != null) { - sendCallback.onSuccess(sendResult); - } - } - - @Override - public void onException(Throwable e) { - LOGGER.warn("Reply message fail, requestId={}", requestId); - if (sendCallback != null) { - sendCallback.onException(e); - } - } - }); - } - - public Message request(Message requestMsg, - long timeout) throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - return request(requestMsg, null, null, timeout); - } - - public Message request(Message requestMsg, final SendCallback sendCallback, RRCallback rrCallback, long timeout) - throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - - boolean isAsyncRR = (rrCallback != null); - - final String uniqueRequestId = DeFiBusRequestIDUtil.createUniqueName("w"); - DefaultMQProducer producer = deFiBusProducer.getDefaultMQProducer(); - requestMsg.putUserProperty(DeFiBusConstant.KEY, DeFiBusConstant.PERSISTENT); - requestMsg.putUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID, uniqueRequestId); - requestMsg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO, producer.buildMQClientId()); - requestMsg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL, String.valueOf(timeout)); - - final RRResponseFuture responseFurture = new RRResponseFuture(rrCallback, timeout); - - String topic = requestMsg.getTopic(); - boolean hasRouteData = deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().getTopicRouteTable().containsKey(topic); - Boolean isSendHeartbeatOk = topicInitMap.get(topic); - if (isSendHeartbeatOk == null) { - isSendHeartbeatOk = false; - } - if (!hasRouteData || !isSendHeartbeatOk) { - long startTimestamp = System.currentTimeMillis(); - synchronized (this) { - boolean hasRouteDataSync = deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().getTopicRouteTable().containsKey(topic); - if (!hasRouteDataSync) { - LOGGER.info("no topic route info for " + topic + ", send heartbeat to nameserver"); - deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().updateTopicRouteInfoFromNameServer(topic); - deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().sendHeartbeatToAllBrokerWithLock(); - topicInitMap.put(topic, true); - } - } - long cost = System.currentTimeMillis() - startTimestamp; - if (cost > 500) { - LOGGER.warn("get topic route info for {} before request cost {} ms.", topic, cost); - } - } - - ResponseTable.getRrResponseFurtureConcurrentHashMap().put(uniqueRequestId, responseFurture); - if (isAsyncRR) { - this.publish(requestMsg, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - if (sendCallback != null) { - sendCallback.onSuccess(sendResult); - } - } - - @Override - public void onException(Throwable e) { - LOGGER.warn("except when publish async rr message, uniqueId :{} {} ", uniqueRequestId, e.getMessage()); - ResponseTable.getRrResponseFurtureConcurrentHashMap().remove(uniqueRequestId); - if (sendCallback != null) { - sendCallback.onException(e); - } - } - }, timeout); - return null; - - } else { - publish(requestMsg, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - if (sendCallback != null) { - sendCallback.onSuccess(sendResult); - } - } - - @Override - public void onException(Throwable e) { - LOGGER.warn("except when publish sync rr message, uniqueId :{} {}", uniqueRequestId, e.getMessage()); - ResponseTable.getRrResponseFurtureConcurrentHashMap().remove(uniqueRequestId); - if (sendCallback != null) { - sendCallback.onException(e); - } - } - }, timeout); - Message retMessage = responseFurture.waitResponse(timeout); - ResponseTable.getRrResponseFurtureConcurrentHashMap().remove(uniqueRequestId); - if (retMessage == null) { - LOGGER.warn("request {} is sent, constant is :{}, but no rr response ", topic, uniqueRequestId); - } - return retMessage; - } - } - - public void publish(Message msg) throws MQClientException, RemotingException, InterruptedException { - publish(msg, deFiBusProducer.getDefaultMQProducer().getSendMsgTimeout()); - } - - public void publish(Message msg, long timeout) throws MQClientException, RemotingException, InterruptedException { - publish(msg, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - LOGGER.debug(sendResult.toString()); - } - - @Override - public void onException(Throwable e) { - LOGGER.warn("", e); - } - }, timeout); - } - - public void publish( - Collection msgs) throws MQClientException, RemotingException, MQBrokerException, InterruptedException { - for (Message msg : msgs) { - if (msg.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL) == null) { - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL, DeFiBusConstant.DEFAULT_TTL); - } - } - publish(batch(msgs)); - } - - private MessageBatch batch(Collection msgs) throws MQClientException { - MessageBatch msgBatch; - try { - msgBatch = MessageBatch.generateFromList(msgs); - for (Message message : msgBatch) { - Validators.checkMessage(message, deFiBusProducer.getDefaultMQProducer()); - MessageClientIDSetter.setUniqID(message); - } - msgBatch.setBody(msgBatch.encode()); - } catch (Exception e) { - throw new MQClientException("Failed to initiate the MessageBatch", e); - } - return msgBatch; - } - - public void publish(Message msg, - SendCallback sendCallback) throws MQClientException, RemotingException, InterruptedException { - publish(msg, sendCallback, this.deFiBusProducer.getDefaultMQProducer().getSendMsgTimeout()); - } - - public void publish(final Message msg, final SendCallback sendCallback, - final long timeout) throws MQClientException, RemotingException, InterruptedException { - if (msg.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL) == null) { - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL, DeFiBusConstant.DEFAULT_TTL); - } - - final AtomicReference selectorArgs = new AtomicReference(); - AsynCircuitBreakSendCallBack asynCircuitBreakSendCallBack = new AsynCircuitBreakSendCallBack(); - asynCircuitBreakSendCallBack.setMsg(msg); - asynCircuitBreakSendCallBack.setProducer(this.deFiBusProducer); - asynCircuitBreakSendCallBack.setSelectorArg(selectorArgs); - asynCircuitBreakSendCallBack.setSendCallback(sendCallback); - - String topic = msg.getTopic(); - boolean hasRouteData = deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().getTopicRouteTable().containsKey(topic); - if (!hasRouteData) { - LOGGER.info("no topic route info for " + topic + ", send heartbeat to nameserver"); - deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory().updateTopicRouteInfoFromNameServer(topic); - } - - DeFiBusProducerImpl.this.deFiBusProducer.getDefaultMQProducer().send(msg, messageQueueSelector, selectorArgs, asynCircuitBreakSendCallBack, timeout); - } - - class AsynCircuitBreakSendCallBack implements SendCallback { - private Message msg; - private DeFiBusProducer producer; - private AtomicReference selectorArg; - private SendCallback sendCallback; - private AtomicInteger sendRetryTimes = new AtomicInteger(0); - private AtomicInteger circuitBreakRetryTimes = new AtomicInteger(0); - private int queueCount = 0; - - public void setProducer(DeFiBusProducer producer) { - this.producer = producer; - } - - public void setMsg(Message msg) { - this.msg = msg; - } - - public void setSelectorArg(AtomicReference selectorArg) { - this.selectorArg = selectorArg; - } - - public void setSendCallback(SendCallback sendCallback) { - this.sendCallback = sendCallback; - } - - @Override - public void onSuccess(SendResult sendResult) { - messageQueueSelector.getMessageQueueHealthManager().markQueueHealthy(sendResult.getMessageQueue()); - if (sendCallback != null) { - sendCallback.onSuccess(sendResult); - } - } - - @Override - public void onException(Throwable e) { - try { - MessageQueueHealthManager messageQueueHealthManager - = ((HealthyMessageQueueSelector) messageQueueSelector).getMessageQueueHealthManager(); - MessageQueue messageQueue = ((AtomicReference) selectorArg).get(); - if (messageQueue != null) { - messageQueueSelector.getMessageQueueHealthManager().markQueueFault(messageQueue); - if (messageQueueSelector.getMessageQueueHealthManager().isQueueFault(messageQueue)) { - LOGGER.warn("isolate send failed mq. {} cause: {}", messageQueue, e.getMessage()); - } - } - //logic of fuse - if (e.getMessage().contains("CODE: " + DeFiBusResponseCode.CONSUME_DIFF_SPAN_TOO_LONG)) { - //first retry initialize - if (queueCount == 0) { - List messageQueueList = producer.getDefaultMQProducer().getDefaultMQProducerImpl().getTopicPublishInfoTable() - .get(msg.getTopic()).getMessageQueueList(); - queueCount = messageQueueList.size(); - String clusterPrefix = deFiBusProducer.getDeFiBusClientConfig().getClusterPrefix(); - if (!StringUtils.isEmpty(clusterPrefix)) { - for (MessageQueue mq : messageQueueList) { - if (messageQueueHealthManager.isQueueFault(mq)) { - queueCount--; - } - } - } - } - - int retryTimes = Math.min(queueCount, deFiBusProducer.getDeFiBusClientConfig().getRetryTimesWhenSendAsyncFailed()); - if (circuitBreakRetryTimes.get() < retryTimes) { - circuitBreakRetryTimes.incrementAndGet(); - LOGGER.warn("fuse:send to [{}] circuit break, retry no.[{}] times, msgKey:[{}]", messageQueue.toString(), circuitBreakRetryTimes.intValue(), msg.getKeys()); - producer.getDefaultMQProducer().send(msg, messageQueueSelector, selectorArg, this); - //no exception to client when retry - return; - } else { - LOGGER.warn("fuse:send to [{}] circuit break after retry {} times, msgKey:[{}]", messageQueue.toString(), retryTimes, msg.getKeys()); - } - } else { - int maxRetryTimes = producer.getDeFiBusClientConfig().getRetryTimesWhenSendAsyncFailed(); - if (sendRetryTimes.getAndIncrement() < maxRetryTimes) { - LOGGER.info("send message fail, retry {} now, msgKey: {}, cause: {}", sendRetryTimes.get(), msg.getKeys(), e.getMessage()); - producer.getDefaultMQProducer().send(msg, messageQueueSelector, selectorArg, this); - return; - } else { - LOGGER.warn("send message fail, after retry {} times, msgKey:[{}]", maxRetryTimes, msg.getKeys()); - } - } - - if (sendCallback != null) { - sendCallback.onException(e); - } - } catch (Exception e1) { - LOGGER.warn("onExcept fail", e1); - if (sendCallback != null) { - sendCallback.onException(e); - } - } - } - } - - public void updateSendNearbyMapping(Map newMapping) { - this.messageQueueSelector.setSendNearbyMapping(newMapping); - } - - public void startUpdateClusterInfoTask() { - updateClusterInfo(); - scheduledExecutorService.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - updateClusterInfo(); - } - }, 0, 60, TimeUnit.SECONDS); - } - - private void updateClusterInfo() { - try { - MQClientInstance mqClientInstance = this.deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory(); - if (mqClientInstance != null - && this.deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getServiceState() == ServiceState.RUNNING) { - if (mqClientInstance.getMQClientAPIImpl() != null && mqClientInstance.getMQClientAPIImpl().getNameServerAddressList() != null - && mqClientInstance.getMQClientAPIImpl().getNameServerAddressList().size() == 0) { - mqClientInstance.getMQClientAPIImpl().fetchNameServerAddr(); - } - clusterInfo = mqClientInstance.getMQClientAPIImpl().getBrokerClusterInfo(3000); - updateLocalBrokers(clusterInfo); - } - } catch (Throwable e) { - LOGGER.warn("updateClusterInfo failed, {}", e.getMessage()); - } - } - - private void updateLocalBrokers(ClusterInfo clusterInfo) { - if (clusterInfo != null) { - String clusterPrefix = deFiBusProducer.getDeFiBusClientConfig().getClusterPrefix(); - HashMap> clusterAddrTable = clusterInfo.getClusterAddrTable(); - Set currentBrokers = new HashSet(); - for (Map.Entry> entry : clusterAddrTable.entrySet()) { - String clusterName = entry.getKey(); - String clusterIdc = StringUtils.split(clusterName, DeFiBusConstant.IDC_SEPERATER)[0]; - if (StringUtils.isNotEmpty(clusterPrefix) && StringUtils.equalsIgnoreCase(clusterIdc, clusterPrefix)) { - currentBrokers.addAll(entry.getValue()); - } - } - if (!currentBrokers.equals(messageQueueSelector.getLocalBrokers())) { - messageQueueSelector.setLocalBrokers(currentBrokers); - LOGGER.info("localBrokers updated: {} , clusterPrefix :{} ", currentBrokers, clusterPrefix); - } - } - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/HealthyMessageQueueSelector.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/HealthyMessageQueueSelector.java deleted file mode 100644 index d0f616bc11..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/HealthyMessageQueueSelector.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.client.producer.MessageQueueSelector; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageQueue; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class HealthyMessageQueueSelector implements MessageQueueSelector { - private static final Logger LOGGER = LoggerFactory.getLogger(HealthyMessageQueueSelector.class); - private final ConcurrentHashMap topicSendIndex = new ConcurrentHashMap<>(); - private final MessageQueueHealthManager messageQueueHealthManager; - private int minMqCountWhenSendLocal = 1; - private Map sendNearbyMapping = new HashMap<>(); - private Set localBrokers = new HashSet(); - - public HealthyMessageQueueSelector(MessageQueueHealthManager messageQueueHealthManager, int minMqCountWhenSendLocal) { - this.messageQueueHealthManager = messageQueueHealthManager; - this.minMqCountWhenSendLocal = minMqCountWhenSendLocal; - } - - @Override - @SuppressWarnings("unchecked") - public MessageQueue select(List mqs, Message msg, final Object selectedResultRef) { - - if (mqs == null || mqs.size() == 0) { - LOGGER.debug("mq list is empty"); - return null; - } - - boolean pub2local = MapUtils.getBoolean(sendNearbyMapping, msg.getTopic(), Boolean.TRUE); - MessageQueue lastOne = ((AtomicReference) selectedResultRef).get(); - - if (pub2local) { - List localMQs = new ArrayList<>(); - List remoteMqs = new ArrayList<>(); - HashMap localBrokerMQCount = separateLocalAndRemoteMQs(mqs, localBrokers, localMQs, remoteMqs); - - for (String brokerName : localBrokerMQCount.keySet()) { - //if MQ num less than threshold, send msg to all broker - if (localBrokerMQCount.get(brokerName) <= minMqCountWhenSendLocal) { - localMQs.addAll(remoteMqs); - } - } - - //try select a mq from local idc first - MessageQueue candidate = selectMessageQueue(localMQs, lastOne, msg); - if (candidate != null) { - ((AtomicReference) selectedResultRef).set(candidate); - LOGGER.debug("select local mq [{}], {}", candidate.toString(), msg); - return candidate; - } - - //try select a mq from other idc if cannot select one from local idc - candidate = selectMessageQueue(remoteMqs, lastOne, msg); - if (candidate != null) { - ((AtomicReference) selectedResultRef).set(candidate); - LOGGER.debug("select remote mq [{}], {}", candidate.toString(), msg); - return candidate; - } - } else { - //try select a mq from all mqs - MessageQueue candidate = selectMessageQueue(mqs, lastOne, msg); - if (candidate != null) { - ((AtomicReference) selectedResultRef).set(candidate); - LOGGER.debug("select global mq [{}], {}", candidate.toString(), msg); - return candidate; - } - } - - //try select a mq which is not isolated if no mq satisfy all limits - for (int j = 0; j < mqs.size(); j++) { - int index = this.getSendIndex(msg.getTopic()); - int pos = Math.abs(index) % mqs.size(); - MessageQueue candidate = mqs.get(pos); - if (isQueueHealthy(candidate)) { - ((AtomicReference) selectedResultRef).set(candidate); - LOGGER.debug("select any available mq [{}], {}", candidate.toString(), msg); - return candidate; - } - } - - //in case of retry, still try select a mq from another broker if all mq isolated - if (lastOne != null) { - for (int j = 0; j < mqs.size(); j++) { - int index = this.getSendIndex(msg.getTopic()); - int pos = Math.abs(index) % mqs.size(); - MessageQueue candidate = mqs.get(pos); - if (!lastOne.getBrokerName().equals(candidate.getBrokerName())) { - ((AtomicReference) selectedResultRef).set(candidate); - LOGGER.debug("select another broker mq [{}], {}", candidate.toString(), msg); - return candidate; - } - } - } - - //select a mq from all mqs anyway if no mq satisfy any limits - int index = this.getSendIndex(msg.getTopic()); - int pos = Math.abs(index) % mqs.size(); - MessageQueue candidate = mqs.get(pos); - ((AtomicReference) selectedResultRef).set(candidate); - LOGGER.debug("select any mq [{}], {}", candidate.toString(), msg); - return candidate; - - } - - private MessageQueue selectMessageQueue(List mqs, MessageQueue lastOneSelected, - Message msg) { - boolean isRetry = (lastOneSelected != null); - List candidateMqs = mqs; - if (isRetry) { - candidateMqs = filterMqsByBrokerName(mqs, lastOneSelected.getBrokerName()); - } - for (int i = 0; i < candidateMqs.size(); i++) { - int index = this.getSendIndex(msg.getTopic()); - int pos = Math.abs(index) % candidateMqs.size(); - MessageQueue candidate = candidateMqs.get(pos); - if (isQueueHealthy(candidate)) { - return candidate; - } - } - return null; - } - - private boolean isQueueHealthy(MessageQueue mq) { - return (mq != null) && (messageQueueHealthManager.isQueueHealthy(mq)); - } - - private List filterMqsByBrokerName(final List mqs, String brokerName) { - List result = new ArrayList<>(); - if (mqs != null && StringUtils.isNotEmpty(brokerName)) { - for (int i = 0; i < mqs.size(); i++) { - if (!mqs.get(i).getBrokerName().equals(brokerName)) { - result.add(mqs.get(i)); - } - } - } - return result; - } - - private HashMap separateLocalAndRemoteMQs(List mqs, Set localBrokers, - List localMQs, List remoteMQs) { - if (localMQs == null) - localMQs = new ArrayList<>(); - if (remoteMQs == null) - remoteMQs = new ArrayList<>(); - HashMap brokerMQCount = new HashMap<>(); - for (MessageQueue mq : mqs) { - if (localBrokers.contains(mq.getBrokerName())) { - localMQs.add(mq); - Integer count = brokerMQCount.get(mq.getBrokerName()); - if (count == null) { - count = 0; - } - brokerMQCount.put(mq.getBrokerName(), count+1); - } else { - remoteMQs.add(mq); - } - } - return brokerMQCount; - } - - public MessageQueueHealthManager getMessageQueueHealthManager() { - return messageQueueHealthManager; - } - - public void setSendNearbyMapping(Map sendNearbyMapping) { - this.sendNearbyMapping = sendNearbyMapping; - } - - public Set getLocalBrokers() { - return localBrokers; - } - - public void setLocalBrokers(Set localBrokers) { - this.localBrokers = localBrokers; - } - - private int getSendIndex(String topic) { - AtomicInteger index = topicSendIndex.get(topic); - if (index == null) { - topicSendIndex.putIfAbsent(topic, new AtomicInteger(0)); - index = topicSendIndex.get(topic); - } - int result = Math.abs(index.getAndIncrement()); - if (result < 0) { - index.set(0); - result = index.getAndIncrement(); - } - return result; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/MessageQueueHealthManager.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/MessageQueueHealthManager.java deleted file mode 100644 index 52aee446ff..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/MessageQueueHealthManager.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import java.util.concurrent.ConcurrentHashMap; -import org.apache.rocketmq.common.message.MessageQueue; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MessageQueueHealthManager { - public static final Logger LOGGER = LoggerFactory.getLogger(MessageQueueHealthManager.class); - - public final ConcurrentHashMap faultMap = new ConcurrentHashMap(32); - - /** - * unhealthy mq isolate time in millisecond - */ - private long isoTime = 60 * 1000L; - - public MessageQueueHealthManager(long isoTime) { - this.isoTime = isoTime; - } - - public void markQueueFault(MessageQueue mq) { - faultMap.put(mq, System.currentTimeMillis() + isoTime); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("mark queue {} fault for time {}", mq, isoTime); - } - } - - public void markQueueHealthy(MessageQueue mq) { - if (faultMap.containsKey(mq)) { - LOGGER.info("mark queue healthy. {}", mq); - faultMap.remove(mq); - } - } - - public boolean isQueueFault(MessageQueue mq) { - Long isolateUntilWhen = faultMap.get(mq); - return isolateUntilWhen != null && System.currentTimeMillis() < isolateUntilWhen; - } - - public boolean isQueueHealthy(MessageQueue mq) { - return !isQueueFault(mq); - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/RRCallback.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/RRCallback.java deleted file mode 100644 index 4614be0492..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/RRCallback.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import org.apache.rocketmq.common.message.Message; - -public interface RRCallback { - public void onSuccess(Message msg); - - public void onException(Throwable e); -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/RRResponseFuture.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/RRResponseFuture.java deleted file mode 100644 index 330f698dc3..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/RRResponseFuture.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.rocketmq.common.message.Message; - -public class RRResponseFuture { - private CountDownLatch countDownLatch = new CountDownLatch(1); - private volatile Message respMsg = null; - private final RRCallback rrCallback; - private long expiredTime = System.currentTimeMillis(); - private AtomicBoolean release = new AtomicBoolean(false); - - public RRResponseFuture() { - this.rrCallback = null; - } - - public RRResponseFuture(RRCallback rrCallback) { - this.rrCallback = rrCallback; - } - - public RRResponseFuture(RRCallback rrCallback, long timeout) { - this.rrCallback = rrCallback; - this.expiredTime += timeout; - } - - public void putResponse(final Message respMsg) { - this.respMsg = respMsg; - this.countDownLatch.countDown(); - } - - public Message waitResponse(long timeout) throws InterruptedException { - this.countDownLatch.await(timeout, TimeUnit.MILLISECONDS); - return this.respMsg; - } - - public RRCallback getRrCallback() { - return rrCallback; - } - - public long getExpiredTime() { - return expiredTime; - } - - public boolean release() { - return release.getAndSet(true); - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/ResponseTable.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/ResponseTable.java deleted file mode 100644 index 04d0069ee7..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/producer/ResponseTable.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import java.util.concurrent.ConcurrentHashMap; - -public class ResponseTable { - private static ConcurrentHashMap rrResponseFurtureConcurrentHashMap = new ConcurrentHashMap(); - - public static ConcurrentHashMap getRrResponseFurtureConcurrentHashMap() { - return rrResponseFurtureConcurrentHashMap; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/rebalance/AllocateMessageQueueByIDC.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/rebalance/AllocateMessageQueueByIDC.java deleted file mode 100644 index 59ff32b91f..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/client/impl/rebalance/AllocateMessageQueueByIDC.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.rebalance; - -import cn.webank.defibus.common.DeFiBusConstant; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.apache.rocketmq.client.consumer.AllocateMessageQueueStrategy; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.client.log.ClientLogger; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.route.BrokerData; -import org.apache.rocketmq.common.protocol.route.TopicRouteData; -import org.apache.rocketmq.logging.InternalLogger; - -public class AllocateMessageQueueByIDC implements AllocateMessageQueueStrategy { - private static final InternalLogger log = ClientLogger.getLog(); - private MQClientInstance mqClientInstance = null; - private static final String UNKNOWN_IDC = "UNKNOWN_IDC"; - - @Override - public String getName() { - return "IDC_NEARBY"; - } - - @Override - public List allocate(String consumerGroup, String currentCID, List mqAll, - List cidAll) { - List result = new ArrayList(); - if (currentCID == null || currentCID.length() < 1) { - throw new IllegalArgumentException("currentCID is empty"); - } - if (mqAll == null || mqAll.isEmpty()) { - log.info("[IGNORE] doRebalance.allocate, mqAll is empty"); - return result; - } - if (cidAll == null || cidAll.isEmpty()) { - log.info("[IGNORE] doRebalance.allocate, cidAll is empty"); - return result; - } - - if (!cidAll.contains(currentCID)) { - log.info("[BUG] ConsumerGroup: {} The consumerId: {} not in cidAll: {}", - consumerGroup, - currentCID, - cidAll); - return result; - } - - { - log.debug("doRebalance: consumerGroup: {} currentCID: {}", consumerGroup, currentCID); - log.debug("mqAll:" + mqAll); - if (mqAll != null) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < mqAll.size(); i++) { - sb.append("MQ#" + i + ":" + mqAll.get(i) + " "); - } - log.debug(sb.toString()); - } - log.debug("cidAll:" + cidAll); - if (cidAll != null) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < cidAll.size(); i++) { - sb.append("CID#" + i + ":" + cidAll.get(i) + " "); - } - log.debug(sb.toString()); - } - } - - /** - * step1: seperate mqs and cids by idc - */ - Map> sepMqs = this.seperateMqsByIDC(mqAll); - Map> sepClients = this.seperateCidsByIDC(cidAll); - - /** - * step2: allocate local mqs first - */ - String clusterPrefix = extractIdcFromClientId(currentCID); - if (clusterPrefix != null) { - List nearbyMqs = sepMqs.get(clusterPrefix); - List nearbyCids = sepClients.get(clusterPrefix); - - if (nearbyMqs != null && nearbyCids != null && !nearbyMqs.isEmpty() && !nearbyCids.isEmpty()) { - Collections.sort(nearbyCids); - Collections.sort(nearbyMqs); - int index = nearbyCids.indexOf(currentCID); - for (int i = index; i < nearbyMqs.size(); i++) { - if (i % nearbyCids.size() == index) { - result.add(nearbyMqs.get(i)); - } - } - } - } - - /** - * step3: allocate mqs which no subscriber in the same idc - */ - List mqsNoClientsInSameIdc = new ArrayList<>(); - for (String idc : sepMqs.keySet()) { - if (!idc.equals(UNKNOWN_IDC) && (sepClients.get(idc) == null || sepClients.get(idc).isEmpty())) { - mqsNoClientsInSameIdc.addAll(sepMqs.get(idc)); - } - } - if (!mqsNoClientsInSameIdc.isEmpty()) { - Collections.sort(mqsNoClientsInSameIdc); - Collections.sort(cidAll); - int index = cidAll.indexOf(currentCID); - for (int i = index; i < mqsNoClientsInSameIdc.size(); i++) { - if (i % cidAll.size() == index) { - result.add(mqsNoClientsInSameIdc.get(i)); - } - } - } - - /** - * step4: allocate mqs which no matched any cluster and cannot determined idc. - */ - if (sepMqs.get(UNKNOWN_IDC) != null && !sepMqs.get(UNKNOWN_IDC).isEmpty()) { - log.warn("doRebalance: cannot determine idc of mqs. allocate all to myself. {}", sepMqs.get(UNKNOWN_IDC)); - result.addAll(sepMqs.get(UNKNOWN_IDC)); - } - return result; - } - - private Map> seperateMqsByIDC(List mqAll) { - String topic = mqAll.get(0).getTopic(); - TopicRouteData topicRouteData = mqClientInstance.getTopicRouteTable().get(topic); - if (topicRouteData == null) { - mqClientInstance.updateTopicRouteInfoFromNameServer(topic); - topicRouteData = mqClientInstance.getTopicRouteTable().get(topic); - } - - HashMap brokerIdcMap = new HashMap<>(); - ArrayList brokerDatas = new ArrayList<>(topicRouteData.getBrokerDatas()); - for (BrokerData broker : brokerDatas) { - String clusterName = broker.getCluster(); - String idc = clusterName.split(DeFiBusConstant.IDC_SEPERATER)[0]; - brokerIdcMap.put(broker.getBrokerName(), idc.toUpperCase()); - } - - Map> result = new HashMap<>(); - for (MessageQueue mq : mqAll) { - String idc = brokerIdcMap.get(mq.getBrokerName()); - if (idc == null) { - idc = UNKNOWN_IDC; - } - if (result.get(idc) == null) { - List mqList = new ArrayList<>(); - mqList.add(mq); - result.put(idc, mqList); - } else { - result.get(idc).add(mq); - } - } - return result; - } - - private Map> seperateCidsByIDC(List cidAll) { - Map> result = new HashMap<>(); - for (String cid : cidAll) { - String cidIdc = extractIdcFromClientId(cid); - if (cidIdc != null) { - cidIdc = cidIdc.toUpperCase(); - if (result.get(cidIdc) != null) { - result.get(cidIdc).add(cid); - } else { - List cidList = new ArrayList<>(); - cidList.add(cid); - result.put(cidIdc, cidList); - } - } - } - return result; - } - - private String extractIdcFromClientId(final String cid) { - if (cid != null) { - String[] cidArr = cid.split(DeFiBusConstant.INSTANCE_NAME_SEPERATER); - if (cidArr.length > 2) { - return cidArr[cidArr.length - 1]; - } - } - return null; - } - - public void setMqClientInstance(MQClientInstance mqClientInstance) { - this.mqClientInstance = mqClientInstance; - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrently.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrently.java deleted file mode 100644 index 2856c6651b..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrently.java +++ /dev/null @@ -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. - */ - -package cn.webank.defibus.consumer; - -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.message.DeFiBusMessageConst; -import java.util.ArrayList; -import java.util.List; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; -import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; -import org.apache.rocketmq.common.message.MessageExt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class DeFiBusMessageListenerConcurrently implements MessageListenerConcurrently { - private static final Logger LOG = LoggerFactory.getLogger(DeFiBusMessageListenerConcurrently.class); - - @Override - public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) { - - List nonTimeOutMsgs = new ArrayList(); - try { - for (MessageExt msgExt : msgs) { - if (LOG.isDebugEnabled()) { - LOG.debug("begin to receive message: " + msgExt); - } - - long ttl = 0; - try { - ttl = Long.valueOf(msgExt.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL)); - } catch (NumberFormatException e) { - LOG.warn("receive illegal message, ttl format err, ack immediately." + msgExt.toString()); - continue; - } - - long storeTimestamp = msgExt.getStoreTimestamp(); - long leaveTime = -1; - if (msgExt.getProperties().get(DeFiBusMessageConst.LEAVE_TIME) != null) { - leaveTime = Long.valueOf(msgExt.getProperties().get(DeFiBusMessageConst.LEAVE_TIME)); - } - - double elapseTime = 0L; - if (leaveTime != -1) { - elapseTime = leaveTime - storeTimestamp; - } - if (elapseTime >= ttl) { - if (LOG.isWarnEnabled()) { - LOG.warn("discard timeout message : " + msgExt.toString()); - } - continue; - } - - nonTimeOutMsgs.add(msgExt); - } - - if (nonTimeOutMsgs.size() == 0) { - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - ConsumeConcurrentlyStatus status = null; - status = handleMessage(nonTimeOutMsgs, context); - - return status; - } catch (Throwable e) { - LOG.warn("handleMessage fail", e); - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - - } - - public abstract ConsumeConcurrentlyStatus handleMessage(List msgs, ConsumeConcurrentlyContext context); - -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrentlyOnce.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrentlyOnce.java deleted file mode 100644 index de5e786219..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrentlyOnce.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.consumer; - -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.message.DeFiBusMessageConst; -import java.util.ArrayList; -import java.util.List; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; -import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; -import org.apache.rocketmq.common.message.MessageExt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class DeFiBusMessageListenerConcurrentlyOnce implements MessageListenerConcurrently { - private static final Logger LOG = LoggerFactory.getLogger(DeFiBusMessageListenerConcurrentlyOnce.class); - - @Override - public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) { - List nonTimeOutMsgs = new ArrayList(); - for (MessageExt msgExt : msgs) { - if (LOG.isDebugEnabled()) { - LOG.debug("begin to receive message: " + msgExt); - } - - long ttl = 0; - try { - ttl = Long.valueOf(msgExt.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL)); - } catch (NumberFormatException e) { - LOG.warn("receive illegal message, ttl format err, ack immediately." + msgExt.toString()); - continue; - } - - long storeTimestamp = msgExt.getStoreTimestamp(); - long leaveTime = -1; - if (msgExt.getProperties().get(DeFiBusMessageConst.LEAVE_TIME) != null) { - leaveTime = Long.valueOf(msgExt.getProperties().get(DeFiBusMessageConst.LEAVE_TIME)); - } - - double elapseTime = 0L; - if (leaveTime != -1) { - elapseTime = leaveTime - storeTimestamp; - } - if (elapseTime >= ttl) { - if (LOG.isWarnEnabled()) { - LOG.warn("discard timeout message : " + msgExt.toString()); - } - continue; - } - nonTimeOutMsgs.add(msgExt); - } - - if (nonTimeOutMsgs.size() == 0) { - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - - ConsumeConcurrentlyStatus status = null; - try { - for (MessageExt msg : nonTimeOutMsgs) { - status = handleMessage(msg, context); - } - } catch (Throwable e) { - LOG.info("handleMessage fail", e); - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - return status; - } - - public abstract ConsumeConcurrentlyStatus handleMessage(MessageExt msg, ConsumeConcurrentlyContext context); - -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrentlyWithReply.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrentlyWithReply.java deleted file mode 100644 index 051f501a01..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusMessageListenerConcurrentlyWithReply.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.consumer; - -import cn.webank.defibus.client.common.DeFiBusClientUtil; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.message.DeFiBusMessageConst; -import cn.webank.defibus.producer.DeFiBusProducer; -import java.util.ArrayList; -import java.util.List; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; -import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageExt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class DeFiBusMessageListenerConcurrentlyWithReply implements MessageListenerConcurrently { - private static final Logger LOG = LoggerFactory.getLogger(DeFiBusMessageListenerConcurrentlyWithReply.class); - private DeFiBusProducer deFiBusProducer; - - public DeFiBusMessageListenerConcurrentlyWithReply(DeFiBusProducer deFiBusProducer) { - this.deFiBusProducer = deFiBusProducer; - if (!deFiBusProducer.isStart()) { - try { - deFiBusProducer.start(); - } catch (MQClientException e) { - e.printStackTrace(); - } - } - } - - @Override - public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) { - List nonTimeOutMsgs = new ArrayList(); - for (MessageExt msgExt : msgs) { - if (LOG.isDebugEnabled()) { - LOG.debug("begin to receive message: " + msgExt); - } - - long ttl = 0; - try { - ttl = Long.valueOf(msgExt.getUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL)); - } catch (NumberFormatException e) { - LOG.warn("receive illegal message, ttl format err, ack immediately." + msgExt.toString()); - continue; - } - - long storeTimestamp = msgExt.getStoreTimestamp(); - long leaveTime = -1; - if (msgExt.getProperties().get(DeFiBusMessageConst.LEAVE_TIME) != null) { - leaveTime = Long.valueOf(msgExt.getProperties().get(DeFiBusMessageConst.LEAVE_TIME)); - } - - double elapseTime = 0L; - if (leaveTime != -1) { - elapseTime = leaveTime - storeTimestamp; - } - if (elapseTime >= ttl) { - if (LOG.isWarnEnabled()) { - LOG.warn("discard timeout message : " + msgExt.toString()); - } - continue; - } - nonTimeOutMsgs.add(msgExt); - } - - if (nonTimeOutMsgs.size() == 0) { - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - - ConsumeConcurrentlyStatus status = ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - try { - for (MessageExt msg : nonTimeOutMsgs) { - String replyContent = handleMessage(msg, context); - Message replyMsg = DeFiBusClientUtil.createReplyMessage(msg, replyContent.getBytes()); - deFiBusProducer.reply(replyMsg, null); - } - } catch (Throwable e) { - LOG.info("handleMessage fail", e); - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - return status; - } - - public abstract String handleMessage(MessageExt msg, ConsumeConcurrentlyContext context); - -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusPushConsumer.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusPushConsumer.java deleted file mode 100644 index 1b36bf324a..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/consumer/DeFiBusPushConsumer.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.consumer; - -import cn.webank.defibus.client.DeFiBusClientManager; -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.client.impl.DeFiBusClientAPIImpl; -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.client.impl.hook.DeFiBusClientHookFactory; -import cn.webank.defibus.client.impl.rebalance.AllocateMessageQueueByIDC; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.DeFiBusVersion; -import java.util.Map; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.rocketmq.client.consumer.AllocateMessageQueueStrategy; -import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; -import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.client.impl.consumer.ProcessQueue; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.remoting.RPCHook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusPushConsumer { - protected static final Logger LOG = LoggerFactory.getLogger(DeFiBusPushConsumer.class); - - private DefaultMQPushConsumer defaultMQPushConsumer; - private DeFiBusClientInstance deFiBusClientInstance; - private AllocateMessageQueueStrategy allocateMessageQueueStrategy; - private RPCHook rpcHook; - private DeFiBusClientConfig deFiBusClientConfig; - private AtomicBoolean isStart = new AtomicBoolean(false); - - static { - System.setProperty("rocketmq.client.log.loadconfig", "false"); - } - - public DeFiBusPushConsumer() { - this(new DeFiBusClientConfig()); - } - - public DeFiBusPushConsumer(final DeFiBusClientConfig deFiBusClientConfig) { - this.deFiBusClientConfig = deFiBusClientConfig; - RPCHook rpcHookForAuth = DeFiBusClientHookFactory.createRPCHook(deFiBusClientConfig.getRpcHook()); - this.rpcHook = rpcHookForAuth; - this.allocateMessageQueueStrategy = new AllocateMessageQueueByIDC(); - - defaultMQPushConsumer = new DefaultMQPushConsumer(deFiBusClientConfig.getConsumerGroup(), rpcHook, allocateMessageQueueStrategy); - defaultMQPushConsumer.setVipChannelEnabled(false); - } - - /** - * start the consumer which will begin to connect with the broker and then message can be consumed. - * If the consumer has been already started, nothing will happen. - * @throws MQClientException - */ - public void start() throws MQClientException { - if (isStart.compareAndSet(false, true)) { - - if (deFiBusClientConfig.getNamesrvAddr() != null) { - this.defaultMQPushConsumer.setNamesrvAddr(deFiBusClientConfig.getNamesrvAddr()); - } - this.defaultMQPushConsumer.changeInstanceNameToPID(); - - String instanceName = this.defaultMQPushConsumer.getInstanceName() + DeFiBusConstant.INSTANCE_NAME_SEPERATER + DeFiBusVersion.getVersionDesc(deFiBusClientConfig.getVersion()); - if (deFiBusClientConfig.getClusterPrefix() != null) { - instanceName = instanceName + DeFiBusConstant.INSTANCE_NAME_SEPERATER + deFiBusClientConfig.getClusterPrefix(); - } - this.defaultMQPushConsumer.setInstanceName(instanceName); - defaultMQPushConsumer.setConsumeMessageBatchMaxSize(deFiBusClientConfig.getConsumeMessageBatchMaxSize()); - defaultMQPushConsumer.setPullInterval(deFiBusClientConfig.getPullInterval()); - defaultMQPushConsumer.setPullBatchSize(deFiBusClientConfig.getPullBatchSize()); - defaultMQPushConsumer.setConsumeConcurrentlyMaxSpan(deFiBusClientConfig.getConsumeConcurrentlyMaxSpan()); - defaultMQPushConsumer.setPollNameServerInterval(deFiBusClientConfig.getPollNameServerInterval()); - defaultMQPushConsumer.setPullThresholdForQueue(deFiBusClientConfig.getAckWindowSize()); - defaultMQPushConsumer.setConsumeTimeout(deFiBusClientConfig.getConsumeTimeout()); - defaultMQPushConsumer.setConsumeThreadMax(deFiBusClientConfig.getThreadPoolMaxSize()); - defaultMQPushConsumer.setConsumeThreadMin(deFiBusClientConfig.getThreadPoolCoreSize()); - defaultMQPushConsumer.setPersistConsumerOffsetInterval(deFiBusClientConfig.getAckTime()); - defaultMQPushConsumer.setMaxReconsumeTimes(deFiBusClientConfig.getMaxReconsumeTimes()); - defaultMQPushConsumer.setHeartbeatBrokerInterval(deFiBusClientConfig.getHeartbeatBrokerInterval()); - - deFiBusClientInstance = DeFiBusClientManager.getInstance().getAndCreateDeFiBusClientInstance(defaultMQPushConsumer, rpcHook); - - deFiBusClientInstance.start(); - - if (allocateMessageQueueStrategy instanceof AllocateMessageQueueByIDC) { - ((AllocateMessageQueueByIDC) allocateMessageQueueStrategy).setMqClientInstance(deFiBusClientInstance); - } - - if (deFiBusClientConfig.getWsAddr() != null) { - DeFiBusClientAPIImpl deFiClientAPI = (DeFiBusClientAPIImpl) deFiBusClientInstance.getMQClientAPIImpl(); - deFiClientAPI.setWsAddr(deFiBusClientConfig.getWsAddr()); - deFiClientAPI.fetchNameServerAddr(); - } - - this.defaultMQPushConsumer.start(); - final String retryTopic = MixAll.getRetryTopic(this.defaultMQPushConsumer.getConsumerGroup()); - defaultMQPushConsumer.unsubscribe(retryTopic); - defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getmQClientFactory().updateTopicRouteInfoFromNameServer(); - - LOG.info("DeFiBusPushConsumer start ok"); - } else { - LOG.warn("DeFiBusPushConsumer already started"); - } - } - - public void shutdown() { - if (isStart.compareAndSet(true, false)) { - this.defaultMQPushConsumer.shutdown(); - LOG.info("DeFiBusPushConsumer [{}] shutdown", defaultMQPushConsumer.getInstanceName()); - } else { - LOG.info("DeFiBusPushConsumer [{}] already shutdown", defaultMQPushConsumer.getInstanceName()); - } - } - - /** - * register a message listener which specify the callback message how message should be consumed. The message will be consumed in a standalone thread pool. - * @param messageListener - */ - public void registerMessageListener(MessageListenerConcurrently messageListener) { - this.defaultMQPushConsumer.registerMessageListener(messageListener); - } - - /** - * subscirbe a topic so that the consumer can consume message from. Typically, you should subscribe topic first then start the consumer - * @param topic topic name that the consumer needs to subscribe - * @throws MQClientException - */ - public void subscribe(String topic) throws MQClientException { - this.defaultMQPushConsumer.subscribe(topic, "*"); - LOG.info("add subscription [{}] to consumer", topic); - } - - public void unsubscribe(String topic) { - unsubscribe(topic, true); - } - - public void unsubscribe(String topic, boolean isNeedSendHeartbeat) { - LOG.info("remove subscription [{}] from consumer", topic); - ConcurrentMap processQueueTable = - this.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getRebalanceImpl().getProcessQueueTable(); - - for (Map.Entry entry : processQueueTable.entrySet()) { - MessageQueue messageQueue = entry.getKey(); - ProcessQueue pq = entry.getValue(); - if (messageQueue.getTopic().equals(topic)) { - pq.setDropped(true); - } - } - this.defaultMQPushConsumer.unsubscribe(topic); - if (isStart.get()) { - if (isNeedSendHeartbeat) { - sendHeartBeatToBrokersWhenSubscribeChange(); - } - } - } - - public DefaultMQPushConsumer getDefaultMQPushConsumer() { - return defaultMQPushConsumer; - } - - public DeFiBusClientInstance getDeFiBusClientInstance() { - return deFiBusClientInstance; - } - - public String getNamesrvAddr() { - return this.defaultMQPushConsumer.getNamesrvAddr(); - } - - public void setNamesrvAddr(String namesrvAddr) { - this.defaultMQPushConsumer.setNamesrvAddr(namesrvAddr); - } - - public void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) { - this.defaultMQPushConsumer.setConsumeFromWhere(consumeFromWhere); - } - - private void sendHeartBeatToBrokersWhenSubscribeChange() { - this.defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getmQClientFactory().sendHeartbeatToAllBrokerWithLock(); - } -} diff --git a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/producer/DeFiBusProducer.java b/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/producer/DeFiBusProducer.java deleted file mode 100644 index 80dc1fcafb..0000000000 --- a/eventmesh-store/defibus-client/src/main/java/cn/webank/defibus/producer/DeFiBusProducer.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.producer; - -import cn.webank.defibus.client.DeFiBusClientManager; -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.client.impl.DeFiBusClientAPIImpl; -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.client.impl.hook.DeFiBusClientHookFactory; -import cn.webank.defibus.client.impl.producer.DeFiBusProducerImpl; -import cn.webank.defibus.client.impl.producer.RRCallback; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.common.DeFiBusVersion; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.client.producer.DefaultMQProducer; -import org.apache.rocketmq.client.producer.SendCallback; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageClientIDSetter; -import org.apache.rocketmq.remoting.RPCHook; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeFiBusProducer { - private static final Logger LOG = LoggerFactory.getLogger(DeFiBusProducer.class); - private DefaultMQProducer defaultMQProducer; - private DeFiBusClientInstance deFiBusClientInstance; - private RPCHook rpcHook; - private AtomicBoolean isStart = new AtomicBoolean(false); - private DeFiBusProducerImpl deFiBusProducerImpl; - private DeFiBusClientConfig deFiBusClientConfig; - - static { - System.setProperty("rocketmq.client.log.loadconfig", "false"); - } - - public DeFiBusProducer() { - this(new DeFiBusClientConfig()); - } - - public DeFiBusProducer(DeFiBusClientConfig deFiBusClientConfig) { - RPCHook rpcHookForAuth = DeFiBusClientHookFactory.createRPCHook(deFiBusClientConfig.getRpcHook()); - defaultMQProducer = new DefaultMQProducer(deFiBusClientConfig.getProducerGroup(), rpcHookForAuth); - defaultMQProducer.setVipChannelEnabled(false); - this.rpcHook = rpcHookForAuth; - this.deFiBusClientConfig = deFiBusClientConfig; - } - - /** - * start the producer which will begin to connect with the broker. A producer MUST call this method before sending any message - * If the producer has been already started, nothing will happen. - * @throws MQClientException - */ - public void start() throws MQClientException { - if (isStart.compareAndSet(false, true)) { - try { - System.setProperty("com.rocketmq.remoting.clientAsyncSemaphoreValue", String.valueOf(deFiBusClientConfig.getPubWindowSize())); - - if (deFiBusClientConfig.getNamesrvAddr() != null) { - this.defaultMQProducer.setNamesrvAddr(deFiBusClientConfig.getNamesrvAddr()); - } - if (!this.defaultMQProducer.getProducerGroup().equals(MixAll.CLIENT_INNER_PRODUCER_GROUP)) { - this.defaultMQProducer.changeInstanceNameToPID(); - } - - String instanceName = this.defaultMQProducer.getInstanceName() + DeFiBusConstant.INSTANCE_NAME_SEPERATER - + DeFiBusVersion.getVersionDesc(this.deFiBusClientConfig.getVersion()); - - if (deFiBusClientConfig.getClusterPrefix() != null) { - instanceName = instanceName + DeFiBusConstant.INSTANCE_NAME_SEPERATER + deFiBusClientConfig.getClusterPrefix(); - } - this.defaultMQProducer.setInstanceName(instanceName); - - this.defaultMQProducer.setPollNameServerInterval(deFiBusClientConfig.getPollNameServerInterval()); - this.defaultMQProducer.setRetryTimesWhenSendAsyncFailed(deFiBusClientConfig.getRetryTimesWhenSendAsyncFailed()); - this.defaultMQProducer.setRetryTimesWhenSendFailed(deFiBusClientConfig.getRetryTimesWhenSendFailed()); - this.defaultMQProducer.setHeartbeatBrokerInterval(deFiBusClientConfig.getHeartbeatBrokerInterval()); - this.defaultMQProducer.setPersistConsumerOffsetInterval(deFiBusClientConfig.getAckTime()); - deFiBusClientInstance - = DeFiBusClientManager.getInstance().getAndCreateDeFiBusClientInstance(defaultMQProducer, rpcHook); - - if (deFiBusClientConfig.getWsAddr() != null) { - DeFiBusClientAPIImpl deFiClientAPI = (DeFiBusClientAPIImpl) deFiBusClientInstance.getMQClientAPIImpl(); - deFiClientAPI.setWsAddr(deFiBusClientConfig.getWsAddr()); - } - - deFiBusProducerImpl = new DeFiBusProducerImpl(this, deFiBusClientConfig, deFiBusClientInstance); - this.defaultMQProducer.start(); - deFiBusProducerImpl.startUpdateClusterInfoTask(); - } catch (MQClientException e) { - LOG.warn("DeFiBusProducer start client failed {}", e.getMessage()); - isStart.set(false); - throw e; - } catch (Exception e) { - LOG.warn("DeFiBusProducer start client failed", e); - isStart.set(false); - throw new MQClientException("DeFiBusProducer start client failed", e); - } - - MessageClientIDSetter.createUniqID(); - - LOG.info("DeFiBusProducer start ok"); - } else { - LOG.warn("DeFiBusProducer already started"); - } - } - - public void shutdown() { - if (isStart.compareAndSet(true, false)) { - this.defaultMQProducer.shutdown(); - LOG.info("DeFiBusProducer [{}] shutdown", defaultMQProducer.getInstanceName()); - } else { - LOG.info("DeFiBusProducer [{}] already shutdown", defaultMQProducer.getInstanceName()); - } - } - - public DefaultMQProducer getDefaultMQProducer() { - return defaultMQProducer; - } - - //sync Request-Response interface - public Message request(Message msg, long timeout) - throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - return deFiBusProducerImpl.request(msg, timeout); - } - - //async Request-Response interface - public void request(Message msg, RRCallback rrCallback, long timeout) - throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - deFiBusProducerImpl.request(msg, null, rrCallback, timeout); - } - - public void request(Message msg, SendCallback sendCallback, RRCallback rrCallback, long timeout) - throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - deFiBusProducerImpl.request(msg, sendCallback, rrCallback, timeout); - } - - public void reply(Message replyMsg, SendCallback sendCallback) - throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - deFiBusProducerImpl.reply(replyMsg, sendCallback); - } - - //async publish with callback - public void publish(Message msg, SendCallback sendCallback) - throws MQClientException, RemotingException, InterruptedException { - this.deFiBusProducerImpl.publish(msg, sendCallback); - } - - //async public - public void publish(Message msg) throws MQClientException, RemotingException, InterruptedException { - this.deFiBusProducerImpl.publish(msg); - } - - public void publish( - Collection msgs) throws MQClientException, RemotingException, MQBrokerException, InterruptedException { - this.deFiBusProducerImpl.publish(msgs); - } - - public String getNamesrvAddr() { - return defaultMQProducer.getNamesrvAddr(); - } - - public void setNamesrvAddr(String namesrvAddr) { - defaultMQProducer.setNamesrvAddr(namesrvAddr); - } - - public boolean isStart() { - return isStart.get(); - } - - public DeFiBusClientConfig getDeFiBusClientConfig() { - return deFiBusClientConfig; - } - - public void updateSendNearbyMapping(Map newMapping) { - this.deFiBusProducerImpl.updateSendNearbyMapping(newMapping); - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/common/DeFiBusCLientUtilTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/common/DeFiBusCLientUtilTest.java deleted file mode 100644 index 9d20241491..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/common/DeFiBusCLientUtilTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.common; - -import cn.webank.defibus.common.DeFiBusConstant; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageExt; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DeFiBusCLientUtilTest { - @Test - public void createReplyMessage_Success() { - MessageExt msg = new MessageExt(); - msg.setTopic("Test"); - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_CLUSTER, "ClusterName"); - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO, "reply_to"); - msg.putUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID, "w/request_id"); - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_BROKER, "BrokerName"); - - byte[] replyContent = "reply content".getBytes(); - Message replyMsg = DeFiBusClientUtil.createReplyMessage(msg, replyContent); - - assertThat(replyMsg).isNotNull(); - assertThat(replyContent).isEqualTo(replyMsg.getBody()); - } - - @Test - public void createReplyMessage_Fail() { - MessageExt msg = new MessageExt(); - msg.setTopic("Test"); - msg.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO, "reply_to"); - msg.putUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID, "w/request_id"); - - byte[] replyContent = "reply content".getBytes(); - Message replyMsg = DeFiBusClientUtil.createReplyMessage(msg, replyContent); - - assertThat(replyMsg).isNull(); - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusMessageListenerConcurrentlyOnceTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusMessageListenerConcurrentlyOnceTest.java deleted file mode 100644 index 39b1200002..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusMessageListenerConcurrentlyOnceTest.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.consumer; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.client.impl.DeFiBusClientAPIImpl; -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.consumer.DeFiBusMessageListenerConcurrentlyOnce; -import cn.webank.defibus.consumer.DeFiBusPushConsumer; -import java.io.ByteArrayOutputStream; -import java.lang.reflect.Field; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.rocketmq.client.consumer.PullCallback; -import org.apache.rocketmq.client.consumer.PullResult; -import org.apache.rocketmq.client.consumer.PullStatus; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; -import org.apache.rocketmq.client.impl.CommunicationMode; -import org.apache.rocketmq.client.impl.FindBrokerResult; -import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl; -import org.apache.rocketmq.client.impl.consumer.ProcessQueue; -import org.apache.rocketmq.client.impl.consumer.PullAPIWrapper; -import org.apache.rocketmq.client.impl.consumer.PullMessageService; -import org.apache.rocketmq.client.impl.consumer.PullRequest; -import org.apache.rocketmq.client.impl.consumer.PullResultExt; -import org.apache.rocketmq.client.impl.consumer.RebalancePushImpl; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.common.message.MessageClientExt; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.header.PullMessageRequestHeader; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiBusMessageListenerConcurrentlyOnceTest { - private String consumerGroup; - private String topic = "FooBar"; - private String brokerName = "BrokerA"; - private DeFiBusClientInstance defiBusClientFactory; - private int totalMsg = 5; - private AtomicInteger consumeCount = new AtomicInteger(0); - - @Mock - private DeFiBusClientAPIImpl deFiBusClientAPIImpl; - - private PullAPIWrapper pullAPIWrapper; - private RebalancePushImpl rebalancePushImpl; - private DeFiBusPushConsumer pushConsumer; - - private final CountDownLatch countDownLatch = new CountDownLatch(totalMsg); - - @Before - public void init() throws Exception { - DeFiBusClientConfig clientConfig = new DeFiBusClientConfig(); - consumerGroup = "FooBarGroup" + System.currentTimeMillis(); - clientConfig.setConsumerGroup(consumerGroup); - pushConsumer = new DeFiBusPushConsumer(clientConfig); - pushConsumer.setNamesrvAddr("127.0.0.1:9876"); - pushConsumer.getDefaultMQPushConsumer().setPullInterval(60 * 1000); - - pushConsumer.registerMessageListener(new DeFiBusMessageListenerConcurrentlyOnce() { - @Override - public ConsumeConcurrentlyStatus handleMessage(MessageExt msg, ConsumeConcurrentlyContext context) { - countDownLatch.countDown(); - consumeCount.getAndIncrement(); - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - }); - - DefaultMQPushConsumerImpl pushConsumerImpl = pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl(); - rebalancePushImpl = spy(new RebalancePushImpl(pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl())); - Field field = DefaultMQPushConsumerImpl.class.getDeclaredField("rebalanceImpl"); - field.setAccessible(true); - field.set(pushConsumerImpl, rebalancePushImpl); - pushConsumer.subscribe(topic); - pushConsumer.start(); - - defiBusClientFactory = spy(pushConsumer.getDeFiBusClientInstance()); - field = DefaultMQPushConsumerImpl.class.getDeclaredField("mQClientFactory"); - field.setAccessible(true); - field.set(pushConsumerImpl, defiBusClientFactory); - - field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl"); - field.setAccessible(true); - field.set(defiBusClientFactory, deFiBusClientAPIImpl); - - pullAPIWrapper = spy(new PullAPIWrapper(defiBusClientFactory, consumerGroup, false)); - field = DefaultMQPushConsumerImpl.class.getDeclaredField("pullAPIWrapper"); - field.setAccessible(true); - field.set(pushConsumerImpl, pullAPIWrapper); - - pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().getRebalanceImpl().setmQClientFactory(defiBusClientFactory); - defiBusClientFactory.registerConsumer(consumerGroup, pushConsumerImpl); - - when(defiBusClientFactory.getMQClientAPIImpl().pullMessage(anyString(), any(PullMessageRequestHeader.class), - anyLong(), any(CommunicationMode.class), nullable(PullCallback.class))) - .thenAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock mock) throws Throwable { - PullMessageRequestHeader requestHeader = mock.getArgument(1); - PullResult pullResult = createPullResult(requestHeader, PullStatus.FOUND, createMessageList(totalMsg)); - ((PullCallback) mock.getArgument(4)).onSuccess(pullResult); - return pullResult; - } - }) - .thenAnswer(new Answer() { - @Override public Object answer(InvocationOnMock invocation) throws Throwable { - PullMessageRequestHeader requestHeader = invocation.getArgument(1); - PullResult pullResult = createPullResult(requestHeader, PullStatus.NO_NEW_MSG, new ArrayList()); - ((PullCallback) invocation.getArgument(4)).onSuccess(pullResult); - return pullResult; - } - }); - - doReturn(new FindBrokerResult("127.0.0.1:10912", false)).when(defiBusClientFactory).findBrokerAddressInSubscribe(anyString(), anyLong(), anyBoolean()); - Set messageQueueSet = new HashSet(); - messageQueueSet.add(createPullRequest().getMessageQueue()); - pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().updateTopicSubscribeInfo(topic, messageQueueSet); - } - - @Test - public void testPullMessage_ConsumeSuccess() throws Exception { - PullMessageService pullMessageService = defiBusClientFactory.getPullMessageService(); - pullMessageService.executePullRequestImmediately(createPullRequest()); - countDownLatch.await(5000, TimeUnit.MILLISECONDS); - - Thread.sleep(2000); - assertThat(consumeCount.get()).isEqualTo(totalMsg); - } - - @After - public void terminate() { - pushConsumer.shutdown(); - } - - private PullRequest createPullRequest() { - PullRequest pullRequest = new PullRequest(); - pullRequest.setConsumerGroup(consumerGroup); - pullRequest.setNextOffset(1024); - - MessageQueue messageQueue = new MessageQueue(); - messageQueue.setBrokerName(brokerName); - messageQueue.setQueueId(0); - messageQueue.setTopic(topic); - pullRequest.setMessageQueue(messageQueue); - ProcessQueue processQueue = new ProcessQueue(); - processQueue.setLocked(true); - processQueue.setLastLockTimestamp(System.currentTimeMillis()); - pullRequest.setProcessQueue(processQueue); - - return pullRequest; - } - - private PullResultExt createPullResult(PullMessageRequestHeader requestHeader, PullStatus pullStatus, - List messageExtList) throws Exception { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - for (MessageExt messageExt : messageExtList) { - outputStream.write(MessageDecoder.encode(messageExt, false)); - } - return new PullResultExt(pullStatus, requestHeader.getQueueOffset() + messageExtList.size(), 123, 2048, messageExtList, 0, outputStream.toByteArray()); - } - - private ArrayList createMessageList(int size) { - ArrayList list = new ArrayList<>(); - for (int i = 0; i < size; i++) { - MessageClientExt messageClientExt = new MessageClientExt(); - messageClientExt.setTopic(topic); - messageClientExt.setQueueId(0); - messageClientExt.setMsgId("123"); - messageClientExt.setBody(new byte[] {'a'}); - messageClientExt.setOffsetMsgId("234"); - messageClientExt.setBornHost(new InetSocketAddress(8080)); - messageClientExt.setStoreHost(new InetSocketAddress(8080)); - messageClientExt.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL, "3000"); - list.add(messageClientExt); - } - return list; - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusMessageListenerConcurrentlyTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusMessageListenerConcurrentlyTest.java deleted file mode 100644 index b8dcf2a092..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusMessageListenerConcurrentlyTest.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.consumer; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.client.impl.DeFiBusClientAPIImpl; -import cn.webank.defibus.client.impl.factory.DeFiBusClientInstance; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.consumer.DeFiBusMessageListenerConcurrently; -import cn.webank.defibus.consumer.DeFiBusPushConsumer; -import java.io.ByteArrayOutputStream; -import java.lang.reflect.Field; -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import org.apache.rocketmq.client.consumer.PullCallback; -import org.apache.rocketmq.client.consumer.PullResult; -import org.apache.rocketmq.client.consumer.PullStatus; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; -import org.apache.rocketmq.client.impl.CommunicationMode; -import org.apache.rocketmq.client.impl.FindBrokerResult; -import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl; -import org.apache.rocketmq.client.impl.consumer.ProcessQueue; -import org.apache.rocketmq.client.impl.consumer.PullAPIWrapper; -import org.apache.rocketmq.client.impl.consumer.PullMessageService; -import org.apache.rocketmq.client.impl.consumer.PullRequest; -import org.apache.rocketmq.client.impl.consumer.PullResultExt; -import org.apache.rocketmq.client.impl.consumer.RebalancePushImpl; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.client.stat.ConsumerStatsManager; -import org.apache.rocketmq.common.message.MessageClientExt; -import org.apache.rocketmq.common.message.MessageDecoder; -import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.header.PullMessageRequestHeader; -import org.apache.rocketmq.common.stats.StatsItem; -import org.apache.rocketmq.common.stats.StatsItemSet; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiBusMessageListenerConcurrentlyTest { - private String consumerGroup; - private String topic = "FooBar"; - private String brokerName = "BrokerA"; - private DeFiBusClientInstance defiBusClientFactory; - - @Mock - private DeFiBusClientAPIImpl deFiBusClientAPIImpl; - - private PullAPIWrapper pullAPIWrapper; - private RebalancePushImpl rebalancePushImpl; - private DeFiBusPushConsumer pushConsumer; - - private final CountDownLatch countDownLatch = new CountDownLatch(1); - private final MessageExt[] messageExts = new MessageExt[1]; - - @Before - public void init() throws Exception { - DeFiBusClientConfig clientConfig = new DeFiBusClientConfig(); - consumerGroup = "FooBarGroup" + System.currentTimeMillis(); - clientConfig.setConsumerGroup(consumerGroup); - pushConsumer = new DeFiBusPushConsumer(clientConfig); - pushConsumer.setNamesrvAddr("127.0.0.1:9876"); - pushConsumer.getDefaultMQPushConsumer().setPullInterval(60 * 1000); - - pushConsumer.registerMessageListener(new DeFiBusMessageListenerConcurrently() { - @Override - public ConsumeConcurrentlyStatus handleMessage(List msgs, ConsumeConcurrentlyContext context) { - messageExts[0] = msgs.get(0); - countDownLatch.countDown(); - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - }); - - DefaultMQPushConsumerImpl pushConsumerImpl = pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl(); - rebalancePushImpl = spy(new RebalancePushImpl(pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl())); - Field field = DefaultMQPushConsumerImpl.class.getDeclaredField("rebalanceImpl"); - field.setAccessible(true); - field.set(pushConsumerImpl, rebalancePushImpl); - pushConsumer.subscribe(topic); - pushConsumer.start(); - - defiBusClientFactory = spy(pushConsumer.getDeFiBusClientInstance()); - field = DefaultMQPushConsumerImpl.class.getDeclaredField("mQClientFactory"); - field.setAccessible(true); - field.set(pushConsumerImpl, defiBusClientFactory); - - field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl"); - field.setAccessible(true); - field.set(defiBusClientFactory, deFiBusClientAPIImpl); - - pullAPIWrapper = spy(new PullAPIWrapper(defiBusClientFactory, consumerGroup, false)); - field = DefaultMQPushConsumerImpl.class.getDeclaredField("pullAPIWrapper"); - field.setAccessible(true); - field.set(pushConsumerImpl, pullAPIWrapper); - - pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().getRebalanceImpl().setmQClientFactory(defiBusClientFactory); - defiBusClientFactory.registerConsumer(consumerGroup, pushConsumerImpl); - - when(defiBusClientFactory.getMQClientAPIImpl().pullMessage(anyString(), any(PullMessageRequestHeader.class), - anyLong(), any(CommunicationMode.class), nullable(PullCallback.class))) - .thenAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock mock) throws Throwable { - PullMessageRequestHeader requestHeader = mock.getArgument(1); - MessageClientExt messageClientExt = new MessageClientExt(); - messageClientExt.setTopic(topic); - messageClientExt.setQueueId(0); - messageClientExt.setMsgId("123"); - messageClientExt.setBody(new byte[] {'a'}); - messageClientExt.setOffsetMsgId("234"); - messageClientExt.setBornHost(new InetSocketAddress(8080)); - messageClientExt.setStoreHost(new InetSocketAddress(8080)); - messageClientExt.putUserProperty(DeFiBusConstant.PROPERTY_MESSAGE_TTL, "3000"); - PullResult pullResult = createPullResult(requestHeader, PullStatus.FOUND, Collections.singletonList(messageClientExt)); - ((PullCallback) mock.getArgument(4)).onSuccess(pullResult); - return pullResult; - } - }); - - doReturn(new FindBrokerResult("127.0.0.1:10912", false)).when(defiBusClientFactory).findBrokerAddressInSubscribe(anyString(), anyLong(), anyBoolean()); - Set messageQueueSet = new HashSet(); - messageQueueSet.add(createPullRequest().getMessageQueue()); - pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().updateTopicSubscribeInfo(topic, messageQueueSet); - } - - @Test - public void testPullMessage_ConsumeSuccess() throws Exception { - PullMessageService pullMessageService = defiBusClientFactory.getPullMessageService(); - pullMessageService.executePullRequestImmediately(createPullRequest()); - countDownLatch.await(); - - Thread.sleep(2000); - - ConsumerStatsManager mgr = pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().getConsumerStatsManager(); - - Field statItmeSetField = mgr.getClass().getDeclaredField("topicAndGroupConsumeOKTPS"); - statItmeSetField.setAccessible(true); - - StatsItemSet itemSet = (StatsItemSet) statItmeSetField.get(mgr); - StatsItem item = itemSet.getAndCreateStatsItem(topic + "@" + pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().groupName()); - - assertThat(item.getValue().get()).isGreaterThan(0L); - assertThat(messageExts[0].getTopic()).isEqualTo(topic); - assertThat(messageExts[0].getBody()).isEqualTo(new byte[] {'a'}); - } - - @After - public void terminate() { - pushConsumer.shutdown(); - } - - private PullRequest createPullRequest() { - PullRequest pullRequest = new PullRequest(); - pullRequest.setConsumerGroup(consumerGroup); - pullRequest.setNextOffset(1024); - - MessageQueue messageQueue = new MessageQueue(); - messageQueue.setBrokerName(brokerName); - messageQueue.setQueueId(0); - messageQueue.setTopic(topic); - pullRequest.setMessageQueue(messageQueue); - ProcessQueue processQueue = new ProcessQueue(); - processQueue.setLocked(true); - processQueue.setLastLockTimestamp(System.currentTimeMillis()); - pullRequest.setProcessQueue(processQueue); - - return pullRequest; - } - - private PullResultExt createPullResult(PullMessageRequestHeader requestHeader, PullStatus pullStatus, - List messageExtList) throws Exception { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - for (MessageExt messageExt : messageExtList) { - outputStream.write(MessageDecoder.encode(messageExt, false)); - } - return new PullResultExt(pullStatus, requestHeader.getQueueOffset() + messageExtList.size(), 123, 2048, messageExtList, 0, outputStream.toByteArray()); - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusPushConsumerTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusPushConsumerTest.java deleted file mode 100644 index 38d5c93b44..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/consumer/DeFiBusPushConsumerTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.consumer; - -import cn.webank.defibus.consumer.DeFiBusPushConsumer; -import org.apache.rocketmq.client.exception.MQClientException; -import org.junit.Test; - -import static junit.framework.TestCase.assertFalse; -import static org.junit.Assert.assertTrue; - -public class DeFiBusPushConsumerTest { - private String topic = "FooBar"; - - @Test - public void test_unsubscribe() throws MQClientException { - DeFiBusPushConsumer pushConsumer = new DeFiBusPushConsumer(); - pushConsumer.subscribe(topic); - assertTrue(pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().getRebalanceImpl().getSubscriptionInner().containsKey(topic)); - - pushConsumer.unsubscribe(topic); - assertFalse(pushConsumer.getDefaultMQPushConsumer().getDefaultMQPushConsumerImpl().getRebalanceImpl().getSubscriptionInner().containsKey(topic)); - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/DeFiBusClientAPIImplTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/DeFiBusClientAPIImplTest.java deleted file mode 100644 index ae05cd018d..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/DeFiBusClientAPIImplTest.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import org.apache.rocketmq.client.ClientConfig; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.hook.SendMessageContext; -import org.apache.rocketmq.client.impl.CommunicationMode; -import org.apache.rocketmq.client.impl.MQClientAPIImpl; -import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; -import org.apache.rocketmq.client.producer.DefaultMQProducer; -import org.apache.rocketmq.client.producer.SendCallback; -import org.apache.rocketmq.client.producer.SendResult; -import org.apache.rocketmq.client.producer.SendStatus; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageConst; -import org.apache.rocketmq.common.protocol.ResponseCode; -import org.apache.rocketmq.common.protocol.header.GetConsumerListByGroupResponseBody; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader; -import org.apache.rocketmq.remoting.InvokeCallback; -import org.apache.rocketmq.remoting.RemotingClient; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.apache.rocketmq.remoting.netty.NettyClientConfig; -import org.apache.rocketmq.remoting.netty.ResponseFuture; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doAnswer; - -@RunWith(MockitoJUnitRunner.class) -public class DeFiBusClientAPIImplTest { - private DeFiBusClientAPIImpl deFiBusClientAPI = new DeFiBusClientAPIImpl(new NettyClientConfig(), null, null, new ClientConfig()); - @Mock - private RemotingClient remotingClient; - @Mock - private DefaultMQProducerImpl defaultMQProducerImpl; - - private String brokerAddr = "127.0.0.1"; - private String brokerName = "DefaultBroker"; - private static String group = "FooBarGroup"; - private static String topic = "FooBar"; - private Message msg = new Message("FooBar", new byte[] {}); - - @Before - public void init() throws Exception { - Field field = MQClientAPIImpl.class.getDeclaredField("remotingClient"); - field.setAccessible(true); - field.set(deFiBusClientAPI, remotingClient); - } - - @Test - public void testSendMessageTypeOfReply_Success() throws Exception { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock mock) throws Throwable { - InvokeCallback callback = mock.getArgument(3); - RemotingCommand request = mock.getArgument(1); - ResponseFuture responseFuture = new ResponseFuture(null, request.getOpaque(), 3 * 1000, null, null); - responseFuture.setResponseCommand(createSuccessResponse(request)); - callback.operationComplete(responseFuture); - return null; - } - }).when(remotingClient).invokeAsync(anyString(), any(RemotingCommand.class), anyLong(), any(InvokeCallback.class)); - SendMessageContext sendMessageContext = new SendMessageContext(); - sendMessageContext.setProducer(new DefaultMQProducerImpl(new DefaultMQProducer())); - msg.getProperties().put("msgType", "reply"); - deFiBusClientAPI.sendMessage(brokerAddr, brokerName, msg, new SendMessageRequestHeader(), 3 * 1000, CommunicationMode.ASYNC, - new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK); - assertThat(sendResult.getOffsetMsgId()).isEqualTo("123"); - assertThat(sendResult.getQueueOffset()).isEqualTo(123L); - assertThat(sendResult.getMessageQueue().getQueueId()).isEqualTo(1); - } - - @Override - public void onException(Throwable e) { - } - }, null, null, 0, sendMessageContext, defaultMQProducerImpl); - } - - @Test - public void testSendMessagetypeOfnull_Success() throws RemotingException, InterruptedException, MQBrokerException { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock mock) throws Throwable { - InvokeCallback callback = mock.getArgument(3); - RemotingCommand request = mock.getArgument(1); - ResponseFuture responseFuture = new ResponseFuture(null, request.getOpaque(), 3 * 1000, null, null); - responseFuture.setResponseCommand(createSuccessResponse(request)); - callback.operationComplete(responseFuture); - return null; - } - }).when(remotingClient).invokeAsync(anyString(), any(RemotingCommand.class), anyLong(), any(InvokeCallback.class)); - SendMessageContext sendMessageContext = new SendMessageContext(); - sendMessageContext.setProducer(new DefaultMQProducerImpl(new DefaultMQProducer())); - deFiBusClientAPI.sendMessage(brokerAddr, brokerName, msg, new SendMessageRequestHeader(), 3 * 1000, CommunicationMode.ASYNC, - new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK); - assertThat(sendResult.getOffsetMsgId()).isEqualTo("123"); - assertThat(sendResult.getQueueOffset()).isEqualTo(123L); - assertThat(sendResult.getMessageQueue().getQueueId()).isEqualTo(1); - } - - @Override - public void onException(Throwable e) { - } - }, - null, null, 0, sendMessageContext, defaultMQProducerImpl); - } - - @Test - public void testGetConsumerIdListByGroupAndTopic_Success() throws Exception { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock mock) throws Throwable { - RemotingCommand request = mock.getArgument(1); - GetConsumerListByGroupResponseBody body = new GetConsumerListByGroupResponseBody(); - List cidList = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - cidList.add(i + ""); - } - body.setConsumerIdList(cidList); - request.setBody(body.encode()); - request.setCode(ResponseCode.SUCCESS); - request.setOpaque(request.getOpaque()); - return request; - } - }).when(remotingClient).invokeSync(anyString(), any(RemotingCommand.class), anyLong()); - List list = deFiBusClientAPI.getConsumerIdListByGroupAndTopic(brokerAddr, group, topic, 3 * 1000); - assertThat(list.size()).isEqualTo(10); - } - - @Test(expected = MQBrokerException.class) - public void testGetConsumerIdListByGroupAndTopic_OnException() throws Exception { - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock mock) throws Throwable { - RemotingCommand request = mock.getArgument(1); - request.setCode(ResponseCode.SYSTEM_ERROR); - return request; - } - }).when(remotingClient).invokeSync(anyString(), any(RemotingCommand.class), anyLong()); - deFiBusClientAPI.getConsumerIdListByGroupAndTopic(brokerAddr, group, topic, 3 * 1000); - } - - private RemotingCommand createSuccessResponse(RemotingCommand request) { - RemotingCommand response = RemotingCommand.createResponseCommand(SendMessageResponseHeader.class); - response.setCode(ResponseCode.SUCCESS); - response.setOpaque(request.getOpaque()); - - SendMessageResponseHeader responseHeader = (SendMessageResponseHeader) response.readCustomHeader(); - responseHeader.setMsgId("123"); - responseHeader.setQueueId(1); - responseHeader.setQueueOffset(123L); - - response.addExtField(MessageConst.PROPERTY_MSG_REGION, "RegionHZ"); - response.addExtField(MessageConst.PROPERTY_TRACE_SWITCH, "true"); - response.addExtField("queueId", String.valueOf(responseHeader.getQueueId())); - response.addExtField("msgId", responseHeader.getMsgId()); - response.addExtField("queueOffset", String.valueOf(responseHeader.getQueueOffset())); - return response; - } - -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/DeFiBusClientManagerTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/DeFiBusClientManagerTest.java deleted file mode 100644 index 62c2b38d11..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/DeFiBusClientManagerTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DeFiBusClientManagerTest { -// @Test -// public void test_createInstanceOnlyOnce() { -// ClientConfig clientConfig = new ClientConfig(); -// RPCHook rpcHook = new RPCHook() { -// @Override public void doBeforeRequest(String remoteAddr, RemotingCommand request) { -// -// } -// -// @Override -// public void doAfterResponse(String remoteAddr, RemotingCommand request, RemotingCommand response) { -// -// } -// }; -// -// DeFiBusClientInstance instance1 = DeFiBusClientManager.getInstance().getAndCreateDeFiBusClientInstance(clientConfig, rpcHook); -// DeFiBusClientInstance instance2 = DeFiBusClientManager.getInstance().getAndCreateDeFiBusClientInstance(clientConfig, rpcHook); -// -// assertThat(instance1).isEqualTo(instance2); -// -// } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/consumer/DeFiBusPullMessageServiceTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/consumer/DeFiBusPullMessageServiceTest.java deleted file mode 100644 index 25dd18fa45..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/consumer/DeFiBusPullMessageServiceTest.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.consumer; - -public class DeFiBusPullMessageServiceTest { -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/factory/DeFiBusClientInstanceTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/factory/DeFiBusClientInstanceTest.java deleted file mode 100644 index 615766bb0b..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/factory/DeFiBusClientInstanceTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.factory; - -import static org.assertj.core.api.Assertions.assertThat; - -//@RunWith(MockitoJUnitRunner.class) -public class DeFiBusClientInstanceTest { -// private DeFiBusClientInstance deFiBusClientInstance = DeFiBusClientManager.getInstance().getAndCreateDeFiBusClientInstance(new ClientConfig(), DeFiBusClientHookFactory.createRPCHook(null)); -// private String topic = "FooBar"; -// private String group = "FooBarGroup"; -// -// @Mock -// private DeFiBusClientAPIImpl deFiBusClientAPI; -// -// @Test -// public void testFindConsumerIdList() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException { -// List cidList = new ArrayList<>(); -// cidList.add("client-1"); -// cidList.add("client-2"); -// cidList.add("client-3"); -// -// ReflectUtil.setSimpleProperty(MQClientInstance.class, deFiBusClientInstance, "mQClientAPIImpl", deFiBusClientAPI); -// ReflectUtil.setSimpleProperty(DeFiBusClientInstance.class, deFiBusClientInstance, "deFiClientAPI", deFiBusClientAPI); -// -// deFiBusClientInstance.getTopicRouteTable().put(topic, createRouteData()); -// -// when(deFiBusClientAPI.getConsumerIdListByGroupAndTopic(anyString(), anyString(), anyString(), anyLong())).thenReturn(cidList); -// assertThat(cidList).isEqualTo(deFiBusClientInstance.findConsumerIdList(topic, group)); -// } -// -// @Test -// public void testFindConsumerIdList_retry() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException { -// List cidList = new ArrayList<>(); -// cidList.add("client-1"); -// cidList.add("client-2"); -// cidList.add("client-3"); -// -// ReflectUtil.setSimpleProperty(MQClientInstance.class, deFiBusClientInstance, "mQClientAPIImpl", deFiBusClientAPI); -// ReflectUtil.setSimpleProperty(DeFiBusClientInstance.class, deFiBusClientInstance, "deFiClientAPI", deFiBusClientAPI); -// -// deFiBusClientInstance.getTopicRouteTable().put(topic, createRouteData()); -// when(deFiBusClientAPI.getConsumerIdListByGroupAndTopic(anyString(), anyString(), anyString(), anyLong())).thenReturn(null).thenReturn(cidList); -// assertThat(cidList).isEqualTo(deFiBusClientInstance.findConsumerIdList(topic, group)); -// } -// -// public static TopicRouteData createRouteData() { -// TopicRouteData topicRouteData = new TopicRouteData(); -// List brokerDataList = new ArrayList<>(); -// -// BrokerData brokerDataA = new BrokerData(); -// brokerDataA.setBrokerName("Broker-A"); -// brokerDataA.setCluster("Cluster-A"); -// HashMap addr = new HashMap<>(); -// addr.put(0L, "127.0.0.1:10911"); -// brokerDataA.setBrokerAddrs(addr); -// brokerDataList.add(brokerDataA); -// -// BrokerData brokerDataB = new BrokerData(); -// brokerDataB.setBrokerName("Broker-B"); -// brokerDataB.setCluster("Cluster-B"); -// HashMap addrB = new HashMap<>(); -// addrB.put(0L, "127.0.0.2:10911"); -// brokerDataB.setBrokerAddrs(addrB); -// brokerDataList.add(brokerDataB); -// -// topicRouteData.setBrokerDatas(brokerDataList); -// -// QueueData queueData = new QueueData(); -// queueData.setBrokerName("Broker-A"); -// queueData.setReadQueueNums(3); -// queueData.setWriteQueueNums(3); -// queueData.setPerm(6); -// -// QueueData queueDataB = new QueueData(); -// queueDataB.setBrokerName("Broker-B"); -// queueDataB.setReadQueueNums(3); -// queueDataB.setWriteQueueNums(3); -// queueDataB.setPerm(6); -// -// List queueDataList = new ArrayList<>(); -// queueDataList.add(queueData); -// queueDataList.add(queueDataB); -// topicRouteData.setQueueDatas(queueDataList); -// -// return topicRouteData; -// } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/hook/DeFiBusClientHookFactoryTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/hook/DeFiBusClientHookFactoryTest.java deleted file mode 100644 index adbdd6935b..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/hook/DeFiBusClientHookFactoryTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.hook; - -import java.util.concurrent.atomic.AtomicInteger; -import org.apache.rocketmq.remoting.RPCHook; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DeFiBusClientHookFactoryTest { - @Test - public void test() { - DeFiBusClientHookFactory.createRPCHook(null); - } - - @Test - public void test_doBefore_doAfter() { - AtomicInteger invokeTimes = new AtomicInteger(0); - RPCHook rpcHook = new RPCHook() { - @Override public void doBeforeRequest(String remoteAddr, RemotingCommand request) { - invokeTimes.getAndIncrement(); - } - - @Override - public void doAfterResponse(String remoteAddr, RemotingCommand request, RemotingCommand response) { - invokeTimes.getAndIncrement(); - } - }; - DeFiBusClientHookFactory.createRPCHook(rpcHook); - rpcHook.doBeforeRequest("", null); - assertThat(invokeTimes.get()).isEqualTo(1); - rpcHook.doAfterResponse("", null, null); - assertThat(invokeTimes.get()).isEqualTo(2); - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/producer/MessageQueueHealthManagerTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/producer/MessageQueueHealthManagerTest.java deleted file mode 100644 index 0131eecfd6..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/producer/MessageQueueHealthManagerTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import org.apache.rocketmq.common.message.MessageQueue; -import org.junit.Test; -import org.mockito.Spy; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class MessageQueueHealthManagerTest { - private long isoTime = 3 * 1000L; - @Spy - private MessageQueueHealthManager messageQueueHealthManager = new MessageQueueHealthManager(isoTime); - - @Test - public void testMarkQueueFault() throws Exception { - MessageQueue mq = new MessageQueue("topic1", "brokerName1", 0); - messageQueueHealthManager.markQueueFault(mq); - assertTrue(messageQueueHealthManager.isQueueFault(mq)); - Thread.sleep(isoTime + 10); - assertFalse(messageQueueHealthManager.isQueueFault(mq)); - } - - @Test - public void testMarkQueueHealthy() throws Exception { - MessageQueue mq = new MessageQueue("topic1", "brokerName1", 0); - messageQueueHealthManager.markQueueFault(mq); - assertTrue(messageQueueHealthManager.isQueueFault(mq)); - messageQueueHealthManager.markQueueHealthy(mq); - assertTrue(messageQueueHealthManager.isQueueHealthy(mq)); - } - -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/producer/RRResponseFutureTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/producer/RRResponseFutureTest.java deleted file mode 100644 index c28e6dcbe3..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/producer/RRResponseFutureTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.producer; - -import org.apache.rocketmq.common.message.Message; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class RRResponseFutureTest { - @Test - public void test() { - RRResponseFuture responseFuture = new RRResponseFuture(); - ResponseTable.getRrResponseFurtureConcurrentHashMap().put("key1", responseFuture); - - RRResponseFuture responseFuture2 = new RRResponseFuture(new RRCallback() { - @Override public void onSuccess(Message msg) { - - } - - @Override public void onException(Throwable e) { - - } - }); - ResponseTable.getRrResponseFurtureConcurrentHashMap().put("key2", responseFuture2); - - RRResponseFuture responseFuture3 = new RRResponseFuture(new RRCallback() { - @Override public void onSuccess(Message msg) { - - } - - @Override public void onException(Throwable e) { - - } - }, 3000); - ResponseTable.getRrResponseFurtureConcurrentHashMap().put("key3", responseFuture3); - } - - @Test - public void test_watiSuccess() throws InterruptedException { - RRResponseFuture responseFuture = new RRResponseFuture(new RRCallback() { - @Override public void onSuccess(Message msg) { - - } - - @Override public void onException(Throwable e) { - - } - }, 3000); - Message rspMsg = new Message(); - rspMsg.setTopic("FooBar"); - Thread thread = new Thread(new Runnable() { - @Override public void run() { - try { - Thread.sleep(1000); - responseFuture.putResponse(rspMsg); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - }); - thread.setDaemon(true); - thread.start(); - - Message rsp = responseFuture.waitResponse(3000); - assertThat(rsp).isNotNull(); - assertThat(rsp).isEqualTo(rspMsg); - } - - @Test - public void test_watiTimeout() throws InterruptedException { - RRResponseFuture responseFuture = new RRResponseFuture(new RRCallback() { - @Override public void onSuccess(Message msg) { - } - - @Override public void onException(Throwable e) { - } - }, 1000); - - Message rsp = responseFuture.waitResponse(1000); - assertThat(rsp).isNull(); - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/rebalance/AllocateMessageQueueByIDCTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/rebalance/AllocateMessageQueueByIDCTest.java deleted file mode 100644 index 6c52c2966c..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/impl/rebalance/AllocateMessageQueueByIDCTest.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.impl.rebalance; - -import cn.webank.defibus.common.DeFiBusConstant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.common.protocol.route.BrokerData; -import org.apache.rocketmq.common.protocol.route.QueueData; -import org.apache.rocketmq.common.protocol.route.TopicRouteData; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class AllocateMessageQueueByIDCTest { - private String topic = "FooBar"; - private String currentCid = "client#0#A"; - private AllocateMessageQueueByIDC allocateMessageQueueByIDC = new AllocateMessageQueueByIDC(); - - @Mock - private MQClientInstance mqClientInstance; - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void test_CurrentCIDisNull() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("currentCID is empty"); - allocateMessageQueueByIDC.allocate("group", null, null, null); - } - - @Test - public void test_mqAllIsNull() { - List result = allocateMessageQueueByIDC.allocate("group", "currentCid", null, new ArrayList<>()); - assertThat(result).isEmpty(); - } - - @Test - public void test_cidAllIsNull() { - List mqAll = new ArrayList<>(); - MessageQueue mq = new MessageQueue(); - mqAll.add(mq); - List result = allocateMessageQueueByIDC.allocate("group", "currentCid", mqAll, null); - assertThat(result).isEmpty(); - } - - @Test - public void test_allocateSuccess() { - List cidAll = prepareCidList("A", 4); - cidAll.addAll(prepareCidList("B", 5)); - cidAll.add(currentCid); - List mqAll = prepareMqList(topic, "A", 4); - mqAll.addAll(prepareMqList(topic, "B", 5)); - - ConcurrentHashMap topicRouteTable = new ConcurrentHashMap<>(); - TopicRouteData topicRouteData = prepareRouteData(); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("A", 5)); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("B", 5)); - topicRouteTable.put(topic, topicRouteData); - allocateMessageQueueByIDC.setMqClientInstance(mqClientInstance); - when(mqClientInstance.getTopicRouteTable()).thenReturn(new ConcurrentHashMap<>()).thenReturn(topicRouteTable); - when(mqClientInstance.updateTopicRouteInfoFromNameServer(anyString())).thenReturn(true); - - List result = allocateMessageQueueByIDC.allocate("group", currentCid, mqAll, cidAll); - - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0)).isEqualTo(mqAll.get(0)); - } - - @Test - public void test_allocateWithUnknownIdc() { - List cidAll = prepareCidList("A", 4); - cidAll.addAll(prepareCidList("B", 5)); - cidAll.add(currentCid); - List mqAll = prepareMqList(topic, "A", 4); - mqAll.addAll(prepareMqList(topic, "B", 5)); - List mqInC = prepareMqList(topic, "C", 5); - mqAll.addAll(mqInC); - - ConcurrentHashMap topicRouteTable = new ConcurrentHashMap<>(); - TopicRouteData topicRouteData = prepareRouteData(); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("A", 5)); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("B", 5)); - topicRouteTable.put(topic, topicRouteData); - allocateMessageQueueByIDC.setMqClientInstance(mqClientInstance); - when(mqClientInstance.getTopicRouteTable()).thenReturn(new ConcurrentHashMap<>()).thenReturn(topicRouteTable); - when(mqClientInstance.updateTopicRouteInfoFromNameServer(anyString())).thenReturn(true); - - List result = allocateMessageQueueByIDC.allocate("group", currentCid, mqAll, cidAll); - - assertThat(result.size()).isEqualTo(6); - assertThat(result.get(0)).isEqualTo(mqAll.get(0)); - assertThat(result.containsAll(mqInC)).isTrue(); - } - - @Test - public void test_allocateOtherIdc() { - List cidAll = prepareCidList("A", 4); - cidAll.add(currentCid); - List mqAll = prepareMqList(topic, "A", 4); - List mqInB = prepareMqList(topic, "B", 5); - mqAll.addAll(mqInB); - - ConcurrentHashMap topicRouteTable = new ConcurrentHashMap<>(); - TopicRouteData topicRouteData = prepareRouteData(); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("A", 5)); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("B", 5)); - topicRouteTable.put(topic, topicRouteData); - allocateMessageQueueByIDC.setMqClientInstance(mqClientInstance); - when(mqClientInstance.getTopicRouteTable()).thenReturn(new ConcurrentHashMap<>()).thenReturn(topicRouteTable); - when(mqClientInstance.updateTopicRouteInfoFromNameServer(anyString())).thenReturn(true); - - List result = allocateMessageQueueByIDC.allocate("group", currentCid, mqAll, cidAll); - - assertThat(result.size()).isEqualTo(2); - assertThat(result.get(0)).isEqualTo(mqAll.get(0)); - assertThat(result.get(1)).isEqualTo(mqInB.get(0)); - } - - @Test - public void test_allocate_notContainCurrentCID() { - List cidAll = prepareCidList("A", 4); - cidAll.addAll(prepareCidList("B", 5)); - List mqAll = prepareMqList(topic, "A", 4); - mqAll.addAll(prepareMqList(topic, "B", 5)); - - ConcurrentHashMap topicRouteTable = new ConcurrentHashMap<>(); - TopicRouteData topicRouteData = prepareRouteData(); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("A", 5)); - topicRouteData.getBrokerDatas().addAll(prepareBrokerData("B", 5)); - topicRouteTable.put(topic, topicRouteData); - allocateMessageQueueByIDC.setMqClientInstance(mqClientInstance); - List result = allocateMessageQueueByIDC.allocate("group", currentCid, mqAll, cidAll); - - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(0); - } - - public List prepareCidList(String idc, int size) { - List cids = new ArrayList<>(); - for (int i = 1; i <= size; i++) { - cids.add("client" + DeFiBusConstant.INSTANCE_NAME_SEPERATER + i + DeFiBusConstant.INSTANCE_NAME_SEPERATER + idc); - } - return cids; - } - - public List prepareMqList(String topic, String idc, int size) { - List mqs = new ArrayList<>(); - for (int i = 0; i < size; i++) { - MessageQueue mq = new MessageQueue(); - mq.setTopic(topic); - mq.setBrokerName(idc + "-Broker-" + i); - mq.setQueueId(i); - mqs.add(mq); - } - return mqs; - } - - public TopicRouteData prepareRouteData() { - TopicRouteData topicRouteData = new TopicRouteData(); - List brokerDataList = new ArrayList<>(); - topicRouteData.setBrokerDatas(brokerDataList); - List queueDataList = new ArrayList<>(); - topicRouteData.setQueueDatas(queueDataList); - return topicRouteData; - } - - public List prepareBrokerData(String idc, int size) { - List brokerDataList = new ArrayList<>(); - for (int i = 0; i < size; i++) { - BrokerData brokerData = new BrokerData(); - brokerData.setBrokerName(idc + "-Broker-" + i); - brokerData.setCluster(idc + DeFiBusConstant.IDC_SEPERATER + "Cluster"); - HashMap addr = new HashMap<>(); - addr.put(0L, "127.0.0.1:10911"); - brokerData.setBrokerAddrs(addr); - brokerDataList.add(brokerData); - } - return brokerDataList; - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/ClientFuseTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/ClientFuseTest.java deleted file mode 100644 index ae1cfabcfe..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/ClientFuseTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.producer; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.client.impl.producer.DeFiBusProducerImpl; -import cn.webank.defibus.client.impl.producer.HealthyMessageQueueSelector; -import cn.webank.defibus.client.impl.producer.MessageQueueHealthManager; -import cn.webank.defibus.common.protocol.DeFiBusResponseCode; -import cn.webank.defibus.producer.DeFiBusProducer; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import org.apache.rocketmq.client.ClientConfig; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.hook.SendMessageContext; -import org.apache.rocketmq.client.impl.CommunicationMode; -import org.apache.rocketmq.client.impl.MQClientAPIImpl; -import org.apache.rocketmq.client.impl.MQClientManager; -import org.apache.rocketmq.client.impl.factory.MQClientInstance; -import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; -import org.apache.rocketmq.client.impl.producer.TopicPublishInfo; -import org.apache.rocketmq.client.producer.SendCallback; -import org.apache.rocketmq.client.producer.SendResult; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader; -import org.apache.rocketmq.common.protocol.route.BrokerData; -import org.apache.rocketmq.common.protocol.route.QueueData; -import org.apache.rocketmq.common.protocol.route.TopicRouteData; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class ClientFuseTest { - private static DeFiBusProducer deFiBusProducer; - private Message msg; - private String topic = "test"; - private String producerGroup = "fuseTest"; - - @Mock - private MQClientAPIImpl mqClientAPIImpl; - @Spy - private MQClientInstance mQClientFactory = MQClientManager.getInstance().getAndCreateMQClientInstance(new ClientConfig()); - - @Before - public void init() throws Exception { - DeFiBusClientConfig clientConfig = new DeFiBusClientConfig(); - clientConfig.setClusterPrefix("GL"); - clientConfig.setProducerGroup(producerGroup); - clientConfig.setNamesrvAddr("127.0.0.1:9876"); - deFiBusProducer = new DeFiBusProducer(clientConfig); - deFiBusProducer.start(); - - msg = new Message(topic, new byte[] {'a'}); - Field field = DefaultMQProducerImpl.class.getDeclaredField("mQClientFactory"); - field.setAccessible(true); - field.set(deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl(), mQClientFactory); - - field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl"); - field.setAccessible(true); - field.set(mQClientFactory, mqClientAPIImpl); - - deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory(). - registerProducer(producerGroup, deFiBusProducer.getDefaultMQProducer().getDefaultMQProducerImpl()); - - Exception e = new MQBrokerException(DeFiBusResponseCode.CONSUME_DIFF_SPAN_TOO_LONG, "CODE: " + DeFiBusResponseCode.CONSUME_DIFF_SPAN_TOO_LONG + " DESC: consume span too long, maybe has slow consumer, so send rejected\nFor more information, please visit the url, http://rocketmq.apache.org/docs/faq/"); - when(mqClientAPIImpl.sendMessage(anyString(), anyString(), any(Message.class), any(SendMessageRequestHeader.class), anyLong(), any(CommunicationMode.class), - any(SendCallback.class), nullable(TopicPublishInfo.class), any(MQClientInstance.class), anyInt(), nullable(SendMessageContext.class), any(DefaultMQProducerImpl.class))) - .thenAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - SendCallback callback = (SendCallback) args[6]; - callback.onException(e); - return new SendResult(); - } - }); - } - - @After - public void shutdown() { - if (deFiBusProducer != null) { - deFiBusProducer.shutdown(); - } - } - - @Test - public void testProcessResponseFuse() throws Exception { - when(mqClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute()); - CountDownLatch countDownLatch = new CountDownLatch(1); - Field fieldSelector = DeFiBusProducerImpl.class.getDeclaredField("messageQueueSelector"); - fieldSelector.setAccessible(true); - Field fieldProducer = DeFiBusProducer.class.getDeclaredField("deFiBusProducerImpl"); - fieldProducer.setAccessible(true); - MessageQueueHealthManager messageQueueHealthManager = ((HealthyMessageQueueSelector) fieldSelector.get(fieldProducer.get(deFiBusProducer))).getMessageQueueHealthManager(); - - Assert.assertEquals(0, messageQueueHealthManager.faultMap.size()); - - deFiBusProducer.publish(msg, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - } - - @Override - public void onException(Throwable e) { - Assert.fail(e.getMessage()); - countDownLatch.countDown(); - } - }); - countDownLatch.await(3000L, TimeUnit.MILLISECONDS); - - Assert.assertEquals(3, messageQueueHealthManager.faultMap.size()); - } - - public static TopicRouteData createTopicRoute() { - TopicRouteData topicRouteData = new TopicRouteData(); - - topicRouteData.setFilterServerTable(new HashMap>()); - List brokerDataList = new ArrayList(); - BrokerData brokerData = new BrokerData(); - brokerData.setBrokerName("BrokerA"); - brokerData.setCluster("DefaultCluster"); - HashMap brokerAddrs = new HashMap(); - brokerAddrs.put(0L, "127.0.0.1:10911"); - brokerData.setBrokerAddrs(brokerAddrs); - brokerDataList.add(brokerData); - topicRouteData.setBrokerDatas(brokerDataList); - - List queueDataList = new ArrayList(); - QueueData queueData = new QueueData(); - queueData.setBrokerName("BrokerA"); - queueData.setPerm(6); - queueData.setReadQueueNums(3); - queueData.setWriteQueueNums(4); - queueData.setTopicSynFlag(0); - queueDataList.add(queueData); - topicRouteData.setQueueDatas(queueDataList); - return topicRouteData; - } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/DeFiBusProducerTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/DeFiBusProducerTest.java deleted file mode 100644 index cea5ad5377..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/DeFiBusProducerTest.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.producer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; - -//@RunWith(MockitoJUnitRunner.class) -public class DeFiBusProducerTest { -// @Spy -// private DeFiBusClientInstance deFiBusClientInstance = DeFiBusClientManager.getInstance().getAndCreateDeFiBusClientInstance(new ClientConfig(), null); -// @Mock -// private DeFiBusClientAPIImpl mqClientAPI; -// -// private DeFiBusProducer producer; -// private Message message; -// private Message zeroMsg; -// private Message bigMessage; -// private String topic = "FooBar"; -// private String producerGroupPrefix = "FooBar_PID"; -// private String clusterName = "DefaultCluster"; -// -// @Before -// public void init() throws Exception { -// String producerGroupTemp = producerGroupPrefix + System.currentTimeMillis(); -// DeFiBusClientConfig clientConfig = new DeFiBusClientConfig(); -// clientConfig.setProducerGroup(producerGroupTemp); -// producer = new DeFiBusProducer(clientConfig); -// producer.setNamesrvAddr("127.0.0.1:9876"); -// producer.getDefaultMQProducer().setCompressMsgBodyOverHowmuch(16); -// message = new Message(topic, new byte[] {'a'}); -// message.getUserProperty(""); -// zeroMsg = new Message(topic, new byte[] {}); -// zeroMsg.getUserProperty(""); -// bigMessage = new Message(topic, "This is a very huge message!".getBytes()); -// bigMessage.getUserProperty(""); -// -// producer.start(); -// -// Field field = DefaultMQProducerImpl.class.getDeclaredField("mQClientFactory"); -// field.setAccessible(true); -// field.set(producer.getDefaultMQProducer().getDefaultMQProducerImpl(), deFiBusClientInstance); -// -// field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl"); -// field.setAccessible(true); -// field.set(deFiBusClientInstance, mqClientAPI); -// -// producer.getDefaultMQProducer().getDefaultMQProducerImpl().getmQClientFactory() -// .registerProducer(producerGroupTemp, producer.getDefaultMQProducer().getDefaultMQProducerImpl()); -// -// when(mqClientAPI.sendMessage(anyString(), anyString(), any(Message.class), any(SendMessageRequestHeader.class), anyLong(), any(CommunicationMode.class), -// nullable(SendCallback.class), nullable(TopicPublishInfo.class), nullable(MQClientInstance.class), anyInt(), nullable(SendMessageContext.class), any(DefaultMQProducerImpl.class))) -// .thenAnswer(new Answer() { -// @Override public Object answer(InvocationOnMock invocation) throws Throwable { -// String brokerName = invocation.getArgument(1); -// CommunicationMode communicationMode = invocation.getArgument(5); -// SendCallback callback = invocation.getArgument(6); -// SendResult sendResult = createSendResult(SendStatus.SEND_OK, brokerName); -// switch (communicationMode) { -// case SYNC: -// return sendResult; -// case ASYNC: -// case ONEWAY: -// if (callback != null) { -// callback.onSuccess(sendResult); -// } -// } -// return null; -// } -// }); -// } -// -// @After -// public void terminate() { -// producer.shutdown(); -// } -// -// @Test -// public void testSendMessage_ZeroMessage() throws InterruptedException, RemotingException, MQBrokerException { -// try { -// producer.publish(zeroMsg); -// } catch (MQClientException e) { -// assertThat(e).hasMessageContaining("message body length is zero"); -// } -// } -// -// @Test -// public void testSendMessage_NoNameSrv() throws RemotingException, InterruptedException { -// try { -// producer.publish(message); -// } catch (MQClientException e) { -// assertThat(e).hasMessageContaining("No name server address"); -// } -// } -// -// @Test -// public void testSendMessage_NoRoute() throws RemotingException, InterruptedException { -// try { -// producer.publish(message); -// } catch (MQClientException e) { -// assertThat(e).hasMessageContaining("No route info of this topic"); -// } -// } -// -// @Test -// public void testSendMessageAsync_Success() throws RemotingException, InterruptedException, MQBrokerException, MQClientException { -// final CountDownLatch countDownLatch = new CountDownLatch(1); -// final AtomicInteger success = new AtomicInteger(0); -// when(mqClientAPI.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute()); -// producer.publish(message, new SendCallback() { -// @Override -// public void onSuccess(SendResult sendResult) { -// assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK); -// assertThat(sendResult.getOffsetMsgId()).isEqualTo("123"); -// assertThat(sendResult.getQueueOffset()).isEqualTo(456L); -// success.getAndIncrement(); -// countDownLatch.countDown(); -// } -// -// @Override -// public void onException(Throwable e) { -// countDownLatch.countDown(); -// } -// }); -// long timeout = producer.getDefaultMQProducer().getSendMsgTimeout(); -// countDownLatch.await(timeout, TimeUnit.MILLISECONDS); -// assertThat(success.get()).isEqualTo(1); -// } -// -// @Test -// public void testSendMessageAsync_Exception() throws RemotingException, MQClientException, InterruptedException, MQBrokerException { -// final CountDownLatch countDownLatch = new CountDownLatch(1); -// final AtomicBoolean success = new AtomicBoolean(true); -// when(mqClientAPI.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute()); -// when(mqClientAPI.sendMessage(anyString(), anyString(), any(Message.class), any(SendMessageRequestHeader.class), anyLong(), any(CommunicationMode.class), -// nullable(SendCallback.class), nullable(TopicPublishInfo.class), nullable(MQClientInstance.class), anyInt(), nullable(SendMessageContext.class), any(DefaultMQProducerImpl.class))) -// .thenAnswer(new Answer() { -// @Override public Object answer(InvocationOnMock invocation) throws Throwable { -// SendCallback callback = invocation.getArgument(6); -// if (callback != null) { -// callback.onException(new Exception("test send exception")); -// } -// return null; -// } -// }); -// producer.publish(message, new SendCallback() { -// @Override -// public void onSuccess(SendResult sendResult) { -// success.set(true); -// countDownLatch.countDown(); -// } -// -// @Override -// public void onException(Throwable e) { -// success.set(false); -// countDownLatch.countDown(); -// assertThat(e).hasMessage("test send exception"); -// } -// }); -// long timeout = producer.getDefaultMQProducer().getSendMsgTimeout(); -// countDownLatch.await(timeout, TimeUnit.MILLISECONDS); -// assertThat(success.get()).isEqualTo(false); -// } -// -// @Test -// public void testRequest_Timeout() throws RemotingException, MQClientException, InterruptedException, MQBrokerException { -// when(mqClientAPI.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute()); -// when(deFiBusClientInstance.getTopicRouteTable()).thenReturn(new ConcurrentHashMap()); -// Message replyMsg = producer.request(createRequestMessage(topic, clusterName), 3000); -// assertThat(replyMsg).isNull(); -// } -// -// @Test -// public void testRequest_Success() throws RemotingException, MQClientException, InterruptedException, MQBrokerException { -// when(mqClientAPI.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute()); -// when(deFiBusClientInstance.getTopicRouteTable()).thenReturn(new ConcurrentHashMap()); -// final AtomicBoolean finish = new AtomicBoolean(false); -// new Thread(new Runnable() { -// @Override public void run() { -// ConcurrentHashMap responseMap = ResponseTable.getRrResponseFurtureConcurrentHashMap(); -// assertThat(responseMap).isNotNull(); -// while (!finish.get()) { -// try { -// Thread.sleep(10); -// } catch (InterruptedException e) { -// } -// for (Map.Entry entry : responseMap.entrySet()) { -// RRResponseFuture future = entry.getValue(); -// future.putResponse(createRequestMessage(topic, clusterName)); -// } -// } -// } -// }).start(); -// Message replyMsg = producer.request(createRequestMessage(topic, clusterName), 3000); -// finish.getAndSet(true); -// assertThat(replyMsg.getTopic()).isEqualTo(topic); -// assertThat(replyMsg.getBody()).isEqualTo(new byte[] {'a'}); -// } -// -// @Test -// public void testRequestAsync_Success() throws RemotingException, MQClientException, InterruptedException, MQBrokerException { -// when(mqClientAPI.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute()); -// when(deFiBusClientInstance.getTopicRouteTable()).thenReturn(new ConcurrentHashMap()); -// final AtomicBoolean finish = new AtomicBoolean(false); -// new Thread(new Runnable() { -// @Override public void run() { -// ConcurrentHashMap responseMap = ResponseTable.getRrResponseFurtureConcurrentHashMap(); -// assertThat(responseMap).isNotNull(); -// while (!finish.get()) { -// try { -// Thread.sleep(10); -// } catch (InterruptedException e) { -// } -// for (Map.Entry entry : responseMap.entrySet()) { -// RRResponseFuture future = entry.getValue(); -// future.putResponse(createRequestMessage(topic, clusterName)); -// } -// } -// } -// }).start(); -// producer.request(createRequestMessage(topic, clusterName), new RRCallback() { -// @Override public void onSuccess(Message msg) { -// finish.getAndSet(true); -// assertThat(msg.getTopic()).isEqualTo(topic); -// assertThat(msg.getBody()).isEqualTo(new byte[] {'a'}); -// } -// -// @Override public void onException(Throwable e) { -// finish.set(true); -// assert false; -// } -// }, 3000); -// } -// -// public static TopicRouteData createTopicRoute() { -// TopicRouteData topicRouteData = new TopicRouteData(); -// -// topicRouteData.setFilterServerTable(new HashMap>()); -// List brokerDataList = new ArrayList(); -// BrokerData brokerData = new BrokerData(); -// brokerData.setBrokerName("BrokerA"); -// brokerData.setCluster("DefaultCluster"); -// HashMap brokerAddrs = new HashMap(); -// brokerAddrs.put(0L, "127.0.0.1:10911"); -// brokerData.setBrokerAddrs(brokerAddrs); -// brokerDataList.add(brokerData); -// topicRouteData.setBrokerDatas(brokerDataList); -// -// List queueDataList = new ArrayList(); -// QueueData queueData = new QueueData(); -// queueData.setBrokerName("BrokerA"); -// queueData.setPerm(6); -// queueData.setReadQueueNums(3); -// queueData.setWriteQueueNums(4); -// queueData.setTopicSynFlag(0); -// queueDataList.add(queueData); -// topicRouteData.setQueueDatas(queueDataList); -// return topicRouteData; -// } -// -// private SendResult createSendResult(SendStatus sendStatus, String brokerName) { -// SendResult sendResult = new SendResult(); -// sendResult.setMsgId("123"); -// sendResult.setOffsetMsgId("123"); -// sendResult.setQueueOffset(456); -// sendResult.setSendStatus(sendStatus); -// sendResult.setRegionId("HZ"); -// MessageQueue mq = new MessageQueue(); -// mq.setTopic(topic); -// mq.setBrokerName(brokerName); -// mq.setQueueId(0); -// sendResult.setMessageQueue(mq); -// return sendResult; -// } -// -// private Message createRequestMessage(String topic, String clusterName) { -// Message requestMessage = new Message(); -// Map map = new HashMap(); -// map.put(DeFiBusConstant.PROPERTY_MESSAGE_REPLY_TO, "127.0.0.1"); -// map.put(DeFiBusConstant.PROPERTY_MESSAGE_CLUSTER, clusterName); -// map.put(DeFiBusConstant.PROPERTY_MESSAGE_TTL, "3000"); -// MessageAccessor.setProperties(requestMessage, map); -// requestMessage.setTopic(topic); -// requestMessage.setBody(new byte[] {'a'}); -// return requestMessage; -// } -} diff --git a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/HealthyMessageQueueSelectorTest.java b/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/HealthyMessageQueueSelectorTest.java deleted file mode 100644 index 81a749a9d1..0000000000 --- a/eventmesh-store/defibus-client/src/test/java/cn/webank/defibus/client/producer/HealthyMessageQueueSelectorTest.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.client.producer; - -import cn.webank.defibus.client.impl.producer.DeFiBusProducerImpl; -import cn.webank.defibus.client.impl.producer.HealthyMessageQueueSelector; -import cn.webank.defibus.client.impl.producer.MessageQueueHealthManager; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageQueue; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; - -public class HealthyMessageQueueSelectorTest { - @Test - public void testLocalValidQueue() { - - final DeFiBusProducerImpl producerImplMock = Mockito.mock(DeFiBusProducerImpl.class); - Message msg = new Message(); - msg.setTopic("testtopic"); - - Set locBrokers = new HashSet<>(); - locBrokers.add("localIDC"); -// PowerMockito.when(producerImplMock.getLocalBrokers()).thenReturn(locBrokers); - - MessageQueueHealthManager manager = new MessageQueueHealthManager(60 * 1000); - HealthyMessageQueueSelector selector = new HealthyMessageQueueSelector(manager, 1); - selector.setLocalBrokers(locBrokers); - - List mqs = new ArrayList<>(); - for (int i = 1; i <= 10; i++) { - MessageQueue m = new MessageQueue("testtopic", "localIDC", i); - mqs.add(m); - } - - final AtomicReference selectedResultRef = new AtomicReference(); - MessageQueue select = selector.select(mqs, msg, selectedResultRef); - Assert.assertTrue(select != null && !(select.getBrokerName().equalsIgnoreCase("dummyBroker"))); - } - - @Test - public void testErrorQueue() { - Set locBrokers = new HashSet<>(); - locBrokers.add("localIDC"); - - MessageQueueHealthManager manager = new MessageQueueHealthManager(60 * 1000); - HealthyMessageQueueSelector selector = new HealthyMessageQueueSelector(manager, 1); - selector.setLocalBrokers(locBrokers); - - List mqs = new ArrayList<>(); - for (int i = 1; i <= 10; i++) { - MessageQueue m = new MessageQueue("testtopic", "localIDC", i); - mqs.add(m); - manager.faultMap.put(m, System.currentTimeMillis() + 60 * 1000);//设置为熔断queue - } - - MessageQueue m = new MessageQueue("testtopic", "dummyBroker", 0); - mqs.add(m); - - final AtomicReference selectedResultRef = new AtomicReference(); - //List mqs, Message msg, final Object selectedResultRef - Message msg = new Message(); - msg.setTopic("testtopic"); - MessageQueue select = selector.select(mqs, msg, selectedResultRef); - Assert.assertTrue(select != null && select.getBrokerName().equalsIgnoreCase("dummyBroker")); - } - - @Test - public void testOtherValidQueue() { - Set locBrokers = new HashSet<>(); - locBrokers.add("localIDC"); - - MessageQueueHealthManager manager = new MessageQueueHealthManager(60 * 1000); - HealthyMessageQueueSelector selector = new HealthyMessageQueueSelector(manager, 1); - selector.setLocalBrokers(locBrokers); - - List mqs = new ArrayList<>(); - for (int i = 1; i <= 10; i++) { - MessageQueue m = new MessageQueue("testtopic", "localIDC1", i); - mqs.add(m); - } - - final AtomicReference selectedResultRef = new AtomicReference(); - //List mqs, Message msg, final Object selectedResultRef - Message msg = new Message(); - msg.setTopic("testtopic"); - MessageQueue select = selector.select(mqs, msg, selectedResultRef); - Assert.assertTrue(select != null && !(select.getBrokerName().equalsIgnoreCase("dummyBroker"))); - } - - @Test - public void testBizTopic() { - String bizTopic = "XX0-s-00000000-01-0"; - String localBrokerName = "localIdcBroker"; - String otherIdcBrokerName = "otherIdcBroker"; - - Message msg = new Message(); - msg.setTopic(bizTopic); - - Set localBrokers = new HashSet<>(); - localBrokers.add(localBrokerName); - - MessageQueueHealthManager manager = new MessageQueueHealthManager(60 * 1000); - HealthyMessageQueueSelector selector = new HealthyMessageQueueSelector(manager, 1); - selector.setLocalBrokers(localBrokers); - - //construct mq data - List localMqs = new ArrayList<>(); - List otherMqs = new ArrayList<>(); - List mqs = new ArrayList<>(); - for (int i = 0; i < 3; i++) { - MessageQueue m = new MessageQueue(bizTopic, localBrokerName, i); - mqs.add(m); - localMqs.add(m); - } - for (int i = 0; i < 3; i++) { - MessageQueue m = new MessageQueue(bizTopic, otherIdcBrokerName, i); - mqs.add(m); - otherMqs.add(m); - } - Collections.sort(mqs); - - //case 1:There are mqs that aren't isolated in this IDC, select from this IDC - for (int i = 0; i < mqs.size(); i++) { - final AtomicReference selectedResultRef = new AtomicReference(); - MessageQueue selectResult = selector.select(mqs, msg, selectedResultRef); - - Assert.assertTrue(selectResult != null - && localBrokers.contains(selectResult.getBrokerName())); - Assert.assertTrue(!selector.getMessageQueueHealthManager().faultMap.containsKey(selectResult)); - } - - //case 2:All mqs in this IDC are isolated, select mq from other IDC. - for (MessageQueue mq : localMqs) { - selector.getMessageQueueHealthManager().markQueueFault(mq); - } - for (int i = 0; i < mqs.size(); i++) { - final AtomicReference selectedResultRef = new AtomicReference(); - MessageQueue selectResult = selector.select(mqs, msg, selectedResultRef); - - Assert.assertTrue(selectResult != null - && !localBrokers.contains(selectResult.getBrokerName())); - Assert.assertTrue(!selector.getMessageQueueHealthManager().faultMap.containsKey(selectResult)); - } - - //case 3:All mqs are isolated, select one randomly - for (MessageQueue mq : otherMqs) { - selector.getMessageQueueHealthManager().markQueueFault(mq); - } - for (int i = 0; i < mqs.size(); i++) { - final AtomicReference selectedResultRef = new AtomicReference(); - MessageQueue selectResult = selector.select(mqs, msg, selectedResultRef); - - Assert.assertTrue(selectResult != null - && (selectResult.getBrokerName().equals(localBrokerName) || selectResult.getBrokerName().equals(otherIdcBrokerName))); - Assert.assertTrue(selector.getMessageQueueHealthManager().faultMap.containsKey(selectResult)); - } - } - - @Test - public void testRetryBizTopic() { - String bizTopic = "XX0-s-00000000-01-0"; - String localBrokerNamePrefix = "localIdcBroker"; - String otherIdcBrokerNamePrefix = "otherIdcBroker"; - - Message msg = new Message(); - msg.setTopic(bizTopic); - - Set localBrokers = new HashSet<>(); - for (int i = 1; i <= 3; i++) { - localBrokers.add(localBrokerNamePrefix + i); - } - - MessageQueueHealthManager manager = new MessageQueueHealthManager(60 * 1000); - HealthyMessageQueueSelector selector = new HealthyMessageQueueSelector(manager, 1); - selector.setLocalBrokers(localBrokers); - - //construct mq data - List localMqs = new ArrayList<>(); - List otherMqs = new ArrayList<>(); - List mqs = new ArrayList<>(); - for (int i = 0; i < 3; i++) { - for (int j = 1; j < 3; j++) { - MessageQueue m = new MessageQueue(bizTopic, localBrokerNamePrefix + j, i); - mqs.add(m); - localMqs.add(m); - } - } - for (int i = 0; i < 3; i++) { - for (int j = 0; j <= 3; j++) { - MessageQueue m = new MessageQueue(bizTopic, otherIdcBrokerNamePrefix + j, i); - mqs.add(m); - otherMqs.add(m); - } - } - Collections.sort(mqs); - - //case 1:There are mqs that aren't isolated in this IDC, select from this IDC - MessageQueue lastSelectedMq = localMqs.get(0); - for (int i = 0; i < mqs.size(); i++) { - final AtomicReference selectedResultRef = new AtomicReference(); - selectedResultRef.set(lastSelectedMq); - MessageQueue selectResult = selector.select(mqs, msg, selectedResultRef); - - Assert.assertTrue(selectResult != null - && localBrokers.contains(selectResult.getBrokerName()) - && !selectResult.getBrokerName().equals(lastSelectedMq.getBrokerName())); - Assert.assertTrue(!selector.getMessageQueueHealthManager().faultMap.containsKey(selectResult)); - } - - //case 2:All mqs in this IDC are isolated, select mq from other IDC. - for (MessageQueue mq : localMqs) { - selector.getMessageQueueHealthManager().markQueueFault(mq); - } - for (int i = 0; i < mqs.size(); i++) { - final AtomicReference selectedResultRef = new AtomicReference(); - selectedResultRef.set(lastSelectedMq); - MessageQueue selectResult = selector.select(mqs, msg, selectedResultRef); - - Assert.assertTrue(selectResult != null - && !localBrokers.contains(selectResult.getBrokerName()) - && !selectResult.getBrokerName().equals(lastSelectedMq.getBrokerName())); - Assert.assertTrue(!selector.getMessageQueueHealthManager().faultMap.containsKey(selectResult)); - } - - //case 3:All mqs are isolated, select one randomly - for (MessageQueue mq : otherMqs) { - selector.getMessageQueueHealthManager().markQueueFault(mq); - } - for (int i = 0; i < mqs.size(); i++) { - final AtomicReference selectedResultRef = new AtomicReference(); - selectedResultRef.set(lastSelectedMq); - MessageQueue selectResult = selector.select(mqs, msg, selectedResultRef); - - Assert.assertTrue(selectResult != null - && !selectResult.getBrokerName().equals(lastSelectedMq.getBrokerName())); - Assert.assertTrue(selector.getMessageQueueHealthManager().faultMap.containsKey(selectResult)); - } - } -} diff --git a/eventmesh-store/defibus-client/src/test/resources/log4j.xml b/eventmesh-store/defibus-client/src/test/resources/log4j.xml deleted file mode 100644 index 2aae98e725..0000000000 --- a/eventmesh-store/defibus-client/src/test/resources/log4j.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-common/.gitignore b/eventmesh-store/defibus-common/.gitignore deleted file mode 100644 index c1285b3799..0000000000 --- a/eventmesh-store/defibus-common/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -/bin/ -/.git/ -/.gradle/ -/.settings/ -/logs -.DS_Store -.*.swp -*.ipr -*.iml -*.iws -*.class -*.log -.idea -build -.classpath -.project -/test-output/ -/dist -/.pmd -/classes -/logs -/out \ No newline at end of file diff --git a/eventmesh-store/defibus-common/build.gradle b/eventmesh-store/defibus-common/build.gradle deleted file mode 100644 index baeb0e739d..0000000000 --- a/eventmesh-store/defibus-common/build.gradle +++ /dev/null @@ -1,21 +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. - */ - -dependencies { - compile "org.apache.rocketmq:rocketmq-common:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-remoting:$project.rocketmqVersion" -} \ No newline at end of file diff --git a/eventmesh-store/defibus-common/conf/checkstyle.xml b/eventmesh-store/defibus-common/conf/checkstyle.xml deleted file mode 100644 index 3d024111bc..0000000000 --- a/eventmesh-store/defibus-common/conf/checkstyle.xml +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusBrokerConfig.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusBrokerConfig.java deleted file mode 100644 index 01f085a3bc..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusBrokerConfig.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common; - -import org.apache.rocketmq.common.annotation.ImportantField; - -public class DeFiBusBrokerConfig { - private int sendReplyMessageThreadPoolNums = 64; - - private int pushReplyMessageThreadPoolNums = 64; - - private int sendReplyThreadPoolQueueCapacity = 10000; - - private int pushReplyThreadPoolQueueCapacity = 10000; - - @ImportantField - private String rmqAddressServerSubGroup = "namesrvAddr"; - - @ImportantField - private String rmqAddressServerDomain = "http://127.0.0.1:8090"; - - private int scaleQueueThreadPoolQueueCapacity = 100000; - - private int scaleQueueSizeDelayTimeMinute = 5; - - private int scaleQueueRetryTimesMax = 10000; - - private int minQueueNum = 1; - - private boolean redirectMessageEnable = true; - - // whether reject sending when the depth exceeds threshold - @ImportantField - private boolean rejectSendWhenMaxDepth = true; - - //warning threshold of fuse - private double queueDepthHighWatermark = 0.7; - - //whether enable auto-clean when there are multiple consumer groups - @ImportantField - private boolean autoUpdateDepth = true; - - @ImportantField - private int depthCheckInterval = 30 * 1000; - - @ImportantField - private int checkQueueListeningPeriod = 5; - - @ImportantField - private boolean checkQueueListening = true; - - public int getSendReplyMessageThreadPoolNums() { - return sendReplyMessageThreadPoolNums; - } - - public void setSendReplyMessageThreadPoolNums(int sendReplyMessageThreadPoolNums) { - this.sendReplyMessageThreadPoolNums = sendReplyMessageThreadPoolNums; - } - - public int getPushReplyMessageThreadPoolNums() { - return pushReplyMessageThreadPoolNums; - } - - public void setPushReplyMessageThreadPoolNums(int pushReplyMessageThreadPoolNums) { - this.pushReplyMessageThreadPoolNums = pushReplyMessageThreadPoolNums; - } - - public int getSendReplyThreadPoolQueueCapacity() { - return sendReplyThreadPoolQueueCapacity; - } - - public void setSendReplyThreadPoolQueueCapacity(int sendReplyThreadPoolQueueCapacity) { - this.sendReplyThreadPoolQueueCapacity = sendReplyThreadPoolQueueCapacity; - } - - public int getPushReplyThreadPoolQueueCapacity() { - return pushReplyThreadPoolQueueCapacity; - } - - public void setPushReplyThreadPoolQueueCapacity(int pushReplyThreadPoolQueueCapacity) { - this.pushReplyThreadPoolQueueCapacity = pushReplyThreadPoolQueueCapacity; - } - - public String getRmqAddressServerSubGroup() { - return rmqAddressServerSubGroup; - } - - public void setRmqAddressServerSubGroup(String rmqAddressServerSubGroup) { - this.rmqAddressServerSubGroup = rmqAddressServerSubGroup; - } - - public String getRmqAddressServerDomain() { - return rmqAddressServerDomain; - } - - public void setRmqAddressServerDomain(String rmqAddressServerDomain) { - this.rmqAddressServerDomain = rmqAddressServerDomain; - } - - public int getScaleQueueThreadPoolQueueCapacity() { - return scaleQueueThreadPoolQueueCapacity; - } - - public void setScaleQueueThreadPoolQueueCapacity(int scaleQueueThreadPoolQueueCapacity) { - this.scaleQueueThreadPoolQueueCapacity = scaleQueueThreadPoolQueueCapacity; - } - - public int getScaleQueueSizeDelayTimeMinute() { - return scaleQueueSizeDelayTimeMinute; - } - - public void setScaleQueueSizeDelayTimeMinute(int scaleQueueSizeDelayTimeMinute) { - this.scaleQueueSizeDelayTimeMinute = scaleQueueSizeDelayTimeMinute; - } - - public int getScaleQueueRetryTimesMax() { - return scaleQueueRetryTimesMax; - } - - public void setScaleQueueRetryTimesMax(int scaleQueueRetryTimesMax) { - this.scaleQueueRetryTimesMax = scaleQueueRetryTimesMax; - } - - public int getMinQueueNum() { - return minQueueNum; - } - - public void setMinQueueNum(int minQueueNum) { - this.minQueueNum = minQueueNum; - } - - public boolean isRedirectMessageEnable() { - return redirectMessageEnable; - } - - public void setRedirectMessageEnable(boolean redirectMessageEnable) { - this.redirectMessageEnable = redirectMessageEnable; - } - - public boolean isAutoUpdateDepth() { - return autoUpdateDepth; - } - - public boolean isRejectSendWhenMaxDepth() { - return rejectSendWhenMaxDepth; - } - - public double getQueueDepthHighWatermark() { - return queueDepthHighWatermark; - } - - public int getDepthCheckInterval() { - return depthCheckInterval; - } - - public boolean isCheckQueueListening() { - return checkQueueListening; - } - - public int getCheckQueueListeningPeriod() { - return checkQueueListeningPeriod; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusConstant.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusConstant.java deleted file mode 100644 index c51ec5060c..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusConstant.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common; - -public class DeFiBusConstant { - public static final String PROPERTY_MESSAGE_REPLY_TO = "REPLY_TO"; //requester clientId - - public static final String PROPERTY_RR_REQUEST_ID = "RR_REQUEST_UNIQ_ID"; - - public static final String PROPERTY_MESSAGE_TTL = "TTL"; //timeout for request-response - - public static final String PROPERTY_MESSAGE_CLUSTER = "CLUSTER"; //cluster name - - public static final String PROPERTY_MESSAGE_BROKER = "BROKER"; //broker name where message stored - - public static final String REDIRECT = "REDIRECT"; - - public static final String REDIRECT_FLAG = "REDIRECT_FLAG"; - - public static final String PLUGIN_CLASS_NAME = "cn.webank.defibus.broker.plugin.DeFiPluginMessageStore"; - - public static final String RR_REPLY_TOPIC = "rr-reply-topic"; //post fix for reply topic - - public static final String KEY = "msgType"; - - public static final String DEFAULT_TTL = "14400000"; - - public static final String EXT_CONSUMER_GROUP = "ExtConsumerGroup"; - - public static final String RMQ_SYS = "RMQ_SYS_"; - - /** - * msgType1: indicate the msg is broadcast message - */ - public static final String DIRECT = "direct"; - - /** - * msgType2: msg of type except broadcast and reply - */ - public static final String PERSISTENT = "persistent"; - - /** - * msgType3: indicate the msg is which consumer reply to producer - */ - public static final String REPLY = "reply"; - - public static final String INSTANCE_NAME_SEPERATER = "#"; - - public static final String IDC_SEPERATER = "-"; - -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusErrorCode.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusErrorCode.java deleted file mode 100644 index 2f90a50cb2..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusErrorCode.java +++ /dev/null @@ -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. - */ - -package cn.webank.defibus.common; - -public class DeFiBusErrorCode { - public static final int RR_REQUEST_TIMEOUT = 1; -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusVersion.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusVersion.java deleted file mode 100644 index f9ebc81915..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/DeFiBusVersion.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common; - -public class DeFiBusVersion { - public static final int CURRENT_VERSION = Version.V1_0_0.ordinal(); - - public static String getVersionDesc(int value) { - try { - DeFiBusVersion.Version v = DeFiBusVersion.Version.values()[value]; - return v.name(); - } catch (Exception e) { - } - - return "HigherVersion"; - } - - public static DeFiBusVersion.Version value2Version(int value) { - return DeFiBusVersion.Version.values()[value]; - } - - public enum Version { - V1_0_0_SNAPSHOT, - V1_0_0, - V1_0_1_SNAPSHOT, - V1_0_1, - V1_1_0_SNAPSHOT, - V1_1_0, - V1_2_0_SNAPSHOT, - V1_2_0, - V1_3_0_SNAPSHOT, - V1_3_0, - V1_3_1_SNAPSHOT, - V1_3_1, - V1_3_2_SNAPSHOT, - V1_3_2, - V1_3_3_SNAPSHOT, - V1_3_3, - V1_3_4_SNAPSHOT, - V1_3_4, - V1_4_0_SNAPSHOT, - V1_4_0, - V1_4_1_SNAPSHOT, - V1_4_1, - V1_4_2_SNAPSHOT, - V1_4_2, - V1_4_3_SNAPSHOT, - V1_4_3, - V1_4_4_SNAPSHOT, - V1_4_4, - V1_4_5_SNAPSHOT, - V1_4_5, - V1_4_6_SNAPSHOT, - V1_4_6, - V1_4_7_SNAPSHOT, - V1_4_7, - V1_5_0_SNAPSHOT, - V1_5_0, - V1_5_1_SNAPSHOT, - V1_5_1, - V1_5_2_SNAPSHOT, - V1_5_2, - V1_6_0_SNAPSHOT, - V1_6_0, - V1_6_1_SNAPSHOT, - V1_6_1, - V1_6_2_SNAPSHOT, - V1_6_2, - V1_6_3_SNAPSHOT, - V1_6_3, - V1_6_4_SNAPSHOT, - V1_6_4, - V1_6_5_SNAPSHOT, - V1_6_5, - V1_7_0_SNAPSHOT, - V1_7_0 - } - - public static void main(String[] args) { - System.out.println(CURRENT_VERSION); - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/admin/DeFiBusConsumeStats.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/admin/DeFiBusConsumeStats.java deleted file mode 100644 index 1be8386a1a..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/admin/DeFiBusConsumeStats.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.admin; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.remoting.protocol.RemotingSerializable; - -public class DeFiBusConsumeStats extends RemotingSerializable { - private HashMap offsetTable = new HashMap(); - private double consumeTps = 0; - - public long computeTotalDiff() { - long diffTotal = 0L; - - Iterator> it = this.offsetTable.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry next = it.next(); - long diff = next.getValue().getBrokerOffset() - next.getValue().getConsumerOffset(); - diffTotal += diff; - } - - return diffTotal; - } - - public HashMap getOffsetTable() { - return offsetTable; - } - - public void setOffsetTable(HashMap offsetTable) { - this.offsetTable = offsetTable; - } - - public double getConsumeTps() { - return consumeTps; - } - - public void setConsumeTps(double consumeTps) { - this.consumeTps = consumeTps; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/admin/DeFiBusOffsetWrapper.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/admin/DeFiBusOffsetWrapper.java deleted file mode 100644 index 7e7ae40e33..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/admin/DeFiBusOffsetWrapper.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.admin; - -import org.apache.rocketmq.common.admin.OffsetWrapper; - -public class DeFiBusOffsetWrapper extends OffsetWrapper { - private long lastDeliverOffset; - - public long getLastDeliverOffset() { - return lastDeliverOffset; - } - - public void setLastDeliverOffset(long lastDeliverOffset) { - this.lastDeliverOffset = lastDeliverOffset; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/exception/DeFiBusException.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/exception/DeFiBusException.java deleted file mode 100644 index c562b9787d..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/exception/DeFiBusException.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.exception; - -public class DeFiBusException extends Exception { - - private int errorCode; - private String errorString; - - public DeFiBusException(int errorCode, String errorString) { - super("CODE: " + errorCode + " DESC:" + errorString); - this.errorCode = errorCode; - this.errorString = errorString; - } - - public DeFiBusException(String message, Throwable cause) { - super(message, cause); - this.errorCode = -1; - this.errorString = message; - } - - public int getErrorCode() { - return errorCode; - } - - public void setErrorCode(int errorCode) { - this.errorCode = errorCode; - } - - public String getErrorString() { - return errorString; - } - - public void setErrorString(String errorString) { - this.errorString = errorString; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/exception/DeFiBusRuntimeException.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/exception/DeFiBusRuntimeException.java deleted file mode 100644 index 60aa9247a8..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/exception/DeFiBusRuntimeException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.exception; - -public class DeFiBusRuntimeException extends RuntimeException { - public DeFiBusRuntimeException(String message) { - super(message); - } - - public DeFiBusRuntimeException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/message/DeFiBusMessageConst.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/message/DeFiBusMessageConst.java deleted file mode 100644 index 391fa5f369..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/message/DeFiBusMessageConst.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.message; - -public class DeFiBusMessageConst { - public static final String LEAVE_TIME = "LEAVE_TIME"; //leaveBrokerTime - public static final String ARRIVE_TIME = "ARRIVE_TIME"; //arriveClientTime -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusRequestCode.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusRequestCode.java deleted file mode 100644 index ce64bf5e83..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusRequestCode.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol; - -public class DeFiBusRequestCode { - public static final int PUSH_RR_REPLY_MSG_TO_CLIENT = 400; - public static final int SEND_DIRECT_MESSAGE = 402; - public static final int SEND_DIRECT_MESSAGE_V2 = 403; - public static final int GET_CONSUME_STATS_V2 = 506; - public static final int GET_CONSUMER_LIST_BY_GROUP_AND_TOPIC = 507; - public static final int NOTIFY_WHEN_TOPIC_CONFIG_CHANGE = 508; -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusResponseCode.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusResponseCode.java deleted file mode 100644 index 0c958b9ec8..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusResponseCode.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol; - -public class DeFiBusResponseCode { - public static final int CONSUME_DIFF_SPAN_TOO_LONG = 301; - -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusTopicConfig.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusTopicConfig.java deleted file mode 100644 index e343b9a9e4..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/DeFiBusTopicConfig.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package cn.webank.defibus.common.protocol; - -import com.google.common.base.Preconditions; - -public class DeFiBusTopicConfig { - public static final long DEFAULT_QUEUE_LENGTH = 500; - private static final String SEPARATOR = " "; - private String topicName; - private long maxQueueDepth = DEFAULT_QUEUE_LENGTH; - - public DeFiBusTopicConfig() { - } - - public DeFiBusTopicConfig(String topicName) { - this(topicName, DEFAULT_QUEUE_LENGTH); - } - - public DeFiBusTopicConfig(String topicName, long maxQueueDepth) { - Preconditions.checkArgument(topicName.indexOf(SEPARATOR) < 0, "topicName is invalid:" + topicName); - this.topicName = topicName; - this.maxQueueDepth = maxQueueDepth; - } - - public String encode() { - StringBuilder sb = new StringBuilder(); - - sb.append(this.topicName); - sb.append(SEPARATOR); - sb.append(this.maxQueueDepth); - - return sb.toString(); - } - - public boolean decode(final String in) { - String[] strs = in.split(SEPARATOR); - if (strs != null && strs.length == 2) { - this.topicName = strs[0]; - - this.maxQueueDepth = Long.parseLong(strs[1]); - - return true; - } - - return false; - } - - public String getTopicName() { - return topicName; - } - - public void setTopicName(String topicName) { - Preconditions.checkArgument(topicName.indexOf(SEPARATOR) < 0, "topicName is invalid:" + topicName); - this.topicName = topicName; - } - - public long getMaxQueueDepth() { - return maxQueueDepth; - } - - public void setMaxQueueDepth(long maxQueueDepth) { - this.maxQueueDepth = maxQueueDepth; - } - - @Override - public boolean equals(final Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - final DeFiBusTopicConfig that = (DeFiBusTopicConfig) o; - - if (maxQueueDepth != that.maxQueueDepth) - return false; - if (topicName != null ? !topicName.equals(that.topicName) : that.topicName != null) - return false; - return true; - } - - @Override - public String toString() { - return "DeFiBusTopicConfig[" + - "topicName='" + topicName + '\'' + - ", maxQueueDepth=" + maxQueueDepth + - ']'; - } - - @Override - public int hashCode() { - int result = topicName.hashCode(); - result = 31 * result + (int) (maxQueueDepth ^ (maxQueueDepth >>> 32)); - return result; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/body/DeFiBusTopicConfigSerializeWrapper.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/body/DeFiBusTopicConfigSerializeWrapper.java deleted file mode 100644 index 16407feded..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/body/DeFiBusTopicConfigSerializeWrapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol.body; - -import cn.webank.defibus.common.protocol.DeFiBusTopicConfig; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.rocketmq.common.DataVersion; -import org.apache.rocketmq.remoting.protocol.RemotingSerializable; - -public class DeFiBusTopicConfigSerializeWrapper extends RemotingSerializable { - private ConcurrentHashMap extTopicConfigTable = - new ConcurrentHashMap(); - private DataVersion dataVersion = new DataVersion(); - - public ConcurrentHashMap getExtTopicConfigTable() { - return extTopicConfigTable; - } - - public void setExtTopicConfigTable(ConcurrentHashMap extTopicConfigTable) { - this.extTopicConfigTable = extTopicConfigTable; - } - - public DataVersion getDataVersion() { - return dataVersion; - } - - public void setDataVersion(DataVersion dataVersion) { - this.dataVersion = dataVersion; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/body/GetConsumerListByGroupAndTopicResponseBody.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/body/GetConsumerListByGroupAndTopicResponseBody.java deleted file mode 100644 index 49e8750284..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/body/GetConsumerListByGroupAndTopicResponseBody.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol.body; - -import java.util.List; -import org.apache.rocketmq.remoting.protocol.RemotingSerializable; - -public class GetConsumerListByGroupAndTopicResponseBody extends RemotingSerializable { - private List consumerIdList; - - public List getConsumerIdList() { - return consumerIdList; - } - - public void setConsumerIdList(List consumerIdList) { - this.consumerIdList = consumerIdList; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/GetConsumerListByGroupAndTopicRequestHeader.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/GetConsumerListByGroupAndTopicRequestHeader.java deleted file mode 100644 index f65936ea5b..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/GetConsumerListByGroupAndTopicRequestHeader.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol.header; - -import org.apache.rocketmq.remoting.CommandCustomHeader; -import org.apache.rocketmq.remoting.annotation.CFNotNull; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; - -public class GetConsumerListByGroupAndTopicRequestHeader implements CommandCustomHeader { - @CFNotNull - private String consumerGroup; - - @CFNotNull - private String topic; - - @Override - public void checkFields() throws RemotingCommandException { - } - - public String getConsumerGroup() { - return consumerGroup; - } - - public void setConsumerGroup(String consumerGroup) { - this.consumerGroup = consumerGroup; - } - - public String getTopic() { - return topic; - } - - public void setTopic(String topic) { - this.topic = topic; - } -} \ No newline at end of file diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/GetConsumerListByGroupAndTopicResponseHeader.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/GetConsumerListByGroupAndTopicResponseHeader.java deleted file mode 100644 index 0486fbe09d..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/GetConsumerListByGroupAndTopicResponseHeader.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol.header; - -import org.apache.rocketmq.remoting.CommandCustomHeader; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; - -public class GetConsumerListByGroupAndTopicResponseHeader implements CommandCustomHeader { - - @Override - public void checkFields() throws RemotingCommandException { - } -} - diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/NotifyTopicChangedRequestHeader.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/NotifyTopicChangedRequestHeader.java deleted file mode 100644 index 04cec6b01b..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/NotifyTopicChangedRequestHeader.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol.header; - -import org.apache.rocketmq.remoting.CommandCustomHeader; -import org.apache.rocketmq.remoting.annotation.CFNotNull; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; - -public class NotifyTopicChangedRequestHeader implements CommandCustomHeader { - @CFNotNull - private String topic; - - @Override - public void checkFields() throws RemotingCommandException { - - } - - public String getTopic() { - return topic; - } - - public void setTopic(String topic) { - this.topic = topic; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/ReplyMessageRequestHeader.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/ReplyMessageRequestHeader.java deleted file mode 100644 index e26c10915c..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/protocol/header/ReplyMessageRequestHeader.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol.header; - -import org.apache.rocketmq.remoting.CommandCustomHeader; -import org.apache.rocketmq.remoting.annotation.CFNotNull; -import org.apache.rocketmq.remoting.annotation.CFNullable; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; - -public class ReplyMessageRequestHeader implements CommandCustomHeader { - @CFNotNull - private String producerGroup; - @CFNotNull - private String topic; - @CFNotNull - private String defaultTopic; - @CFNotNull - private Integer defaultTopicQueueNums; - @CFNotNull - private Integer queueId; - @CFNotNull - private Integer sysFlag; - @CFNotNull - private Long bornTimestamp; - @CFNotNull - private Integer flag; - @CFNullable - private String properties; - @CFNullable - private Integer reconsumeTimes; - @CFNullable - private boolean unitMode = false; - - @CFNotNull - private String bornHost; - - @CFNotNull - private String storeHost; - - private long storeTimestamp; - - public String getBornHost() { - return bornHost; - } - - @Override - public void checkFields() throws RemotingCommandException { - } - - public String getProducerGroup() { - return producerGroup; - } - - public void setProducerGroup(String producerGroup) { - this.producerGroup = producerGroup; - } - - public String getTopic() { - return topic; - } - - public void setTopic(String topic) { - this.topic = topic; - } - - public String getDefaultTopic() { - return defaultTopic; - } - - public void setDefaultTopic(String defaultTopic) { - this.defaultTopic = defaultTopic; - } - - public Integer getDefaultTopicQueueNums() { - return defaultTopicQueueNums; - } - - public void setDefaultTopicQueueNums(Integer defaultTopicQueueNums) { - this.defaultTopicQueueNums = defaultTopicQueueNums; - } - - public Integer getQueueId() { - return queueId; - } - - public void setQueueId(Integer queueId) { - this.queueId = queueId; - } - - public Integer getSysFlag() { - return sysFlag; - } - - public void setSysFlag(Integer sysFlag) { - this.sysFlag = sysFlag; - } - - public Long getBornTimestamp() { - return bornTimestamp; - } - - public void setBornTimestamp(Long bornTimestamp) { - this.bornTimestamp = bornTimestamp; - } - - public Integer getFlag() { - return flag; - } - - public void setFlag(Integer flag) { - this.flag = flag; - } - - public String getProperties() { - return properties; - } - - public void setProperties(String properties) { - this.properties = properties; - } - - public Integer getReconsumeTimes() { - return reconsumeTimes; - } - - public void setReconsumeTimes(Integer reconsumeTimes) { - this.reconsumeTimes = reconsumeTimes; - } - - public boolean isUnitMode() { - return unitMode; - } - - public void setUnitMode(boolean isUnitMode) { - this.unitMode = isUnitMode; - } - - public void setBornHost(String bornHost) { - this.bornHost = bornHost; - } - - public String getStoreHost() { - return storeHost; - } - - public void setStoreHost(String storeHost) { - this.storeHost = storeHost; - } - - public long getStoreTimestamp() { - return storeTimestamp; - } - - public void setStoreTimestamp(long storeTimestamp) { - this.storeTimestamp = storeTimestamp; - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/util/DeFiBusRequestIDUtil.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/util/DeFiBusRequestIDUtil.java deleted file mode 100644 index ae2c9ddb55..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/util/DeFiBusRequestIDUtil.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.util; - -import java.util.UUID; - -public class DeFiBusRequestIDUtil { - public static String createUniqueName(String prefix) { - if (prefix != null && prefix.trim().length() != 0) { - StringBuilder bldr = new StringBuilder(prefix); - bldr.append("/"); - bldr.append(UUID.randomUUID().toString()); - return bldr.toString(); - } else { - return UUID.randomUUID().toString(); - } - } -} diff --git a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/util/ReflectUtil.java b/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/util/ReflectUtil.java deleted file mode 100644 index 11ee6fd0c6..0000000000 --- a/eventmesh-store/defibus-common/src/main/java/cn/webank/defibus/common/util/ReflectUtil.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.util; - -import cn.webank.defibus.common.exception.DeFiBusRuntimeException; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class ReflectUtil { - public static void setSimpleProperty(Class c, Object instance, String proName, Object value) { - try { - Field field4pro = c.getDeclaredField(proName); - field4pro.setAccessible(true); - field4pro.set(instance, value); - } catch (NoSuchFieldException e) { - throw new DeFiBusRuntimeException("set property fail", e); - } catch (IllegalAccessException e) { - throw new DeFiBusRuntimeException("set property fail", e); - } catch (Exception e) { - throw new DeFiBusRuntimeException("set property fail", e); - } - } - - public static Object getSimpleProperty(Class c, Object instance, String proName) { - Object value = null; - try { - Field field4pro = c.getDeclaredField(proName); - field4pro.setAccessible(true); - value = field4pro.get(instance); - } catch (NoSuchFieldException e) { - throw new DeFiBusRuntimeException("get property fail", e); - } catch (IllegalAccessException e) { - throw new DeFiBusRuntimeException("get property fail", e); - } catch (Exception e) { - throw new DeFiBusRuntimeException("get property fail", e); - } - - return value; - } - - public static void invokeMethod(Class c, Object instance, String methodName) { - try { - Method method4bean = c.getDeclaredMethod(methodName); - method4bean.setAccessible(true); - method4bean.invoke(instance); - } catch (IllegalAccessException e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } catch (InvocationTargetException e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } catch (NoSuchMethodException e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } catch (Exception e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } - } - - public static Object invokeMethodWithReturn(Class c, Object instance, String methodName) { - Object result = null; - try { - Method method4bean = c.getDeclaredMethod(methodName); - method4bean.setAccessible(true); - result = method4bean.invoke(instance); - } catch (IllegalAccessException e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } catch (InvocationTargetException e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } catch (NoSuchMethodException e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } catch (Exception e) { - throw new DeFiBusRuntimeException("invokeMethod fail", e); - } - - return result; - } - - public static void invokeMethodByParams(Method method, Object instance, Object... params) { - try { - method.invoke(instance, params); - } catch (IllegalAccessException e) { - throw new DeFiBusRuntimeException("invokeMethodByParams fail", e); - } catch (InvocationTargetException e) { - throw new DeFiBusRuntimeException("invokeMethodByParams fail", e); - } catch (Exception e) { - throw new DeFiBusRuntimeException("invokeMethodByParams fail", e); - } - } - - @SuppressWarnings("unchecked") - public static Method getMethodByName(Class c, String methodName) { - try { - Method[] methods = c.getDeclaredMethods(); - if (methods == null) { - return null; - } - - for (Method method : methods) { - if (method.getName().equalsIgnoreCase(methodName)) { - Method declaredMethod = c.getDeclaredMethod(methodName, method.getParameterTypes()); - declaredMethod.setAccessible(true); - return method; - } - } - } catch (NoSuchMethodException e) { - throw new DeFiBusRuntimeException("getMethodByName fail", e); - } catch (Exception e) { - throw new DeFiBusRuntimeException("getMethodByName fail", e); - } - return null; - } -} diff --git a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/DeFiBusBrokerConfigTest.java b/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/DeFiBusBrokerConfigTest.java deleted file mode 100644 index 961f36d467..0000000000 --- a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/DeFiBusBrokerConfigTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common; - -import org.junit.Test; - -import static org.junit.Assert.assertTrue; - -public class DeFiBusBrokerConfigTest { - - @Test - public void testDeFiBusBrokerConfigDefaultValue() throws Exception { - DeFiBusBrokerConfig deFiBusBrokerConfig = new DeFiBusBrokerConfig(); - assertTrue(deFiBusBrokerConfig.getSendReplyMessageThreadPoolNums() == 64); - assertTrue(deFiBusBrokerConfig.getPushReplyMessageThreadPoolNums() == 64); - assertTrue(deFiBusBrokerConfig.getSendReplyThreadPoolQueueCapacity() == 10000); - assertTrue(deFiBusBrokerConfig.isRejectSendWhenMaxDepth() == true); - assertTrue(deFiBusBrokerConfig.isRedirectMessageEnable() == true); - assertTrue(deFiBusBrokerConfig.isAutoUpdateDepth() == true); - assertTrue(deFiBusBrokerConfig.getDepthCheckInterval() == 30 * 1000); - } -} diff --git a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/admin/DeFiBusConsumeStatsTest.java b/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/admin/DeFiBusConsumeStatsTest.java deleted file mode 100644 index 3419fab244..0000000000 --- a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/admin/DeFiBusConsumeStatsTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.admin; - -import java.util.HashMap; -import org.apache.rocketmq.common.message.MessageQueue; -import org.junit.Test; - -import static org.junit.Assert.assertTrue; - -public class DeFiBusConsumeStatsTest { - private String topic = "topic"; - private String brokerName = "brokerName"; - private HashMap offsetTable = new HashMap(); - private DeFiBusConsumeStats deFiBusConsumeStats = new DeFiBusConsumeStats(); - - @Test - public void testComputeTotalDiff() throws Exception { - long totalDiff = createOffsetTable(10); - deFiBusConsumeStats.setOffsetTable(offsetTable); - long i = deFiBusConsumeStats.computeTotalDiff(); - assertTrue(totalDiff == deFiBusConsumeStats.computeTotalDiff()); - } - - private long createOffsetTable(int queueSize) { - long totalDiff = 0; - for (int i = 0; i < queueSize; i++) { - DeFiBusOffsetWrapper wrapper = new DeFiBusOffsetWrapper(); - wrapper.setBrokerOffset(queueSize); - wrapper.setConsumerOffset(i); - long temp = queueSize - i; - totalDiff += temp; - offsetTable.put(new MessageQueue(topic, brokerName, i), wrapper); - - } - return totalDiff; - } -} diff --git a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/protocol/DeFiBusTopicConfigTest.java b/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/protocol/DeFiBusTopicConfigTest.java deleted file mode 100644 index 36c0ff1b98..0000000000 --- a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/protocol/DeFiBusTopicConfigTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.protocol; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertTrue; - -public class DeFiBusTopicConfigTest { - private String topic = "topicA"; - - @Test - public void testEcodeAndDecode() throws Exception { - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(topic); - String ecodeMsg = deFiBusTopicConfig.encode(); - assertTrue(deFiBusTopicConfig.decode(ecodeMsg)); - } - - @Test - public void testAttribute() { - DeFiBusTopicConfig deFiBusTopicConfig = new DeFiBusTopicConfig(); - deFiBusTopicConfig.setTopicName(topic); - deFiBusTopicConfig.setMaxQueueDepth(500); - assertThat(deFiBusTopicConfig.getTopicName()).isEqualTo(topic); - assertThat(deFiBusTopicConfig.getMaxQueueDepth()).isEqualTo(500); - } -} diff --git a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/util/DeFiBusRequestIDUtilTest.java b/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/util/DeFiBusRequestIDUtilTest.java deleted file mode 100644 index 447f10fdea..0000000000 --- a/eventmesh-store/defibus-common/src/test/java/cn/webank/defibus/common/util/DeFiBusRequestIDUtilTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.common.util; - -import org.junit.Test; - -import static org.junit.Assert.assertTrue; - -public class DeFiBusRequestIDUtilTest { - - @Test - public void testCreateUniqueNameByPrefix() { - String prefix = "w"; - String UniqueName = DeFiBusRequestIDUtil.createUniqueName(prefix); - String prefix2 = UniqueName.split("/")[0]; - assertTrue(prefix.equals(prefix2)); - } - - @Test(expected = ArrayIndexOutOfBoundsException.class) - public void testCreateUniqueNameNoPrefix() { - String UniqueName = DeFiBusRequestIDUtil.createUniqueName(null); - String prefix2 = UniqueName.split("/")[1]; - } -} diff --git a/eventmesh-store/defibus-common/src/test/resources/logback.xml b/eventmesh-store/defibus-common/src/test/resources/logback.xml deleted file mode 100644 index d2bb771a7f..0000000000 --- a/eventmesh-store/defibus-common/src/test/resources/logback.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - ../logs/broker_default.log - - - %d{yyy-MM-dd HH:mm:ss,GMT+8} %p %t - %m%n - UTF-8 - - - - true - - - - ../logs/brokder-default-%d{yyyy-MM-dd_MM}.%i.log - - 1MB - 10 - 20GB - - - - - - - - - - diff --git a/eventmesh-store/defibus-examples/build.gradle b/eventmesh-store/defibus-examples/build.gradle deleted file mode 100644 index 2c739da0f4..0000000000 --- a/eventmesh-store/defibus-examples/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -List Log = [ - "org.slf4j:slf4j-log4j12:1.7.12", - "log4j:log4j:1.2.17" -] - -dependencies { - compile project(":defibus-client") - compile project(":defibus-common") - compile "org.apache.rocketmq:rocketmq-common:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-client:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-remoting:$project.rocketmqVersion" - compile Log -} diff --git a/eventmesh-store/defibus-examples/conf/checkstyle.xml b/eventmesh-store/defibus-examples/conf/checkstyle.xml deleted file mode 100644 index 3d024111bc..0000000000 --- a/eventmesh-store/defibus-examples/conf/checkstyle.xml +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/RequestProducer.java b/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/RequestProducer.java deleted file mode 100644 index 8cccab04fd..0000000000 --- a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/RequestProducer.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.examples.rpc; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.producer.DeFiBusProducer; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RequestProducer { - private static final Logger logger = LoggerFactory.getLogger(RequestProducer.class); - - public static void main(String[] args) throws MQClientException { - DeFiBusClientConfig clientConfig = new DeFiBusClientConfig(); - clientConfig.setClusterPrefix("XL"); - - DeFiBusProducer deFiBusProducer = new DeFiBusProducer(clientConfig); - deFiBusProducer.setNamesrvAddr("127.0.0.1:9876"); - - deFiBusProducer.start(); - - long ttl = 2000; - String topic = "RequestTopic"; - - final String content = "Hello world"; - Message msg = new Message(topic, content.getBytes()); - try { - long time = System.currentTimeMillis(); - - Message reply = deFiBusProducer.request(msg, ttl); - long cost = System.currentTimeMillis() - time; - - if (reply == null) { - logger.warn("request timeout. "); - } else { - logger.info("request success. cost: {}ms. reply msg: {}", cost, reply); - } - } catch (MQClientException | RemotingException | InterruptedException | MQBrokerException e) { - logger.warn("{}", e); - } catch (Exception e) { - logger.warn("{}", e); - } finally { - // normally , we ONLY shutdown DeFiBusProducer when the application exits. In this sample, we shutdown the producer when message is sent. - deFiBusProducer.shutdown(); - } - } -} diff --git a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/ResponseConsumer.java b/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/ResponseConsumer.java deleted file mode 100644 index ff585db9dd..0000000000 --- a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/ResponseConsumer.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.examples.rpc; - -import java.util.List; - -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.client.producer.SendCallback; -import org.apache.rocketmq.client.producer.SendResult; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.client.common.DeFiBusClientUtil; -import cn.webank.defibus.common.DeFiBusConstant; -import cn.webank.defibus.consumer.DeFiBusMessageListenerConcurrently; -import cn.webank.defibus.consumer.DeFiBusPushConsumer; -import cn.webank.defibus.producer.DeFiBusProducer; - -public class ResponseConsumer { - private static final Logger logger = LoggerFactory.getLogger(ResponseConsumer.class); - - public static void main(String[] args) throws MQClientException { - String topic = "RequestTopic"; - DeFiBusClientConfig deFiBusClientConfig = new DeFiBusClientConfig(); - deFiBusClientConfig.setConsumerGroup("Your-group-name"); - deFiBusClientConfig.setPullBatchSize(32); - deFiBusClientConfig.setThreadPoolCoreSize(12); - deFiBusClientConfig.setClusterPrefix("XL"); - DeFiBusProducer deFiBusProducer = new DeFiBusProducer(deFiBusClientConfig); - deFiBusProducer.setNamesrvAddr("127.0.0.1:9876"); - deFiBusProducer.start(); - DeFiBusPushConsumer deFiBusPushConsumer = new DeFiBusPushConsumer(deFiBusClientConfig); - deFiBusPushConsumer.setNamesrvAddr("127.0.0.1:9876"); - deFiBusPushConsumer.registerMessageListener(new DeFiBusMessageListenerConcurrently() { - @Override - public ConsumeConcurrentlyStatus handleMessage(List msgs, ConsumeConcurrentlyContext context) { - for (MessageExt msg : msgs) { - String uniqueId = msg.getUserProperty(DeFiBusConstant.PROPERTY_RR_REQUEST_ID); - if (uniqueId == null) { - logger.info("REQUEST_ID is null from the request msg, will not reply this constant..."); - } else { - try { - logger.info("begin handle: " + msg.toString()); - Message replyMsg = DeFiBusClientUtil.createReplyMessage(msg, ("I am replying content").getBytes()); - deFiBusProducer.reply(replyMsg, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - logger.info("reply success. {}", msg.toString()); - } - @Override - public void onException(Throwable e) { - logger.info("reply fail. {}", msg.toString(), e); - } - }); - } catch (InterruptedException | RemotingException | MQClientException | MQBrokerException e) { - logger.warn("{}", e); - } - } - } - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - }); - deFiBusPushConsumer.subscribe(topic); - deFiBusPushConsumer.start(); - - //shutdown the consumer when application exits. - Runtime.getRuntime().addShutdownHook(new Thread(){ - @Override - public void run() { - deFiBusPushConsumer.shutdown(); - } - }); - } -} diff --git a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/ResponseConsumerAutoReply.java b/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/ResponseConsumerAutoReply.java deleted file mode 100644 index 36eb9c594e..0000000000 --- a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/rpc/ResponseConsumerAutoReply.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.examples.rpc; - -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.consumer.ConsumeFromWhere; -import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.consumer.DeFiBusMessageListenerConcurrentlyWithReply; -import cn.webank.defibus.consumer.DeFiBusPushConsumer; -import cn.webank.defibus.producer.DeFiBusProducer; - -/** - * the example of responder with auto reply - */ -public class ResponseConsumerAutoReply { - public static void main(String[] args) { - DeFiBusClientConfig deFiBusClientConfig = new DeFiBusClientConfig(); - deFiBusClientConfig.setNamesrvAddr(""); - DeFiBusProducer deFiBusProducer = new DeFiBusProducer(deFiBusClientConfig); - DeFiBusPushConsumer deFiBusPushConsumer = new DeFiBusPushConsumer(deFiBusClientConfig); - deFiBusPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET); - deFiBusPushConsumer.getDefaultMQPushConsumer().setMessageModel(MessageModel.CLUSTERING); - deFiBusPushConsumer.registerMessageListener(new DeFiBusMessageListenerConcurrentlyWithReply(deFiBusProducer) { - @Override - public String handleMessage(MessageExt msg, ConsumeConcurrentlyContext context) { - //1. biz handle logic - - //2. create reply content - - return "A reply message content"; - } - }); - try { - deFiBusProducer.start(); - deFiBusPushConsumer.subscribe("REQUEST_REPLY_TOPIC"); - deFiBusPushConsumer.start(); - } catch (MQClientException e) { - e.printStackTrace(); - } finally { - deFiBusProducer.shutdown(); - } - - //shutdown the consumer when application exits. - Runtime.getRuntime().addShutdownHook(new Thread(){ - @Override - public void run() { - deFiBusPushConsumer.shutdown(); - } - }); - - } -} diff --git a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/simple/PubProducer.java b/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/simple/PubProducer.java deleted file mode 100644 index aab3f60776..0000000000 --- a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/simple/PubProducer.java +++ /dev/null @@ -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. - */ - -package cn.webank.defibus.examples.simple; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.producer.DeFiBusProducer; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PubProducer { - private static final Logger logger = LoggerFactory.getLogger(PubProducer.class); - - public static void main(String[] args) throws MQClientException { - DeFiBusClientConfig clientConfig = new DeFiBusClientConfig(); - clientConfig.setClusterPrefix("XL"); - - DeFiBusProducer deFiBusProducer = new DeFiBusProducer(clientConfig); - deFiBusProducer.setNamesrvAddr("127.0.0.1:9876"); - deFiBusProducer.start(); - - String topic = "PublishTopic"; - final String content = "Hello world"; - Message msg = new Message(topic, content.getBytes()); - try { - deFiBusProducer.publish(msg); - } catch (MQClientException | RemotingException | InterruptedException e) { - logger.warn("{}", e); - } finally { - // normally , we only shutdown DeFiBusProducer when the application exits. In this sample, we shutdown the producer when message is sent. - deFiBusProducer.shutdown(); - } - } -} diff --git a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/simple/SubConsumer.java b/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/simple/SubConsumer.java deleted file mode 100644 index 3c8af43441..0000000000 --- a/eventmesh-store/defibus-examples/src/main/java/cn/webank/defibus/examples/simple/SubConsumer.java +++ /dev/null @@ -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. - */ - -package cn.webank.defibus.examples.simple; - -import java.util.List; - -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.message.MessageExt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cn.webank.defibus.client.common.DeFiBusClientConfig; -import cn.webank.defibus.consumer.DeFiBusMessageListenerConcurrently; -import cn.webank.defibus.consumer.DeFiBusPushConsumer; -import cn.webank.defibus.producer.DeFiBusProducer; - -public class SubConsumer { - private static final Logger logger = LoggerFactory.getLogger(SubConsumer.class); - - public static void main(String[] args) throws MQClientException { - String topic = "PublishTopic"; - DeFiBusClientConfig deFiBusClientConfig = new DeFiBusClientConfig(); - deFiBusClientConfig.setConsumerGroup("Your-group-name"); - deFiBusClientConfig.setPullBatchSize(32); - deFiBusClientConfig.setThreadPoolCoreSize(12); - deFiBusClientConfig.setClusterPrefix("XL"); - - DeFiBusProducer deFiBusProducer = new DeFiBusProducer(deFiBusClientConfig); - deFiBusProducer.setNamesrvAddr("127.0.0.1:9876"); - deFiBusProducer.start(); - - DeFiBusPushConsumer deFiBusPushConsumer = new DeFiBusPushConsumer(deFiBusClientConfig); - deFiBusPushConsumer.setNamesrvAddr("127.0.0.1:9876"); - deFiBusPushConsumer.registerMessageListener(new DeFiBusMessageListenerConcurrently() { - @Override - public ConsumeConcurrentlyStatus handleMessage(List msgs, ConsumeConcurrentlyContext context) { - for (MessageExt msg : msgs) { - logger.info("begin handle: " + msg.toString()); - } - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } - }); - - deFiBusPushConsumer.subscribe(topic); - deFiBusPushConsumer.start(); - - //shutdown the consumer when application exits. - Runtime.getRuntime().addShutdownHook(new Thread(){ - @Override - public void run() { - deFiBusPushConsumer.shutdown(); - } - }); - - } -} diff --git a/eventmesh-store/defibus-examples/src/main/resources/log4j.xml b/eventmesh-store/defibus-examples/src/main/resources/log4j.xml deleted file mode 100644 index e5e5006a47..0000000000 --- a/eventmesh-store/defibus-examples/src/main/resources/log4j.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-namesrv/.gitignore b/eventmesh-store/defibus-namesrv/.gitignore deleted file mode 100644 index c1285b3799..0000000000 --- a/eventmesh-store/defibus-namesrv/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -/bin/ -/.git/ -/.gradle/ -/.settings/ -/logs -.DS_Store -.*.swp -*.ipr -*.iml -*.iws -*.class -*.log -.idea -build -.classpath -.project -/test-output/ -/dist -/.pmd -/classes -/logs -/out \ No newline at end of file diff --git a/eventmesh-store/defibus-namesrv/build.gradle b/eventmesh-store/defibus-namesrv/build.gradle deleted file mode 100644 index 22807bb8b9..0000000000 --- a/eventmesh-store/defibus-namesrv/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//apply plugin: 'java' - -dependencies { - compile project(":defibus-common") - testCompile project(":defibus-common") - - compile "ch.qos.logback:logback-core:1.2.3" - compile "ch.qos.logback:logback-classic:1.2.3" - - compile "org.apache.rocketmq:rocketmq-broker:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-namesrv:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-client:$project.rocketmqVersion" -} \ No newline at end of file diff --git a/eventmesh-store/defibus-namesrv/conf/checkstyle.xml b/eventmesh-store/defibus-namesrv/conf/checkstyle.xml deleted file mode 100644 index 3d024111bc..0000000000 --- a/eventmesh-store/defibus-namesrv/conf/checkstyle.xml +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-namesrv/src/main/java/cn/webank/defibus/namesrv/DeFiBusNamesrvStartup.java b/eventmesh-store/defibus-namesrv/src/main/java/cn/webank/defibus/namesrv/DeFiBusNamesrvStartup.java deleted file mode 100644 index ea9142d10d..0000000000 --- a/eventmesh-store/defibus-namesrv/src/main/java/cn/webank/defibus/namesrv/DeFiBusNamesrvStartup.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.namesrv; - -import org.apache.rocketmq.namesrv.NamesrvStartup; - -public class DeFiBusNamesrvStartup { - - private static final String DEFAULT_ROCKETMQ_HOME_PATH = "."; - - //init default rocketmq home path. - public static void initRocketMQHomePath() { - String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV)); - if (StringUtils.isBlank(rocketmqHome)) { - System.setProperty(MixAll.ROCKETMQ_HOME_PROPERTY, DEFAULT_ROCKETMQ_HOME_PATH); - } - } - - - public static void main(String[] args) { - NamesrvStartup.main0(args); - } -} diff --git a/eventmesh-store/defibus-tools/.gitignore b/eventmesh-store/defibus-tools/.gitignore deleted file mode 100644 index 404407627e..0000000000 --- a/eventmesh-store/defibus-tools/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -bin -.git -.gradle -.settings -logs -.DS_Store -.*.swp -*.ipr -*.iml -*.iws -*.class -*.log -.idea -build -.classpath -.project -test-output -dist -.pmd -classes -out diff --git a/eventmesh-store/defibus-tools/build.gradle b/eventmesh-store/defibus-tools/build.gradle deleted file mode 100644 index 42f6a2d403..0000000000 --- a/eventmesh-store/defibus-tools/build.gradle +++ /dev/null @@ -1,32 +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. - */ - -apply plugin: 'java' - -dependencies { - compile project(":defibus-common"), project(":defibus-client") - testCompile project(":defibus-common"), project(":defibus-client") - - compile "org.springframework:spring-beans:4.3.9.RELEASE" - compile "ch.qos.logback:logback-core:1.2.3" - compile "ch.qos.logback:logback-classic:1.2.3" - - compile "org.apache.rocketmq:rocketmq-client:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-srvutil:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-store:$project.rocketmqVersion" - compile "org.apache.rocketmq:rocketmq-tools:$project.rocketmqVersion" -} \ No newline at end of file diff --git a/eventmesh-store/defibus-tools/conf/checkstyle.xml b/eventmesh-store/defibus-tools/conf/checkstyle.xml deleted file mode 100644 index 3d024111bc..0000000000 --- a/eventmesh-store/defibus-tools/conf/checkstyle.xml +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/admin/DeFiBusAdminExt.java b/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/admin/DeFiBusAdminExt.java deleted file mode 100644 index 68abd18255..0000000000 --- a/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/admin/DeFiBusAdminExt.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.tools.admin; - -import org.apache.rocketmq.remoting.RPCHook; -import org.apache.rocketmq.tools.admin.DefaultMQAdminExt; - -public class DeFiBusAdminExt extends DefaultMQAdminExt { - public DeFiBusAdminExt(RPCHook rpcHook, long timeoutMillis) { - super(rpcHook, timeoutMillis); - } -} diff --git a/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/command/DeFiBusAdminStartup.java b/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/command/DeFiBusAdminStartup.java deleted file mode 100644 index 561fa431d7..0000000000 --- a/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/command/DeFiBusAdminStartup.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.tools.command; - -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.joran.JoranConfigurator; -import ch.qos.logback.core.joran.spi.JoranException; -import cn.webank.defibus.tools.command.topic.UpdateTopicPermSubCommand; -import com.alibaba.fastjson.JSONObject; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.PosixParser; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.acl.common.AclClientRPCHook; -import org.apache.rocketmq.acl.common.AclUtils; -import org.apache.rocketmq.acl.common.SessionCredentials; -import org.apache.rocketmq.common.MQVersion; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.remoting.RPCHook; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.apache.rocketmq.srvutil.ServerUtil; -import org.apache.rocketmq.tools.command.SubCommand; -import org.apache.rocketmq.tools.command.broker.*; -import org.apache.rocketmq.tools.command.cluster.CLusterSendMsgRTCommand; -import org.apache.rocketmq.tools.command.cluster.ClusterListSubCommand; -import org.apache.rocketmq.tools.command.connection.ConsumerConnectionSubCommand; -import org.apache.rocketmq.tools.command.connection.ProducerConnectionSubCommand; -import org.apache.rocketmq.tools.command.consumer.*; -import org.apache.rocketmq.tools.command.message.*; -import org.apache.rocketmq.tools.command.namesrv.*; -import org.apache.rocketmq.tools.command.offset.CloneGroupOffsetCommand; -import org.apache.rocketmq.tools.command.offset.ResetOffsetByTimeCommand; -import org.apache.rocketmq.tools.command.queue.QueryConsumeQueueCommand; -import org.apache.rocketmq.tools.command.stats.StatsAllSubCommand; -import org.apache.rocketmq.tools.command.topic.*; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -public class DeFiBusAdminStartup { - protected static List subCommandList = new ArrayList(); - - public static void main(String[] args) { - main0(args); - } - - public static void main0(String[] args) { - System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION)); - - initCommand(); - - try { - initLogback(); - switch (args.length) { - case 0: - printHelp(); - break; - case 2: - if (args[0].equals("help")) { - SubCommand cmd = findSubCommand(args[1]); - if (cmd != null) { - Options options = ServerUtil.buildCommandlineOptions(new Options()); - options = cmd.buildCommandlineOptions(options); - if (options != null) { - ServerUtil.printCommandLineHelp("mqadmin " + cmd.commandName(), options); - } - } else { - System.out.printf("The sub command %s not exist.%n", args[1]); - } - break; - } - case 1: - default: - SubCommand cmd = findSubCommand(args[0]); - if (cmd != null) { - String[] subargs = parseSubArgs(args); - - Options options = ServerUtil.buildCommandlineOptions(new Options()); - final CommandLine commandLine = - ServerUtil.parseCmdLine("mqadmin " + cmd.commandName(), subargs, cmd.buildCommandlineOptions(options), - new PosixParser()); - if (null == commandLine) { - return; - } - - if (commandLine.hasOption('n')) { - String namesrvAddr = commandLine.getOptionValue('n'); - System.setProperty(MixAll.NAMESRV_ADDR_PROPERTY, namesrvAddr); - } - - cmd.execute(commandLine, options, getAclRPCHook()); - } else { - System.out.printf("The sub command %s not exist.%n", args[0]); - } - break; - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void initCommand() { - initCommand(new UpdateTopicSubCommand()); - initCommand(new DeleteTopicSubCommand()); - initCommand(new UpdateSubGroupSubCommand()); - initCommand(new DeleteSubscriptionGroupCommand()); - initCommand(new UpdateBrokerConfigSubCommand()); - initCommand(new UpdateTopicPermSubCommand()); - - initCommand(new TopicRouteSubCommand()); - initCommand(new TopicStatusSubCommand()); - initCommand(new TopicClusterSubCommand()); - - initCommand(new BrokerStatusSubCommand()); - initCommand(new QueryMsgByIdSubCommand()); - initCommand(new QueryMsgByKeySubCommand()); - initCommand(new QueryMsgByUniqueKeySubCommand()); - initCommand(new QueryMsgByOffsetSubCommand()); - - initCommand(new PrintMessageSubCommand()); - initCommand(new PrintMessageByQueueCommand()); - initCommand(new SendMsgStatusCommand()); - initCommand(new BrokerConsumeStatsSubCommad()); - - initCommand(new ProducerConnectionSubCommand()); - initCommand(new ConsumerConnectionSubCommand()); - initCommand(new ConsumerProgressSubCommand()); - initCommand(new ConsumerStatusSubCommand()); - initCommand(new CloneGroupOffsetCommand()); - - initCommand(new ClusterListSubCommand()); - initCommand(new TopicListSubCommand()); - - initCommand(new UpdateKvConfigCommand()); - initCommand(new DeleteKvConfigCommand()); - - initCommand(new WipeWritePermSubCommand()); - initCommand(new ResetOffsetByTimeCommand()); - - initCommand(new UpdateOrderConfCommand()); - initCommand(new CleanExpiredCQSubCommand()); - initCommand(new CleanUnusedTopicCommand()); - - initCommand(new StartMonitoringSubCommand()); - initCommand(new StatsAllSubCommand()); - - initCommand(new AllocateMQSubCommand()); - - initCommand(new CheckMsgSendRTCommand()); - initCommand(new CLusterSendMsgRTCommand()); - - initCommand(new GetNamesrvConfigCommand()); - initCommand(new UpdateNamesrvConfigCommand()); - initCommand(new GetBrokerConfigCommand()); - - initCommand(new QueryConsumeQueueCommand()); - initCommand(new SendMessageCommand()); - initCommand(new ConsumeMessageCommand()); - } - - private static void initLogback() throws JoranException { - String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV)); - - LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); - JoranConfigurator configurator = new JoranConfigurator(); - configurator.setContext(lc); - lc.reset(); - configurator.doConfigure(rocketmqHome + "/conf/logback_tools.xml"); - } - - private static void printHelp() { - System.out.printf("The most commonly used mqadmin commands are:%n"); - for (SubCommand cmd : subCommandList) { - System.out.printf(" %-20s %s%n", cmd.commandName(), cmd.commandDesc()); - } - - System.out.printf("%nSee 'mqadmin help ' for more information on a specific command.%n"); - } - - private static SubCommand findSubCommand(final String name) { - for (SubCommand cmd : subCommandList) { - if (cmd.commandName().toUpperCase().equals(name.toUpperCase())) { - return cmd; - } - } - - return null; - } - - private static String[] parseSubArgs(String[] args) { - if (args.length > 1) { - String[] result = new String[args.length - 1]; - for (int i = 0; i < args.length - 1; i++) { - result[i] = args[i + 1]; - } - return result; - } - return null; - } - - public static void initCommand(SubCommand command) { - subCommandList.add(command); - } - - public static RPCHook getAclRPCHook() { - String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV)); - String fileName = "/conf/tools.yml"; - JSONObject yamlDataObject = AclUtils.getYamlDataObject(fileHome + fileName, - JSONObject.class); - - if (yamlDataObject == null || yamlDataObject.isEmpty()) { - System.out.printf(" Cannot find conf file %s, acl is not be enabled.%n", fileHome + fileName); - return null; - } - - String accessKey = yamlDataObject.getString("accessKey"); - String secretKey = yamlDataObject.getString("secretKey"); - - if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(secretKey)) { - System.out.printf("AccessKey or secretKey is blank, the acl is not enabled.%n"); - return null; - } - return new AclClientRPCHook(new SessionCredentials(accessKey, secretKey)); - } -} diff --git a/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/command/topic/UpdateTopicPermSubCommand.java b/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/command/topic/UpdateTopicPermSubCommand.java deleted file mode 100644 index 0db2518425..0000000000 --- a/eventmesh-store/defibus-tools/src/main/java/cn/webank/defibus/tools/command/topic/UpdateTopicPermSubCommand.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.webank.defibus.tools.command.topic; - -import cn.webank.defibus.tools.admin.DeFiBusAdminExt; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.io.FileUtils; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.common.protocol.body.ClusterInfo; -import org.apache.rocketmq.common.protocol.route.BrokerData; -import org.apache.rocketmq.common.protocol.route.QueueData; -import org.apache.rocketmq.common.protocol.route.TopicRouteData; -import org.apache.rocketmq.remoting.RPCHook; -import org.apache.rocketmq.remoting.exception.RemotingConnectException; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.apache.rocketmq.remoting.exception.RemotingSendRequestException; -import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; -import org.apache.rocketmq.tools.command.SubCommand; - -import java.io.File; -import java.util.*; - -public class UpdateTopicPermSubCommand implements SubCommand { - ClusterInfo clusterInfo = null; - - @Override - public String commandName() { - return "updateTopicPerm"; - } - - @Override - public String commandDesc() { - return "Update topic perm"; - } - - @Override - public Options buildCommandlineOptions(Options options) { - Option opt = new Option("b", "brokerAddr", true, "create topic to which broker"); - opt.setRequired(false); - options.addOption(opt); - - opt = new Option("t", "topic", true, "topic name"); - opt.setRequired(false); - options.addOption(opt); - - opt = new Option("f", "topicList", true, "read the topic list by file path, split with '\\n'"); - opt.setRequired(false); - options.addOption(opt); - - opt = new Option("s", "sleetTime", true, "sleep time between create two topic(ms)"); - opt.setRequired(false); - options.addOption(opt); - - opt = new Option("p", "perm", true, "set topic's permission(2|4|6), intro[2:W; 4:R; 6:RW]"); - opt.setRequired(true); - options.addOption(opt); - - return options; - } - - @Override - public void execute(final CommandLine commandLine, final Options options, RPCHook rpcHook) { - DeFiBusAdminExt deFiBusAdminExt = new DeFiBusAdminExt(rpcHook, 3000L); - deFiBusAdminExt.setInstanceName(Long.toString(System.currentTimeMillis())); - try { - deFiBusAdminExt.start(); - TopicConfig topicConfig = new TopicConfig(); - - long sleepTime = 1000; - if (commandLine.hasOption("s")) { - sleepTime = Long.parseLong(commandLine.getOptionValue("s").trim()); - } - - List topicList = new ArrayList<>(); - if (commandLine.hasOption("t")) { - String[] topicArr = commandLine.getOptionValue("t").trim().split(";"); - topicList = Arrays.asList(topicArr); - } else if (commandLine.hasOption("f")) { - String path = commandLine.getOptionValue("f").trim(); - topicList = FileUtils.readLines(new File(path)); - } - for (String topic : topicList) { - try { - updateTopicPerm(topic, deFiBusAdminExt, topicConfig, sleepTime, commandLine); - } catch (Exception e) { - System.out.println("[WARN] update topic[" + topic + "] perm failed ,exception info: " + e.getMessage()); - try { - updateTopicPerm(topic, deFiBusAdminExt, topicConfig, sleepTime, commandLine); - } catch (Exception e1) { - System.out.println("[WARN] try again ,update topic[" + topic + "] perm failed,exception info: " + e1.getMessage()); - } - } - } -// ServerUtil.printCommandLineHelp("mqadmin " + this.commandName(), options); - } catch (Exception e) { - e.printStackTrace(); - } finally { - deFiBusAdminExt.shutdown(); - } - return; - } - - private void updateTopicPerm(String topic, DeFiBusAdminExt deFiBusAdminExt, TopicConfig topicConfig, long sleepTime, CommandLine commandLine) throws InterruptedException, MQClientException, RemotingException, MQBrokerException { - TopicRouteData topicRouteData = deFiBusAdminExt.examineTopicRouteInfo(topic); - assert topicRouteData != null; - List queueDatas = topicRouteData.getQueueDatas(); - assert queueDatas != null && queueDatas.size() > 0; - - Set brokerAddrs = new HashSet<>(); - if (commandLine.hasOption('b')) { - brokerAddrs.add(commandLine.getOptionValue('b').trim()); - } else { - brokerAddrs = fetchMasterAddrByTopic(deFiBusAdminExt, topic); - } - if (brokerAddrs.size() == 0) { - System.out.println("[WARN] can not get brokerAddr for topic[" + topic + "]"); - return; - } - for (String brokerAddr : brokerAddrs) { - String brokerName = getBrokerNameByBrokerAddr(deFiBusAdminExt, brokerAddr); - QueueData queueData = null; - for (QueueData queueDataTemp : queueDatas) { - if (brokerName.equals(queueDataTemp.getBrokerName())) { - queueData = queueDataTemp; - break; - } - } - if (queueData == null) { - System.out.println("[WARN] topic[" + topic + "] get queueData failed for brokerAddr[" + brokerAddr + "]"); - return; - } - topicConfig.setTopicName(topic); - topicConfig.setWriteQueueNums(queueData.getWriteQueueNums()); - topicConfig.setReadQueueNums(queueData.getReadQueueNums()); - topicConfig.setPerm(queueData.getPerm()); - topicConfig.setTopicSysFlag(queueData.getTopicSynFlag()); - - //new perm - int perm = Integer.parseInt(commandLine.getOptionValue("p").trim()); - int oldPerm = topicConfig.getPerm(); - if (perm == oldPerm) { - System.out.printf("new perm equals to the old one!%n"); - } - topicConfig.setPerm(perm); - deFiBusAdminExt.createAndUpdateTopicConfig(brokerAddr, topicConfig); - Thread.sleep(sleepTime); - System.out.printf("update topic[%s] perm from %s to %s in %s success.%n", topic, oldPerm, perm, brokerAddr); - } - } - - private Set fetchMasterAddrByTopic(DeFiBusAdminExt defaultMQAdminExt, String topic) throws RemotingException, MQClientException, InterruptedException { - Set masterSet = new HashSet<>(); - TopicRouteData topicRouteData = defaultMQAdminExt.examineTopicRouteInfo(topic); - for (BrokerData bd : topicRouteData.getBrokerDatas()) { - String masterAddr = bd.getBrokerAddrs().get(MixAll.MASTER_ID); - if (masterAddr != null) { - masterSet.add(masterAddr); - } else { - System.out.println("there is no master alive in " + bd.getBrokerName() + ", skip this group"); - } - } - - return masterSet; - } - - private String getBrokerNameByBrokerAddr(DeFiBusAdminExt deFiBusAdminExt, String brokerAddr) throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException { - String brokerName = null; - if (clusterInfo == null) { - clusterInfo = deFiBusAdminExt.examineBrokerClusterInfo(); - } - Map brokerDataMap = clusterInfo.getBrokerAddrTable(); - for (Map.Entry entry : brokerDataMap.entrySet()) { - Map brokerAddrs = entry.getValue().getBrokerAddrs(); - if (brokerAddrs.containsValue(brokerAddr)) { - brokerName = entry.getKey(); - break; - } - } - if (brokerName == null) { - System.out.println("can not get brokerName for brokerAddr[" + brokerAddr + "]"); - System.exit(-1); - } else { - System.out.println("brokerAddr[" + brokerAddr + "]'s name is " + brokerName); - } - return brokerName; - } -} diff --git a/eventmesh-store/gradle.properties b/eventmesh-store/gradle.properties deleted file mode 100644 index 022e772b7d..0000000000 --- a/eventmesh-store/gradle.properties +++ /dev/null @@ -1,24 +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. -# -group=cn.webank.defibus -version=1.0.0 -rocketmqVersion=4.4.0 -jdk=1.8 -snapshot=false -mavenUserName= -mavenPassword= -#org.gradle.java.home=C:\\Program Files\\Java\\jdk1.7.0_67 diff --git a/eventmesh-store/releasenotes.txt b/eventmesh-store/releasenotes.txt deleted file mode 100644 index 0d48a10a49..0000000000 --- a/eventmesh-store/releasenotes.txt +++ /dev/null @@ -1,9 +0,0 @@ --------------------------VERSION 1.0.0----------------------------- -1. implement of sync-request producer. -2. dark launch -3. circuit breaker mechanism -4. invoke service nearby -5. (tong cheng duo huo) -6. dynamic adjust queue -7. isolation mechanism -8. fault tolerant \ No newline at end of file diff --git a/eventmesh-store/script/broker_watchdog.sh b/eventmesh-store/script/broker_watchdog.sh deleted file mode 100644 index b0a051b098..0000000000 --- a/eventmesh-store/script/broker_watchdog.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -if [ ! -f "pid.file" ]; then - Result_pid="noPid" -else - Result_pid=`cat pid.file` -fi - - -Result=$(ps -ef|grep DeFiBusBrokerStartup|grep -v grep|grep $Result_pid) -if [ "" == "$Result" ] -then - export LANG=zh_CN.utf8 - export LC_ALL=zh_CN.UTF-8 - export LC_CTYPE=en_US.UTF-8 - ./runbroker.sh -fi diff --git a/eventmesh-store/script/namesrv_watchdog.sh b/eventmesh-store/script/namesrv_watchdog.sh deleted file mode 100644 index 098293677a..0000000000 --- a/eventmesh-store/script/namesrv_watchdog.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Result=$(ps -ef|grep NamesrvStartup|grep -v grep | awk '{print $2}') -if [ "" == "$Result" ] -then - export LANG=zh_CN.utf8 - export LC_ALL=zh_CN.UTF-8 - export LC_CTYPE=en_US.UTF-8 - ./runnamesrv.sh -fi diff --git a/eventmesh-store/script/runadmin.cmd b/eventmesh-store/script/runadmin.cmd deleted file mode 100644 index 61a11704fe..0000000000 --- a/eventmesh-store/script/runadmin.cmd +++ /dev/null @@ -1,32 +0,0 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! & EXIT /B 1 - -set "JAVA=%JAVA_HOME%\bin\java.exe" - -setlocal -set BASE_DIR=%~dp0 -set BASE_DIR=%BASE_DIR:~0,-1% -for %%d in (%BASE_DIR%) do set BASE_DIR=%%~dpd -set CLASSPATH=.;%BASE_DIR%conf;%CLASSPATH% -rem =========================================================================================== -rem JVM Configuration -rem =========================================================================================== -set "JAVA_OPT=%JAVA_OPT% -server -Xms1g -Xmx1g -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=128m" -set "JAVA_OPT=%JAVA_OPT% -Djava.ext.dirs="%BASE_DIR%\lib;%BASE_DIR%\apps";"%JAVA_HOME%\jre\lib\ext"" -set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%"" -"%JAVA%" %JAVA_OPT% cn.webank.defibus.tools.command.DeFiBusAdminStartup %* \ No newline at end of file diff --git a/eventmesh-store/script/runadmin.sh b/eventmesh-store/script/runadmin.sh deleted file mode 100644 index 4e19a72715..0000000000 --- a/eventmesh-store/script/runadmin.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -#=========================================================================================== -# Java Environment Setting -#=========================================================================================== -TMP_JAVA_HOME="/nemo/jdk8" - -function is_java8 { - local _java="$1" - [[ -x "$_java" ]] || return 1 - [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' ]] || return 2 - return 0 -} - -if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then - JAVA="$TMP_JAVA_HOME/bin/java" -elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then - JAVA="$JAVA_HOME/bin/java" -elif is_java8 "/nemo/jdk8/bin/java"; then - JAVA="/nemo/jdk8/bin/java"; -elif is_java8 "/nemo/jdk/bin/java"; then - JAVA="/nemo/jdk/bin/java"; -elif is_java8 "$(which java)"; then - JAVA="$(which java)" -else - echo -e "ERROR\t java(1.8) not found, operation abort." - exit 9; -fi - -echo "admin use java location= "$JAVA - -ROCKETMQ_HOME=`cd "./.." && pwd` -export ROCKETMQ_HOME - - -JAVA_OPTS="-server -Xms256m -Xmx256m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+DisableExplicitGC" -JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" - - -APP_HOME=../. -APP_MAIN=cn.webank.defibus.tools.command.DeFiBusAdminStartup -CLASSPATH=$APP_HOME/lib:$APP_HOME/apps:$APP_HOME/conf -ARGS="$@" - -for libJar in "$APP_HOME"/lib/*.jar; -do - CLASSPATH="$CLASSPATH":"$libJar" -done - -for appJar in "$APP_HOME"/apps/*.jar; -do - CLASSPATH="$CLASSPATH":"$appJar" -done - -for confFile in "$APP_HOME"/conf/*.*; -do - CLASSPATH="$CLASSPATH":"$confFile" -done -export CLASSPATH -#echo $CLASSPATH -#echo $APP_HOME -#echo $APP_MAIN - -startup(){ - $JAVA $JAVA_OPTS -classpath $CLASSPATH $APP_MAIN $ARGS -} - -if [ ! -d "../logs" ]; then - mkdir ../logs -fi -if [ ! -d "../logs/otherdays" ]; then - mkdir ../logs/otherdays -fi -if [ -f "../logs/tools.log" ]; then -today=`date '+%Y-%m-%d'` -files="tools.log" -for file in $files -do -timestamp=`stat -c %Y ../logs/$file` -fileTime=`date -d @$timestamp '+%Y-%m-%d'` -if [[ $fileTime != $today ]] -then - num=$(ls ../logs/otherdays|grep "tools-$fileTime"|wc -l) - mv ../logs/$file ../logs/otherdays/tools-$fileTime-$num.log -else -filesize=`ls -l ../logs/$file | awk '{ print $5 }'` -maxsize=$((1024*1024*2)) -if [[ $filesize -gt $maxsize ]] -then - num=$(ls ../logs/otherdays|grep "tools-$fileTime"|wc -l) - mv ../logs/$file ../logs/otherdays/tools-$fileTime-$num.log -fi -fi -done -fi -startup $ARGS |tee -a ../logs/tools.log \ No newline at end of file diff --git a/eventmesh-store/script/runbroker.cmd b/eventmesh-store/script/runbroker.cmd deleted file mode 100644 index 3cf476e539..0000000000 --- a/eventmesh-store/script/runbroker.cmd +++ /dev/null @@ -1,37 +0,0 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! & EXIT /B 1 -set "JAVA=%JAVA_HOME%\bin\java.exe" - -setlocal - -set BASE_DIR=%~dp0 -set BASE_DIR=%BASE_DIR:~0,-1% -for %%d in (%BASE_DIR%) do set BASE_DIR=%%~dpd -set CLASSPATH=.;%BASE_DIR%conf;%CLASSPATH% -set "JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g -XX:PermSize=128m -XX:MaxPermSize=320m" -set "JAVA_OPT=%JAVA_OPT% -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:+DisableExplicitGC -XX:-UseParNewGC" -set "JAVA_OPT=%JAVA_OPT% -verbose:gc -Xloggc:"%USERPROFILE%\rmq_srv_gc.log" -XX:+PrintGCDetails" -set "JAVA_OPT=%JAVA_OPT% -XX:-OmitStackTraceInFastThrow" -set "JAVA_OPT=%JAVA_OPT% -XX:-UseLargePages" -set "JAVA_OPT=%JAVA_OPT% -Djava.ext.dirs=%BASE_DIR%lib;%BASE_DIR%apps" -set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%"" -"%JAVA%" %JAVA_OPT% cn.webank.defibus.broker.DeFiBusBrokerStartup %* - -IF %ERRORLEVEL% EQU 0 ( - ECHO "DeFiBusBroker starts OK" -) \ No newline at end of file diff --git a/eventmesh-store/script/runbroker.sh b/eventmesh-store/script/runbroker.sh deleted file mode 100644 index f86d72b807..0000000000 --- a/eventmesh-store/script/runbroker.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -#=========================================================================================== -# Java Environment Setting -#=========================================================================================== - -TMP_JAVA_HOME="/nemo/jdk8" - -function is_java8 { - local _java="$1" - [[ -x "$_java" ]] || return 1 - [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' ]] || return 2 - return 0 -} - -#0(not running), 1(is running) -function is_brokerRunning { - local _pid="$1" - local pid=`ps ax | grep -i 'cn.webank.defibus.broker.DeFiBusBrokerStartup' |grep java | grep -v grep | awk '{print $1}'|grep $_pid` - if [ -z "$pid" ] ; then - return 0 - else - return 1 - fi -} - - -if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then - JAVA="$TMP_JAVA_HOME/bin/java" -elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then - JAVA="$JAVA_HOME/bin/java" -elif is_java8 "/nemo/jdk8/bin/java"; then - JAVA="/nemo/jdk8/bin/java"; -elif is_java8 "/nemo/jdk1.8/bin/java"; then - JAVA="/nemo/jdk1.8/bin/java"; -elif is_java8 "/nemo/jdk/bin/java"; then - JAVA="/nemo/jdk/bin/java"; -elif is_java8 "$(which java)"; then - JAVA="$(which java)" -else - echo -e "ERROR\t java(1.8) not found, operation abort." - exit 9; -fi - -echo "broker use java location= "$JAVA - -ROCKETMQ_HOME=`cd "./.." && pwd` - -error_exit () -{ - echo "ERROR: $1 !!" - exit 1 -} - -export ROCKETMQ_HOME -export JAVA_HOME -#export JAVA="$JAVA_HOME/bin/java" -export BASE_DIR=$(dirname $0)/.. -export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH} - -#=========================================================================================== -# JVM Configuration -#=========================================================================================== -JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g" -JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" -JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" -JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" -JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" -JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" -JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g" -JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" -JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib:${BASE_DIR}/apps" -#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n" -JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}" -JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" - -if [ -f "pid.file" ]; then - pid=`cat pid.file` - if ! is_brokerRunning "$pid"; then - echo "broker is running already" - exit 9; - else - echo "err pid$pid, rm pid.file" - rm pid.file - fi -fi - - -nohup $JAVA ${JAVA_OPT} cn.webank.defibus.broker.DeFiBusBrokerStartup -c ../conf/broker.properties 2>&1 >/dev/null & -echo $!>pid.file diff --git a/eventmesh-store/script/runbroker_cloud.sh b/eventmesh-store/script/runbroker_cloud.sh deleted file mode 100644 index efafa39f5f..0000000000 --- a/eventmesh-store/script/runbroker_cloud.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#=========================================================================================== -# Java Environment Setting -#=========================================================================================== - -TMP_JAVA_HOME="/nemo/jdk8" - -function is_java8 { - local _java="$1" - [[ -x "$_java" ]] || return 1 - [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' ]] || return 2 - return 0 -} - -#0(not running), 1(is running) -function is_brokerRunning { - local _pid="$1" - local pid=`ps ax | grep -i 'cn.webank.defibus.broker.DeFiBusBrokerStartup' |grep java | grep -v grep | awk '{print $1}'|grep $_pid` - if [ -z "$pid" ] ; then - return 0 - else - return 1 - fi -} - - -if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then - JAVA="$TMP_JAVA_HOME/bin/java" -elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then - JAVA="$JAVA_HOME/bin/java" -elif is_java8 "/nemo/jdk8/bin/java"; then - JAVA="/nemo/jdk8/bin/java"; -elif is_java8 "/nemo/jdk1.8/bin/java"; then - JAVA="/nemo/jdk1.8/bin/java"; -elif is_java8 "/nemo/jdk/bin/java"; then - JAVA="/nemo/jdk/bin/java"; -elif is_java8 "$(which java)"; then - JAVA="$(which java)" -else - echo -e "ERROR\t java(1.8) not found, operation abort." - exit 9; -fi - -echo "broker use java location= "$JAVA - -ROCKETMQ_HOME=`cd "./.." && pwd` - -error_exit () -{ - echo "ERROR: $1 !!" - exit 1 -} - -export ROCKETMQ_HOME -export JAVA_HOME -#export JAVA="$JAVA_HOME/bin/java" -export BASE_DIR=$(dirname $0)/.. -export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH} - -#=========================================================================================== -# JVM Configuration -#=========================================================================================== -JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g" -JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:MaxGCPauseMillis=50" -JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" -JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" -JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" -JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" -JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=1g" -JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking" -JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib:${BASE_DIR}/apps" -#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n" -JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}" -JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" - -if [ -f "pid.file" ]; then - pid=`cat pid.file` - if ! is_brokerRunning "$pid"; then - echo "broker is running already" - exit 9; - else - echo "err pid$pid, rm pid.file" - rm pid.file - fi -fi - - -nohup $JAVA ${JAVA_OPT} cn.webank.defibus.broker.DeFiBusBrokerStartup -c ../conf/broker.properties 2>&1 >/dev/null & -echo $!>pid.file diff --git a/eventmesh-store/script/runnamesrv.cmd b/eventmesh-store/script/runnamesrv.cmd deleted file mode 100644 index b3344addd0..0000000000 --- a/eventmesh-store/script/runnamesrv.cmd +++ /dev/null @@ -1,37 +0,0 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! & EXIT /B 1 -set "JAVA=%JAVA_HOME%\bin\java.exe" - -setlocal - -set BASE_DIR=%~dp0 -set BASE_DIR=%BASE_DIR:~0,-1% -for %%d in (%BASE_DIR%) do set BASE_DIR=%%~dpd -set CLASSPATH=.;%BASE_DIR%conf;%CLASSPATH% -set "JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g -XX:PermSize=128m -XX:MaxPermSize=320m" -set "JAVA_OPT=%JAVA_OPT% -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:+DisableExplicitGC -XX:-UseParNewGC" -set "JAVA_OPT=%JAVA_OPT% -verbose:gc -Xloggc:"%USERPROFILE%\rmq_srv_gc.log" -XX:+PrintGCDetails" -set "JAVA_OPT=%JAVA_OPT% -XX:-OmitStackTraceInFastThrow" -set "JAVA_OPT=%JAVA_OPT% -XX:-UseLargePages" -set "JAVA_OPT=%JAVA_OPT% -Djava.ext.dirs=%BASE_DIR%lib;%BASE_DIR%apps" -set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%"" -"%JAVA%" %JAVA_OPT% cn.webank.defibus.namesrv.DeFiBusNamesrvStartup -c ../conf/broker.properties %* - -IF %ERRORLEVEL% EQU 0 ( - ECHO "DeFiBusNamesrv starts OK" -) \ No newline at end of file diff --git a/eventmesh-store/script/runnamesrv.sh b/eventmesh-store/script/runnamesrv.sh deleted file mode 100644 index f4395dab46..0000000000 --- a/eventmesh-store/script/runnamesrv.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#=========================================================================================== -# Java Environment Setting -#=========================================================================================== -TMP_JAVA_HOME="/nemo/jdk8" - -function is_java8 { - local _java="$1" - [[ -x "$_java" ]] || return 1 - [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' ]] || return 2 - return 0 -} - -if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then - JAVA="$TMP_JAVA_HOME/bin/java" -elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then - JAVA="$JAVA_HOME/bin/java" -elif is_java8 "/nemo/jdk8/bin/java"; then - JAVA="/nemo/jdk8/bin/java"; -elif is_java8 "/nemo/jdk1.8/bin/java"; then - JAVA="/nemo/jdk1.8/bin/java"; -elif is_java8 "/nemo/jdk/bin/java"; then - JAVA="/nemo/jdk/bin/java"; -elif is_java8 "$(which java)"; then - JAVA="$(which java)" -else - echo -e "ERROR\t java(1.8) not found, operation abort.">>read.me - exit 9; -fi - -echo "nameSrv use java location= "$JAVA - - -ROCKETMQ_HOME=`cd "./.." && pwd` - -error_exit () -{ - echo "ERROR: $1 !!" - exit 1 -} - - -export ROCKETMQ_HOME -#export JAVA_HOME -#export JAVA="$JAVA_HOME/bin/java" -export BASE_DIR=$(dirname $0)/.. -export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH} - -#=========================================================================================== -# JVM Configuration -#=========================================================================================== -JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g" -JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:MaxGCPauseMillis=100 -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:-UseBiasedLocking -XX:+AlwaysPreTouch -XX:SoftRefLRUPolicyMSPerMB=0" -JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" -JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" -JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" -JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" -JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib:${BASE_DIR}/apps" -#JAVA_OPT="${JAVA_OPT} -Dio.netty.recycler.maxCapacity.default=0" -#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n" -JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}" -JAVA_OPT="${JAVA_OPT} -Djava.security.egd=file:/dev/./urandom" - -nohup $JAVA ${JAVA_OPT} cn.webank.defibus.namesrv.DeFiBusNamesrvStartup -c ../conf/namesrv.properties 2>&1 >/dev/null & - -echo "Now Add crontab...." -crontab -l | grep -v namesrv_watchdog > tmp_crontab.txt -dir=`pwd` -echo "*/1 * * * * cd $dir; ./namesrv_watchdog.sh >/dev/null 2>&1" >> tmp_crontab.txt -crontab tmp_crontab.txt -rm tmp_crontab.txt \ No newline at end of file diff --git a/eventmesh-store/script/stop.cmd b/eventmesh-store/script/stop.cmd deleted file mode 100644 index 6c2ad3f800..0000000000 --- a/eventmesh-store/script/stop.cmd +++ /dev/null @@ -1,35 +0,0 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if not exist "%JAVA_HOME%\bin\jps.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! & EXIT /B 1 - -setlocal - -set "PATH=%JAVA_HOME%\bin;%PATH%" - -if /I "%1" == "broker" ( - echo killing broker - for /f "tokens=1" %%i in ('jps -m ^| find "DeFiBusBrokerStartup"') do ( taskkill /F /PID %%i ) - echo Done! -) else if /I "%1" == "namesrv" ( - echo killing name server - - for /f "tokens=1" %%i in ('jps -m ^| find "DeFiBusNamesrvStartup"') do ( taskkill /F /PID %%i ) - - echo Done! -) else ( - echo Unknown role to kill, please specify broker or namesrv -) \ No newline at end of file diff --git a/eventmesh-store/script/stop.sh b/eventmesh-store/script/stop.sh deleted file mode 100644 index d4dfb13ded..0000000000 --- a/eventmesh-store/script/stop.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -echo "Now removing crontab....." -crontab -l | grep -v broker_watchdog | grep -v namesrv_watchdog > tmp_crontab.txt -crontab tmp_crontab.txt -rm -f tmp_crontab.txt -echo "Finish...." - -case $1 in - broker) - - pid=`ps ax | grep -i 'cn.webank.defibus.broker.DeFiBusBrokerStartup' |grep java | grep -v grep | awk '{print $1}'` - if [ -z "$pid" ] ; then - echo "No DeFiBusBroker running." - exit -1; - fi - - if [ "$2" != "-f" ] ; then - echo "read from pid.file" - pid=`cat pid.file` - fi - - echo "The DeFiBusBroker(${pid}) is running..." - kill ${pid} - - echo "Send shutdown request to DeFiBusBroker(${pid}) OK" - - # wait for broker to shutdown - while ps -p ${pid} > /dev/null 2>&1; do sleep 1; echo "waiting broker process ${pid} to exit."; done; - - rm -rf pid.file - - echo "broker process exits." - ;; - namesrv) - - pid=`ps ax | grep -i 'cn.webank.defibus.namesrv.DeFiBusNameSrvStartup' |grep java | grep -v grep | awk '{print $1}'` - if [ -z "$pid" ] ; then - echo "No DeFiBusNameSrv running." - exit -1; - fi - - echo "The DeFiBusNameSrv(${pid}) is running..." - - kill ${pid} - - echo "Send shutdown request to DeFiBusNameSrv(${pid}) OK" - ;; - *) - echo "Useage: `basename $0` (broker|namesrv)" -esac \ No newline at end of file diff --git a/eventmesh-store/settings.gradle b/eventmesh-store/settings.gradle deleted file mode 100644 index da9a085c87..0000000000 --- a/eventmesh-store/settings.gradle +++ /dev/null @@ -1,26 +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. - */ - -rootProject.name = 'EventMesh' -String jdkVersion = "${jdk}" -if (jdkVersion.equals('1.7')) { - include 'defibus-common', 'defibus-client', 'defibus-tools' -} else { - include 'defibus-common', 'defibus-client', 'defibus-tools', 'defibus-broker', 'defibus-namesrv', 'defibus-examples' -} - - diff --git a/eventmesh-trace-plugin/build.gradle b/eventmesh-trace-plugin/build.gradle new file mode 100644 index 0000000000..d973dcedae --- /dev/null +++ b/eventmesh-trace-plugin/build.gradle @@ -0,0 +1,16 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/build.gradle b/eventmesh-trace-plugin/eventmesh-trace-api/build.gradle new file mode 100644 index 0000000000..f8b885f881 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/build.gradle @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + api project(":eventmesh-spi") + implementation project(":eventmesh-common") + api 'io.cloudevents:cloudevents-core' + + implementation 'io.opentelemetry:opentelemetry-api' + implementation 'io.opentelemetry:opentelemetry-sdk' + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + testImplementation project(":eventmesh-trace-plugin:eventmesh-trace-zipkin") +} \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/gradle.properties b/eventmesh-trace-plugin/eventmesh-trace-api/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/EventMeshTraceService.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/EventMeshTraceService.java new file mode 100644 index 0000000000..c7d5661990 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/EventMeshTraceService.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.api; + +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; +import org.apache.eventmesh.trace.api.exception.TraceException; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; + +/** + * EventMeshTraceService + */ +@EventMeshSPI(isSingleton = true, eventMeshExtensionType = EventMeshExtensionType.TRACE) +public interface EventMeshTraceService { + void init() throws TraceException; + + //extract attr from carrier to context + Context extractFrom(Context context, Map carrier) throws TraceException; + + //inject attr from context to carrier + void inject(Context context, Map carrier); + + Span createSpan(String spanName, SpanKind spanKind, long startTimestamp, TimeUnit timeUnit, + Context context, boolean isSpanFinishInOtherThread) throws TraceException; + + Span createSpan(String spanName, SpanKind spanKind, Context context, + boolean isSpanFinishInOtherThread) throws TraceException; + + void shutdown() throws TraceException; +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/TracePluginFactory.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/TracePluginFactory.java new file mode 100644 index 0000000000..e0bac19ed1 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/TracePluginFactory.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.api; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import lombok.experimental.UtilityClass; + +/** + * to get the trace service + */ +@UtilityClass +public class TracePluginFactory { + /** + * to get TraceService + * + * @param traceServiceType + * @return + */ + public static EventMeshTraceService getEventMeshTraceService(String traceServiceType) { + checkNotNull(traceServiceType, "traceServiceType cannot be null"); + + EventMeshTraceService eventMeshTraceService = EventMeshExtensionFactory.getExtension(EventMeshTraceService.class, traceServiceType); + return checkNotNull(eventMeshTraceService, "traceServiceType: " + traceServiceType + " is not supported"); + } +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/common/EventMeshTraceConstants.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/common/EventMeshTraceConstants.java new file mode 100644 index 0000000000..82dc63ead4 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/common/EventMeshTraceConstants.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.api.common; + + +public class EventMeshTraceConstants { + + public static final String TRACE_EVENTMESH_SDK_CLIENT_SPAN = "eventmesh-sdk-client-span"; + + public static final String TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN = "upstream-eventmesh-server-span"; + public static final String TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN = "upstream-eventmesh-client-span"; + + public static final String TRACE_DOWNSTREAM_EVENTMESH_SERVER_SPAN = "downstream-eventmesh-server-span"; + public static final String TRACE_DOWNSTREAM_EVENTMESH_CLIENT_SPAN = "downstream-eventmesh-client-span"; + + public static final String TRACE_EVENTMESH_SDK_SERVER_SPAN = "eventmesh-sdk-server-span"; + +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/common/ProtocolType.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/common/ProtocolType.java new file mode 100644 index 0000000000..734f4c638d --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/common/ProtocolType.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.api.common; + +public enum ProtocolType { + TCP, + HTTP +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/config/ExporterConfiguration.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/config/ExporterConfiguration.java new file mode 100644 index 0000000000..44d54d032c --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/config/ExporterConfiguration.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.api.config; + +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Properties; + +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +/** + * to load the properties form exporter.properties + */ +@Slf4j +@UtilityClass +public class ExporterConfiguration { + + private static final String CONFIG_FILE = "exporter.properties"; + private static final Properties properties = new Properties(); + + private int eventMeshTraceMaxExportSize = 512; + private int eventMeshTraceMaxQueueSize = 2048; + private int eventMeshTraceExportTimeout = 30; + private int eventMeshTraceExportInterval = 5; + + static { + loadProperties(); + initializeConfig(); + } + + public static int getEventMeshTraceMaxExportSize() { + return eventMeshTraceMaxExportSize; + } + + public static int getEventMeshTraceMaxQueueSize() { + return eventMeshTraceMaxQueueSize; + } + + public static int getEventMeshTraceExportTimeout() { + return eventMeshTraceExportTimeout; + } + + public static int getEventMeshTraceExportInterval() { + return eventMeshTraceExportInterval; + } + + private void initializeConfig() { + String eventMeshTraceMaxExportSizeStr = properties.getProperty("eventmesh.trace.max.export.size"); + if (StringUtils.isNotEmpty(eventMeshTraceMaxExportSizeStr)) { + eventMeshTraceMaxExportSize = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshTraceMaxExportSizeStr)); + } + + String eventMeshTraceMaxQueueSizeStr = properties.getProperty("eventmesh.trace.max.queue.size"); + if (StringUtils.isNotEmpty(eventMeshTraceMaxQueueSizeStr)) { + eventMeshTraceMaxQueueSize = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshTraceMaxQueueSizeStr)); + } + + String eventMeshTraceExportTimeoutStr = properties.getProperty("eventmesh.trace.export.timeout"); + if (StringUtils.isNotEmpty(eventMeshTraceExportTimeoutStr)) { + eventMeshTraceExportTimeout = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshTraceExportTimeoutStr)); + } + + String eventMeshTraceExportIntervalStr = properties.getProperty("eventmesh.trace.export.interval"); + if (StringUtils.isNotEmpty(eventMeshTraceExportIntervalStr)) { + eventMeshTraceExportInterval = + Integer.parseInt(StringUtils.deleteWhitespace(eventMeshTraceExportIntervalStr)); + } + } + + private void loadProperties() { + URL resource = ExporterConfiguration.class.getClassLoader().getResource(CONFIG_FILE); + if (resource != null) { + try (InputStream inputStream = resource.openStream()) { + if (inputStream.available() > 0) { + properties.load(new BufferedReader(new InputStreamReader(inputStream))); + } + } catch (IOException e) { + throw new RuntimeException("Load exporter.properties file from classpath error"); + } + } + // get from config home + try { + String configPath = + System.getProperty("confPath", System.getenv("confPath")) + File.separator + CONFIG_FILE; + if (new File(configPath).exists()) { + properties.load(new BufferedReader(new FileReader(configPath))); + } + } catch (IOException e) { + throw new IllegalArgumentException("Cannot load exporter.properties file from conf"); + } + } +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/exception/TraceException.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/exception/TraceException.java new file mode 100644 index 0000000000..8a953ba381 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/exception/TraceException.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.api.exception; + +public class TraceException extends RuntimeException { + + public TraceException(String message) { + super(message); + } + + public TraceException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/resources/exporter.properties b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/resources/exporter.properties new file mode 100644 index 0000000000..a36d2d86b9 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/resources/exporter.properties @@ -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. +# + +#set the maximum batch size to use +eventmesh.trace.max.export.size=512 +#set the queue size. This must be >= the export batch size +eventmesh.trace.max.queue.size=2048 +#set the max amount of time an export can run before getting(TimeUnit=SECONDS) +eventmesh.trace.export.timeout=30 +#set time between two different exports(TimeUnit=SECONDS) +eventmesh.trace.export.interval=5 \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/test/java/org/apache/eventmesh/trace/api/TracePluginFactoryTest.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/test/java/org/apache/eventmesh/trace/api/TracePluginFactoryTest.java new file mode 100644 index 0000000000..58583fa063 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/test/java/org/apache/eventmesh/trace/api/TracePluginFactoryTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.api; + +import static org.hamcrest.CoreMatchers.is; + +import org.apache.eventmesh.trace.zipkin.ZipkinTraceService; + +import org.hamcrest.MatcherAssert; +import org.junit.Assert; +import org.junit.Test; + +public class TracePluginFactoryTest { + + @Test + public void testFailedGetTraceService() { + NullPointerException nullPointerException1 = Assert.assertThrows(NullPointerException.class, + () -> TracePluginFactory.getEventMeshTraceService(null)); + MatcherAssert.assertThat(nullPointerException1.getMessage(), is("traceServiceType cannot be null")); + + String traceServiceType = "non-Existing"; + NullPointerException nullPointerException2 = + Assert.assertThrows(NullPointerException.class, () -> TracePluginFactory.getEventMeshTraceService(traceServiceType)); + MatcherAssert.assertThat(nullPointerException2.getMessage(), is("traceServiceType: " + traceServiceType + " is not supported")); + } + + @Test + public void testSuccessfulGetTraceService() { + EventMeshTraceService zipkinTraceService = TracePluginFactory.getEventMeshTraceService("zipkin"); + Assert.assertNotNull(zipkinTraceService); + Assert.assertTrue(zipkinTraceService instanceof ZipkinTraceService); + } +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/build.gradle b/eventmesh-trace-plugin/eventmesh-trace-zipkin/build.gradle new file mode 100644 index 0000000000..7daff5d46f --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/build.gradle @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + implementation project(":eventmesh-trace-plugin:eventmesh-trace-api") + implementation project(":eventmesh-common") + implementation 'org.slf4j:slf4j-api' + implementation 'org.apache.commons:commons-lang3' + implementation 'com.google.guava:guava' + + implementation 'io.opentelemetry:opentelemetry-exporter-zipkin' + implementation 'io.opentelemetry:opentelemetry-semconv' + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-inline" +} \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/gradle.properties b/eventmesh-trace-plugin/eventmesh-trace-zipkin/gradle.properties new file mode 100644 index 0000000000..13bc3c5a83 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/gradle.properties @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pluginType=trace +pluginName=zipkin \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/ZipkinTraceService.java b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/ZipkinTraceService.java new file mode 100644 index 0000000000..cf36da592b --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/ZipkinTraceService.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.zipkin; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; + +import org.apache.eventmesh.trace.api.EventMeshTraceService; +import org.apache.eventmesh.trace.api.config.ExporterConfiguration; +import org.apache.eventmesh.trace.api.exception.TraceException; +import org.apache.eventmesh.trace.zipkin.config.ZipkinConfiguration; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nullable; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.ContextPropagators; +import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.context.propagation.TextMapSetter; +import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; + + +/** + * + */ +public class ZipkinTraceService implements EventMeshTraceService { + // Zipkin API Endpoints for uploading spans + private static final String ENDPOINT_V2_SPANS = "/api/v2/spans"; + // Name of the service(using the instrumentationName) + private final String serviceName = "eventmesh_trace"; + private String eventMeshZipkinIP; + private int eventMeshZipkinPort; + private int eventMeshTraceExportInterval; + private int eventMeshTraceExportTimeout; + private int eventMeshTraceMaxExportSize; + private int eventMeshTraceMaxQueueSize; + protected SdkTracerProvider sdkTracerProvider; + + protected OpenTelemetry openTelemetry; + + protected Thread shutdownHook; + + private Tracer tracer; + private TextMapPropagator textMapPropagator; + + @Override + public void init() { + //zipkin's config + eventMeshZipkinIP = ZipkinConfiguration.getEventMeshZipkinIP(); + eventMeshZipkinPort = ZipkinConfiguration.getEventMeshZipkinPort(); + //exporter's config + eventMeshTraceExportInterval = ExporterConfiguration.getEventMeshTraceExportInterval(); + eventMeshTraceExportTimeout = ExporterConfiguration.getEventMeshTraceExportTimeout(); + eventMeshTraceMaxExportSize = ExporterConfiguration.getEventMeshTraceMaxExportSize(); + eventMeshTraceMaxQueueSize = ExporterConfiguration.getEventMeshTraceMaxQueueSize(); + + String httpUrl = String.format("http://%s:%s", eventMeshZipkinIP, eventMeshZipkinPort); + ZipkinSpanExporter zipkinExporter = + ZipkinSpanExporter.builder().setEndpoint(httpUrl + ENDPOINT_V2_SPANS).build(); + + SpanProcessor spanProcessor = BatchSpanProcessor.builder(zipkinExporter) + .setScheduleDelay(eventMeshTraceExportInterval, TimeUnit.SECONDS) + .setExporterTimeout(eventMeshTraceExportTimeout, TimeUnit.SECONDS) + .setMaxExportBatchSize(eventMeshTraceMaxExportSize) + .setMaxQueueSize(eventMeshTraceMaxQueueSize) + .build(); + + //set the trace service's name + Resource serviceNameResource = + Resource.create(Attributes.of(stringKey("service.name"), serviceName)); + + sdkTracerProvider = SdkTracerProvider.builder() + .addSpanProcessor(spanProcessor) + .setResource(Resource.getDefault().merge(serviceNameResource)) + .build(); + + openTelemetry = OpenTelemetrySdk.builder() + .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) + .setTracerProvider(sdkTracerProvider) + .build(); + + //TODO serviceName??? + tracer = openTelemetry.getTracer(serviceName); + textMapPropagator = openTelemetry.getPropagators().getTextMapPropagator(); + + shutdownHook = new Thread(sdkTracerProvider::close); + Runtime.getRuntime().addShutdownHook(shutdownHook); + } + + @Override + public Context extractFrom(Context context, Map map) throws TraceException { + textMapPropagator.extract(context, map, new TextMapGetter>() { + @Override + public Iterable keys(Map carrier) { + return carrier.keySet(); + } + + @Override + public String get(Map carrier, String key) { + return carrier.get(key).toString(); + } + }); + return context; + } + + @Override + public void inject(Context context, Map map) { + textMapPropagator.inject(context, map, new TextMapSetter>() { + @Override + public void set(@Nullable Map carrier, String key, String value) { + map.put(key, value); + } + }); + } + + @Override + public Span createSpan(String spanName, SpanKind spanKind, long startTime, TimeUnit timeUnit, + Context context, boolean isSpanFinishInOtherThread) + throws TraceException { + return tracer.spanBuilder(spanName) + .setParent(context) + .setSpanKind(spanKind) + .setStartTimestamp(startTime, timeUnit) + .startSpan(); + } + + @Override + public Span createSpan(String spanName, SpanKind spanKind, Context context, + boolean isSpanFinishInOtherThread) throws TraceException { + return tracer.spanBuilder(spanName) + .setParent(context) + .setSpanKind(spanKind) + .setStartTimestamp(System.currentTimeMillis(), TimeUnit.MILLISECONDS) + .startSpan(); + } + + @Override + public void shutdown() { + //todo: check the spanProcessor if it was already close + + sdkTracerProvider.close(); + + //todo: turn the value of useTrace in AbstractHTTPServer into false + } +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/config/ZipkinConfiguration.java b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/config/ZipkinConfiguration.java new file mode 100644 index 0000000000..5dfa9a42a6 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/config/ZipkinConfiguration.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.zipkin.config; + +import org.apache.commons.lang3.StringUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Properties; + +import com.google.common.base.Preconditions; + +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +/** + * to load the properties form zipkin.properties + */ +@Slf4j +@UtilityClass +public class ZipkinConfiguration { + + private static final String CONFIG_FILE = "zipkin.properties"; + private static final Properties properties = new Properties(); + + private String eventMeshZipkinIP = "localhost"; + private int eventMeshZipkinPort = 9411; + + static { + loadProperties(); + initializeConfig(); + } + + public static String getEventMeshZipkinIP() { + return eventMeshZipkinIP; + } + + public static int getEventMeshZipkinPort() { + return eventMeshZipkinPort; + } + + private void initializeConfig() { + String eventMeshZipkinIPStr = properties.getProperty("eventmesh.trace.zipkin.ip"); + Preconditions.checkState(StringUtils.isNotEmpty(eventMeshZipkinIPStr), + String.format("%s error", "eventmesh.trace.zipkin.ip")); + eventMeshZipkinIP = StringUtils.deleteWhitespace(eventMeshZipkinIPStr); + + String eventMeshZipkinPortStr = properties.getProperty("eventmesh.trace.zipkin.port"); + if (StringUtils.isNotEmpty(eventMeshZipkinPortStr)) { + eventMeshZipkinPort = Integer.parseInt(StringUtils.deleteWhitespace(eventMeshZipkinPortStr)); + } + } + + private void loadProperties() { + URL resource = ZipkinConfiguration.class.getClassLoader().getResource(CONFIG_FILE); + if (resource != null) { + try (InputStream inputStream = resource.openStream()) { + if (inputStream.available() > 0) { + properties.load(new BufferedReader(new InputStreamReader(inputStream))); + } + } catch (IOException e) { + throw new RuntimeException("Load zipkin.properties file from classpath error"); + } + } + // get from config home + try { + String configPath = + System.getProperty("confPath", System.getenv("confPath")) + File.separator + CONFIG_FILE; + if (new File(configPath).exists()) { + properties.load(new BufferedReader(new FileReader(configPath))); + } + } catch (IOException e) { + throw new IllegalArgumentException("Cannot load zipkin.properties file from conf"); + } + } +} diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.trace.api.EventMeshTraceService b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.trace.api.EventMeshTraceService new file mode 100644 index 0000000000..a6ccf899e4 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.trace.api.EventMeshTraceService @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +zipkin=org.apache.eventmesh.trace.zipkin.ZipkinTraceService \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/resources/zipkin.properties b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/resources/zipkin.properties new file mode 100644 index 0000000000..323c84cbc3 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/resources/zipkin.properties @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#zipkin's working ip and port +eventmesh.trace.zipkin.ip=localhost +eventmesh.trace.zipkin.port=9411 \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/ZipkinTraceServiceTest.java b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/ZipkinTraceServiceTest.java new file mode 100644 index 0000000000..ccb102e5c3 --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/ZipkinTraceServiceTest.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.trace.zipkin; + +import static org.junit.Assert.assertThrows; + +import java.lang.reflect.Field; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import io.opentelemetry.sdk.trace.SdkTracerProvider; + +public class ZipkinTraceServiceTest { + + @Test + public void testInit() { + ZipkinTraceService zipkinTraceService = new ZipkinTraceService(); + zipkinTraceService.init(); + + Assert.assertNotNull(zipkinTraceService.sdkTracerProvider); + Assert.assertNotNull(zipkinTraceService.openTelemetry); + Assert.assertNotNull(zipkinTraceService.shutdownHook); + + IllegalArgumentException illegalArgumentException = + assertThrows(IllegalArgumentException.class, () -> Runtime.getRuntime().addShutdownHook(zipkinTraceService.shutdownHook)); + Assert.assertEquals(illegalArgumentException.getMessage(), "Hook previously registered"); + } + + @Test + public void testShutdown() throws Exception { + SdkTracerProvider mockSdkTracerProvider = Mockito.mock(SdkTracerProvider.class); + ZipkinTraceService zipkinTraceService = new ZipkinTraceService(); + zipkinTraceService.init(); + Field sdkTracerProviderField = ZipkinTraceService.class.getDeclaredField("sdkTracerProvider"); + sdkTracerProviderField.setAccessible(true); + sdkTracerProviderField.set(zipkinTraceService, mockSdkTracerProvider); + + zipkinTraceService.shutdown(); + Mockito.verify(mockSdkTracerProvider, Mockito.times(1)).close(); + } +} diff --git a/eventmesh-trace-plugin/gradle.properties b/eventmesh-trace-plugin/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-trace-plugin/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-webhook/build.gradle b/eventmesh-webhook/build.gradle new file mode 100644 index 0000000000..8d8657a4e6 --- /dev/null +++ b/eventmesh-webhook/build.gradle @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +task copyEventMeshAdmin(dependsOn: ['jar']) { + doFirst { + new File(projectDir, '../eventmesh-webhook/dist/apps').mkdir() + new File(projectDir, '../dist/webhook/').mkdirs() + } + doLast { + copy { + into('../eventmesh-webhook/dist/apps/') + from project.jar.getArchivePath() + exclude { + "eventmesh-webhook-${version}.jar" + } + } + copy { + into '../dist/webhook' + from "../eventmesh-webhook/dist/apps/eventmesh-webhook-api.jar" + from "../eventmesh-webhook/dist/apps/eventmesh-webhook-admin.jar" + from "../eventmesh-webhook/dist/apps/eventmesh-webhook-receive.jar" + } + } +} diff --git a/eventmesh-webhook/eventmesh-webhook-admin/bin/.gitignore b/eventmesh-webhook/eventmesh-webhook-admin/bin/.gitignore new file mode 100644 index 0000000000..ddf9c65631 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-admin/bin/.gitignore @@ -0,0 +1 @@ +/main/ diff --git a/eventmesh-webhook/eventmesh-webhook-admin/build.gradle b/eventmesh-webhook/eventmesh-webhook-admin/build.gradle new file mode 100644 index 0000000000..af232747a0 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-admin/build.gradle @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + + implementation project(":eventmesh-common") + implementation project(":eventmesh-webhook:eventmesh-webhook-api") + + implementation 'org.slf4j:slf4j-api' + implementation "com.alibaba.nacos:nacos-client:2.0.4" + implementation "com.fasterxml.jackson.core:jackson-databind" + implementation "com.fasterxml.jackson.core:jackson-core" + implementation "com.fasterxml.jackson.core:jackson-annotations" + + testImplementation project(":eventmesh-webhook:eventmesh-webhook-api") + + +} diff --git a/eventmesh-webhook/eventmesh-webhook-admin/gradle.properties b/eventmesh-webhook/eventmesh-webhook-admin/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-admin/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManage.java b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManage.java new file mode 100644 index 0000000000..84ecf7014a --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManage.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.admin; + +import org.apache.eventmesh.common.config.ConfigurationWrapper; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; +import org.apache.eventmesh.webhook.api.WebHookOperationConstant; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class AdminWebHookConfigOperationManage { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private static final Map> map = new HashMap<>(); + + static { + map.put("file", FileWebHookConfigOperation.class); + map.put("nacos", NacosWebHookConfigOperation.class); + } + + private ConfigurationWrapper configurationWrapper; + + private WebHookConfigOperation webHookConfigOperation; + + public void setConfigurationWrapper(ConfigurationWrapper configurationWrapper) { + this.configurationWrapper = configurationWrapper; + } + + public WebHookConfigOperation getWebHookConfigOperation() { + return webHookConfigOperation; + } + + public void init() throws Exception { + + if (!configurationWrapper.getBoolProp(WebHookOperationConstant.ADMIN_START_CONFIG_NAME, false)) { + return; + } + + String operationMode = configurationWrapper.getProp(WebHookOperationConstant.OPERATION_MODE_CONFIG_NAME); + + if (!map.containsKey(operationMode)) { + throw new IllegalStateException("operationMode is not supported."); + } + + Constructor constructor = map.get(operationMode).getDeclaredConstructor(Properties.class); + constructor.setAccessible(true); + try { + Properties properties = configurationWrapper.getPropertiesByConfig("eventMesh.webHook." + operationMode + "Mode", true); + logger.info("operationMode is {} properties is {} ", operationMode, properties); + this.webHookConfigOperation = constructor.newInstance(properties); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + logger.error("can't find WebHookConfigOperation implementation"); + throw new Exception("can't find WebHookConfigOperation implementation"); + } + } +} diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/FileWebHookConfigOperation.java b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/FileWebHookConfigOperation.java new file mode 100644 index 0000000000..c443382655 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/FileWebHookConfigOperation.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.admin; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; +import org.apache.eventmesh.webhook.api.WebHookOperationConstant; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.channels.FileLock; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileWebHookConfigOperation implements WebHookConfigOperation { + + private static final Logger logger = LoggerFactory.getLogger(FileWebHookConfigOperation.class); + + private final String webHookFilePath; + + + public FileWebHookConfigOperation(Properties properties) throws FileNotFoundException { + String webHookFilePath = WebHookOperationConstant.getFilePath(properties.getProperty("filePath")); + + assert webHookFilePath != null; + File webHookFileDir = new File(webHookFilePath); + if (!webHookFileDir.isDirectory()) { + throw new FileNotFoundException("File path " + webHookFilePath + " is not directory"); + } + if (!webHookFileDir.exists()) { + webHookFileDir.mkdirs(); + } + this.webHookFilePath = webHookFilePath; + } + + @Override + public Integer insertWebHookConfig(WebHookConfig webHookConfig) { + if (!webHookConfig.getCallbackPath().startsWith(WebHookOperationConstant.CALLBACK_PATH_PREFIX)) { + logger.error("webhookConfig callback path must start with {}", WebHookOperationConstant.CALLBACK_PATH_PREFIX); + return 0; + } + File manuDir = new File(getWebhookConfigManuDir(webHookConfig)); + if (!manuDir.exists()) { + manuDir.mkdir(); + } + File webhookConfigFile = getWebhookConfigFile(webHookConfig); + if (webhookConfigFile.exists()) { + logger.error("webhookConfig {} is existed", webHookConfig.getCallbackPath()); + return 0; + } + return writeToFile(webhookConfigFile, webHookConfig) ? 1 : 0; + } + + @Override + public Integer updateWebHookConfig(WebHookConfig webHookConfig) { + File webhookConfigFile = getWebhookConfigFile(webHookConfig); + if (!webhookConfigFile.exists()) { + logger.error("webhookConfig {} is not existed", webHookConfig.getCallbackPath()); + return 0; + } + return writeToFile(webhookConfigFile, webHookConfig) ? 1 : 0; + } + + @Override + public Integer deleteWebHookConfig(WebHookConfig webHookConfig) { + File webhookConfigFile = getWebhookConfigFile(webHookConfig); + if (!webhookConfigFile.exists()) { + logger.error("webhookConfig {} is not existed", webHookConfig.getCallbackPath()); + return 0; + } + return webhookConfigFile.delete() ? 1 : 0; + } + + @Override + public WebHookConfig queryWebHookConfigById(WebHookConfig webHookConfig) { + File webhookConfigFile = getWebhookConfigFile(webHookConfig); + if (!webhookConfigFile.exists()) { + logger.error("webhookConfig {} is not existed", webHookConfig.getCallbackPath()); + return null; + } + return getWebHookConfigFromFile(webhookConfigFile); + } + + @Override + public List queryWebHookConfigByManufacturer(WebHookConfig webHookConfig, Integer pageNum, + Integer pageSize) { + String manuDirPath = getWebhookConfigManuDir(webHookConfig); + File manuDir = new File(manuDirPath); + if (!manuDir.exists()) { + logger.warn("webhookConfig dir {} is not existed", manuDirPath); + return new ArrayList<>(); + } + List webHookConfigs = new ArrayList<>(); + + File[] webhookFiles = manuDir.listFiles(); + if (webhookFiles == null || webhookFiles.length == 0) { + return webHookConfigs; + } + + int startIndex = (pageNum - 1) * pageSize; + int endIndex = pageNum * pageSize - 1; + if (webhookFiles.length > startIndex) { + for (int i = startIndex; i < endIndex && i < webhookFiles.length; i++) { + webHookConfigs.add(getWebHookConfigFromFile(webhookFiles[i])); + } + } + return webHookConfigs; + } + + private WebHookConfig getWebHookConfigFromFile(File webhookConfigFile) { + StringBuffer fileContent = new StringBuffer(); + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(webhookConfigFile)))) { + String line = null; + while ((line = br.readLine()) != null) { + fileContent.append(line); + } + } catch (IOException e) { + logger.error("get webhook from file {} error", webhookConfigFile.getPath(), e); + return null; + } + return JsonUtils.deserialize(fileContent.toString(), WebHookConfig.class); + } + + private boolean writeToFile(File webhookConfigFile, WebHookConfig webHookConfig) { + FileLock lock = null; + try (FileOutputStream fos = new FileOutputStream(webhookConfigFile); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos))) { + // lock this file + lock = fos.getChannel().lock(); + bw.write(JsonUtils.serialize(webHookConfig)); + } catch (IOException e) { + logger.error("write webhookConfig {} to file error", webHookConfig.getCallbackPath()); + return false; + } finally { + try { + if (lock != null) { + lock.release(); + } + } catch (IOException e) { + logger.warn("writeToFile finally caught an exception", e); + } + } + return true; + } + + private String getWebhookConfigManuDir(WebHookConfig webHookConfig) { + return webHookFilePath + WebHookOperationConstant.FILE_SEPARATOR + webHookConfig.getManufacturerName(); + } + + private File getWebhookConfigFile(WebHookConfig webHookConfig) { + String webhookConfigFilePath = null; + try { + // use URLEncoder.encode before, because the path may contain some speacial char like '/', which is illegal as a file name. + webhookConfigFilePath = this.getWebhookConfigManuDir(webHookConfig) + + WebHookOperationConstant.FILE_SEPARATOR + URLEncoder.encode(webHookConfig.getCallbackPath(), "UTF-8") + + WebHookOperationConstant.FILE_EXTENSION; + } catch (UnsupportedEncodingException e) { + logger.error("get webhookConfig file path {} failed", webHookConfig.getCallbackPath(), e); + } + assert webhookConfigFilePath != null; + return new File(webhookConfigFilePath); + } + + +} diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/NacosWebHookConfigOperation.java b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/NacosWebHookConfigOperation.java new file mode 100644 index 0000000000..14972dc0ec --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/NacosWebHookConfigOperation.java @@ -0,0 +1,205 @@ +package org.apache.eventmesh.webhook.admin; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 static org.apache.eventmesh.webhook.api.WebHookOperationConstant.DATA_ID_EXTENSION; +import static org.apache.eventmesh.webhook.api.WebHookOperationConstant.GROUP_PREFIX; +import static org.apache.eventmesh.webhook.api.WebHookOperationConstant.MANUFACTURERS_DATA_ID; +import static org.apache.eventmesh.webhook.api.WebHookOperationConstant.TIMEOUT_MS; + + + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.webhook.api.ManufacturerObject; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; +import org.apache.eventmesh.webhook.api.WebHookOperationConstant; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.nacos.api.config.ConfigFactory; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.ConfigType; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.util.internal.StringUtil; + + +public class NacosWebHookConfigOperation implements WebHookConfigOperation { + + private static final Logger logger = LoggerFactory.getLogger(NacosWebHookConfigOperation.class); + + private final ConfigService configService; + + + public NacosWebHookConfigOperation(Properties properties) throws NacosException { + configService = ConfigFactory.createConfigService(properties); + + String manufacturers = configService.getConfig(MANUFACTURERS_DATA_ID, "webhook", TIMEOUT_MS); + if (manufacturers == null) { + configService.publishConfig(MANUFACTURERS_DATA_ID, "webhook", JsonUtils.serialize(new ManufacturerObject()), ConfigType.JSON.getType()); + } + + } + + @Override + public Integer insertWebHookConfig(WebHookConfig webHookConfig) { + if (!webHookConfig.getCallbackPath().startsWith(WebHookOperationConstant.CALLBACK_PATH_PREFIX)) { + logger.error("webhookConfig callback path must start with {}", WebHookOperationConstant.CALLBACK_PATH_PREFIX); + return 0; + } + Boolean result; + String manufacturerName = webHookConfig.getManufacturerName(); + try { + if (configService.getConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig), TIMEOUT_MS) != null) { + logger.error("insertWebHookConfig failed, config has existed"); + return 0; + } + result = configService.publishConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig), + JsonUtils.serialize(webHookConfig), ConfigType.JSON.getType()); + } catch (NacosException e) { + logger.error("insertWebHookConfig failed", e); + return 0; + } + if (result) { + // update manufacturer config + try { + ManufacturerObject manufacturerObject = getManufacturersInfo(); + manufacturerObject.addManufacturer(manufacturerName); + manufacturerObject.getManufacturerEvents(manufacturerName).add(getWebHookConfigDataId(webHookConfig)); + configService.publishConfig(MANUFACTURERS_DATA_ID, "webhook", + JsonUtils.serialize(manufacturerObject), ConfigType.JSON.getType()); + } catch (NacosException e) { + logger.error("update manufacturersInfo error", e); + //rollback insert + try { + configService.removeConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig)); + } catch (NacosException ex) { + logger.error("rollback insertWebHookConfig failed", e); + } + } + } + return result ? 1 : 0; + } + + @Override + public Integer updateWebHookConfig(WebHookConfig webHookConfig) { + Boolean result = false; + try { + if (configService.getConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig), TIMEOUT_MS) == null) { + logger.error("updateWebHookConfig failed, config is not existed"); + return 0; + } + result = configService.publishConfig(getWebHookConfigDataId(webHookConfig), + getManuGroupId(webHookConfig), JsonUtils.serialize(webHookConfig), ConfigType.JSON.getType()); + } catch (NacosException e) { + logger.error("updateWebHookConfig failed", e); + } + return result ? 1 : 0; + } + + @Override + public Integer deleteWebHookConfig(WebHookConfig webHookConfig) { + Boolean result = false; + String manufacturerName = webHookConfig.getManufacturerName(); + try { + result = configService.removeConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig)); + } catch (NacosException e) { + logger.error("deleteWebHookConfig failed", e); + } + if (result) { + try { + ManufacturerObject manufacturerObject = getManufacturersInfo(); + manufacturerObject.getManufacturerEvents(manufacturerName).remove(getWebHookConfigDataId(webHookConfig)); + configService.publishConfig(MANUFACTURERS_DATA_ID, "webhook", + JsonUtils.serialize(manufacturerObject), ConfigType.JSON.getType()); + } catch (NacosException e) { + logger.error("update manufacturersInfo error", e); + } + } + return result ? 1 : 0; + } + + @Override + public WebHookConfig queryWebHookConfigById(WebHookConfig webHookConfig) { + try { + String content = configService.getConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig), TIMEOUT_MS); + return JsonUtils.deserialize(content, WebHookConfig.class); + } catch (NacosException e) { + logger.error("queryWebHookConfigById failed", e); + } + return null; + } + + @Override + public List queryWebHookConfigByManufacturer(WebHookConfig webHookConfig, Integer pageNum, + Integer pageSize) { + List webHookConfigs = new ArrayList<>(); + String manufacturerName = webHookConfig.getManufacturerName(); + // get manufacturer event list + try { + ManufacturerObject manufacturerObject = getManufacturersInfo(); + List manufacturerEvents = manufacturerObject.getManufacturerEvents(manufacturerName); + int startIndex = (pageNum - 1) * pageSize; + int endIndex = pageNum * pageSize - 1; + if (manufacturerEvents.size() > startIndex) { + // nacos API is not able to get all config, so use foreach + for (int i = startIndex; i < endIndex && i < manufacturerEvents.size(); i++) { + String content = configService.getConfig(manufacturerEvents.get(i) + DATA_ID_EXTENSION, + getManuGroupId(webHookConfig), TIMEOUT_MS); + webHookConfigs.add(JsonUtils.deserialize(content, WebHookConfig.class)); + } + } + } catch (NacosException e) { + logger.error("queryWebHookConfigByManufacturer failed", e); + } + return webHookConfigs; + } + + /** + * @param webHookConfig + * @return + */ + private String getWebHookConfigDataId(WebHookConfig webHookConfig) { + try { + // use URLEncoder.encode before, because the path may contain some speacial char like '/', which is illegal as a data id. + return URLEncoder.encode(webHookConfig.getCallbackPath(), "UTF-8") + DATA_ID_EXTENSION; + } catch (UnsupportedEncodingException e) { + logger.error("get webhookConfig dataId {} failed", webHookConfig.getCallbackPath(), e); + } + return webHookConfig.getCallbackPath() + DATA_ID_EXTENSION; + } + + private String getManuGroupId(WebHookConfig webHookConfig) { + return GROUP_PREFIX + webHookConfig.getManufacturerName(); + } + + private ManufacturerObject getManufacturersInfo() throws NacosException { + String manufacturersContent = configService.getConfig(MANUFACTURERS_DATA_ID, "webhook", TIMEOUT_MS); + return StringUtil.isNullOrEmpty(manufacturersContent) + ? new ManufacturerObject() : JsonUtils.deserialize(manufacturersContent, ManufacturerObject.class); + } + +} diff --git a/eventmesh-webhook/eventmesh-webhook-api/bin/.gitignore b/eventmesh-webhook/eventmesh-webhook-api/bin/.gitignore new file mode 100644 index 0000000000..ddf9c65631 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/bin/.gitignore @@ -0,0 +1 @@ +/main/ diff --git a/eventmesh-webhook/eventmesh-webhook-api/build.gradle b/eventmesh-webhook/eventmesh-webhook-api/build.gradle new file mode 100644 index 0000000000..52c44a50ff --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/build.gradle @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + testCompileOnly 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + +} diff --git a/eventmesh-webhook/eventmesh-webhook-api/gradle.properties b/eventmesh-webhook/eventmesh-webhook-api/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/ManufacturerObject.java b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/ManufacturerObject.java new file mode 100644 index 0000000000..88f79264fd --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/ManufacturerObject.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.api; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ManufacturerObject { + + private Set manufacturerSet = new HashSet<>(); + + private Map> manufacturerEventMap = new HashMap<>(); + + + public Set getManufacturerSet() { + return manufacturerSet; + } + + public Set addManufacturer(String manufacturer) { + manufacturerSet.add(manufacturer); + return manufacturerSet; + } + + public Set removeManufacturer(String manufacturer) { + manufacturerSet.remove(manufacturer); + return manufacturerSet; + } + + public Map> getManufacturerEventMap() { + return manufacturerEventMap; + } + + public void setManufacturerEventMap(Map> manufacturerEventMap) { + this.manufacturerEventMap = manufacturerEventMap; + } + + public List getManufacturerEvents(String manufacturerName) { + if (!manufacturerEventMap.containsKey(manufacturerName)) { + List m = new ArrayList<>(); + manufacturerEventMap.put(manufacturerName, m); + return m; + } + return manufacturerEventMap.get(manufacturerName); + } +} diff --git a/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookConfig.java b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookConfig.java new file mode 100644 index 0000000000..dce5422d0a --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookConfig.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.api; + +import lombok.Data; + +@Data +public class WebHookConfig { + + /** + * manufacturer callback path + */ + private String callbackPath; + + /** + * manufacturer name ,like github + */ + private String manufacturerName; + + /** + * webhook event name ,like rep-push + */ + private String manufacturerEventName; + + /** + * http header content type + */ + private String contentType = "application/json"; + + /** + * description of this WebHookConfig + */ + private String description; + + /** + * secret key ,for authentication + */ + private String secret; + + /** + * userName ,for HTTP authentication + */ + private String userName; + + /** + * password ,for HTTP authentication + */ + private String password; + + /** + * roll out protocol ,like http/kafka + */ + private String cloudEventProtocol; + + /** + * roll out addr + */ + private String cloudEventServiceAddress; + + /** + * roll out event name ,like topic to mq + */ + private String cloudEventName; + + /** + * roll out data format -> CloudEvent serialization mode + * If HTTP protocol is used, the request header contentType needs to be marked + */ + private String dataContentType = "application/json"; + + /** + * source of event + */ + private String cloudEventSource; + + /** + * id of cloudEvent ,like uuid/manufacturerEventId + */ + private String cloudEventIdGenerateMode = "manufacturerEventId"; +} diff --git a/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookConfigOperation.java b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookConfigOperation.java new file mode 100644 index 0000000000..1673c6e257 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookConfigOperation.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.api; + +import java.util.List; + +/** + * WebHookConfigOperation + */ +public interface WebHookConfigOperation { + + public Integer insertWebHookConfig(WebHookConfig webHookConfig); + + public Integer updateWebHookConfig(WebHookConfig webHookConfig); + + public Integer deleteWebHookConfig(WebHookConfig webHookConfig); + + public WebHookConfig queryWebHookConfigById(WebHookConfig webHookConfig); + + public List queryWebHookConfigByManufacturer(WebHookConfig webHookConfig, Integer pageNum, + Integer pageSize); +} diff --git a/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookOperationConstant.java b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookOperationConstant.java new file mode 100644 index 0000000000..2a887f682f --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/WebHookOperationConstant.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.api; + +import java.io.File; + +public class WebHookOperationConstant { + + public static final String FILE_SEPARATOR = File.separator; + + public static final String FILE_EXTENSION = ".json"; + + public static final String GROUP_PREFIX = "webhook_"; + + public static final String CALLBACK_PATH_PREFIX = "/webhook"; + + public static final String DATA_ID_EXTENSION = ".json"; + + public static final String MANUFACTURERS_DATA_ID = "manufacturers" + DATA_ID_EXTENSION; + + public static final long TIMEOUT_MS = 3 * 1000L; + + public static final String ADMIN_START_CONFIG_NAME = "eventMesh.webHook.admin.start"; + + public static final String OPERATION_MODE_CONFIG_NAME = "eventMesh.webHook.operationMode"; + + public static final String getFilePath(String filePath) { + if (filePath.startsWith("#{eventMeshHome}")) { + String configPath = System.getProperty("confPath", System.getenv("confPath")); + + filePath = filePath.replace("#{eventMeshHome}", configPath.substring(0, configPath.lastIndexOf(FILE_SEPARATOR))); + } + return filePath; + } + +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/bin/.gitignore b/eventmesh-webhook/eventmesh-webhook-receive/bin/.gitignore new file mode 100644 index 0000000000..ddf9c65631 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/bin/.gitignore @@ -0,0 +1 @@ +/main/ diff --git a/eventmesh-webhook/eventmesh-webhook-receive/build.gradle b/eventmesh-webhook/eventmesh-webhook-receive/build.gradle new file mode 100644 index 0000000000..15a1489251 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/build.gradle @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +dependencies { + + compileOnly project(":eventmesh-common") + implementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") + implementation project(":eventmesh-webhook:eventmesh-webhook-api") + implementation project(":eventmesh-connector-plugin:eventmesh-connector-api") + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + implementation "io.openmessaging:openmessaging-api" + + implementation "io.cloudevents:cloudevents-core" + implementation "io.cloudevents:cloudevents-json-jackson" + implementation "com.alibaba.nacos:nacos-client:2.0.4" + implementation "com.fasterxml.jackson.core:jackson-databind" + implementation "com.fasterxml.jackson.core:jackson-core" + implementation "com.fasterxml.jackson.core:jackson-annotations" + + testImplementation project(":eventmesh-webhook:eventmesh-webhook-api") + + +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/gradle.properties b/eventmesh-webhook/eventmesh-webhook-receive/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/ManufacturerProtocol.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/ManufacturerProtocol.java new file mode 100644 index 0000000000..db93baed72 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/ManufacturerProtocol.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive; + +import org.apache.eventmesh.webhook.api.WebHookConfig; + +import java.util.Map; + +/** + * Information and protocol resolution methods for different manufacturers + */ +public interface ManufacturerProtocol { + + String getManufacturerName(); + + + /** + * - 1.authentication + * - 2.parse webhook content to WebHookRequest + * + * @param webHookRequest formatted data + * @param webHookConfig webhook config + * @param header webhook content header + * @throws Exception authenticate failed ,or content parse failed + */ + void execute(WebHookRequest webHookRequest, WebHookConfig webHookConfig, Map header) throws Exception; +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookController.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookController.java new file mode 100644 index 0000000000..0d0279f38b --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookController.java @@ -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 org.apache.eventmesh.webhook.receive; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.common.config.ConfigurationWrapper; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.http.WebhookProtocolTransportObject; +import org.apache.eventmesh.protocol.api.ProtocolAdaptor; +import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.receive.protocol.ProtocolManage; +import org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManage; + +import java.util.Map; +import java.util.Objects; +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import lombok.Setter; + +public class WebHookController { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * protocol pool + */ + private final ProtocolManage protocolManage = new ProtocolManage(); + + /** + * config pool + */ + private HookConfigOperationManage hookConfigOperationManage; + + private WebHookMQProducer webHookMQProducer; + + private ProtocolAdaptor protocolAdaptor; + + @Setter + private ConfigurationWrapper configurationWrapper; + + public void init() throws Exception { + this.webHookMQProducer = new WebHookMQProducer( + configurationWrapper.getProp("eventMesh.webHook.producer.connector")); + this.hookConfigOperationManage = new HookConfigOperationManage(configurationWrapper); + this.protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor("webhookProtocolAdaptor"); + + } + + /** + * 1. get webhookConfig from path 2. get ManufacturerProtocol and execute 3. + * convert to cloudEvent obj 4. send cloudEvent + * + * @param path CallbackPath + * @param header map of webhook request header + * @param body data + */ + public void execute(String path, Map header, byte[] body) throws Exception { + + // 1. get webhookConfig from path + WebHookConfig webHookConfig = new WebHookConfig(); + webHookConfig.setCallbackPath(path); + webHookConfig = hookConfigOperationManage.queryWebHookConfigById(webHookConfig); + if (webHookConfig == null) { + throw new Exception("No matching webhookConfig."); + } + + if (!Objects.equals(webHookConfig.getContentType(), header.get("content-type"))) { + throw new Exception( + "http request header content-type value is mismatch. current value " + header.get("content-type")); + } + + // 2. get ManufacturerProtocol and execute + String manufacturerName = webHookConfig.getManufacturerName(); + ManufacturerProtocol protocol = protocolManage.getManufacturerProtocol(manufacturerName); + WebHookRequest webHookRequest = new WebHookRequest(); + webHookRequest.setData(body); + try { + protocol.execute(webHookRequest, webHookConfig, header); + } catch (Exception e) { + throw new Exception("Webhook Message Parse Failed."); + } + + // 3. convert to cloudEvent obj + String cloudEventId = "uuid".equals(webHookConfig.getCloudEventIdGenerateMode()) ? UUID.randomUUID().toString() + : webHookRequest.getManufacturerEventId(); + String eventType = manufacturerName + "." + webHookConfig.getManufacturerEventName(); + + WebhookProtocolTransportObject webhookProtocolTransportObject = WebhookProtocolTransportObject.builder() + .cloudEventId(cloudEventId).eventType(eventType).cloudEventName(webHookConfig.getCloudEventName()) + .dataContentType(webHookConfig.getDataContentType()).body(body).build(); + + // 4. send cloudEvent + webHookMQProducer.send(this.protocolAdaptor.toCloudEvent(webhookProtocolTransportObject), new SendCallback() { + @Override + public void onSuccess(SendResult sendResult) { + if (logger.isDebugEnabled()) { + logger.debug(sendResult.toString()); + } + } + + @Override + public void onException(OnExceptionContext context) { + logger.warn("", context.getException()); + } + + }); + } + +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookMQProducer.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookMQProducer.java new file mode 100644 index 0000000000..4058b233fb --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookMQProducer.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.factory.ConnectorPluginFactory; +import org.apache.eventmesh.api.producer.Producer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.cloudevents.CloudEvent; + +public class WebHookMQProducer { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected Producer hookMQProducer; + + public WebHookMQProducer(String connectorPluginType) { + this.hookMQProducer = ConnectorPluginFactory.getMeshMQProducer(connectorPluginType); + if (hookMQProducer == null) { + logger.error("can't load the hookMQProducer plugin, please check."); + throw new RuntimeException("doesn't load the hookMQProducer plugin, please check."); + } + } + + public void send(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { + hookMQProducer.publish(cloudEvent, sendCallback); + } + + public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) + throws Exception { + hookMQProducer.request(cloudEvent, rrCallback, timeout); + } + + public boolean reply(final CloudEvent cloudEvent, final SendCallback sendCallback) throws Exception { + return hookMQProducer.reply(cloudEvent, sendCallback); + } + + public Producer getHookMQProducer() { + return hookMQProducer; + } + +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookRequest.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookRequest.java new file mode 100644 index 0000000000..7fdc78bd86 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/WebHookRequest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive; + +import lombok.Data; + +@Data +public class WebHookRequest { + + /** + * manufacturer event id + */ + private String manufacturerEventId; + + /** + * manufacturer event name + */ + private String manufacturerEventName; + + /** + * manufacturer name + */ + private String manufacturerSource; + + /** + * webhook request body + */ + private byte[] data; +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/protocol/GithubProtocol.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/protocol/GithubProtocol.java new file mode 100644 index 0000000000..6f20db94e5 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/protocol/GithubProtocol.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive.protocol; + + +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.receive.ManufacturerProtocol; +import org.apache.eventmesh.webhook.receive.WebHookRequest; + +import java.util.Map; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GithubProtocol implements ManufacturerProtocol { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public String getManufacturerName() { + return "github"; + } + + @Override + public void execute(WebHookRequest webHookRequest, WebHookConfig webHookConfig, Map header) throws Exception { + + String fromSignature = header.get("X-Hub-Signature-256"); + if (!isValid(fromSignature, webHookRequest.getData(), webHookConfig.getSecret())) { + throw new Exception("webhook-GithubProtocol authenticate failed"); + } + + try { + webHookRequest.setManufacturerEventId(header.get("X-GitHub-Delivery")); + webHookRequest.setManufacturerEventName(webHookConfig.getManufacturerEventName()); + webHookRequest.setManufacturerSource(getManufacturerName()); + } catch (Exception e) { + throw new Exception("webhook-GithubProtocol parse failed"); + } + } + + /** + * Authentication + * + * @param fromSignature Signature received + * @param data data + * @param secret secret key + * @return Authentication result + */ + private Boolean isValid(String fromSignature, byte[] data, String secret) { + String hash = "sha256="; + try { + Mac sha = Mac.getInstance("HmacSHA256"); + SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); + sha.init(secretKey); + byte[] bytes = sha.doFinal(data); + hash += byteArrayToHexString(bytes); + } catch (Exception e) { + logger.error("Error HmacSHA256", e); + } + return hash.equals(fromSignature); + } + + /** + * byte array -> hexadecimal character string + * + * @param b byte array + * @return hexadecimal character string + */ + private String byteArrayToHexString(byte[] b) { + StringBuilder hs = new StringBuilder(); + String stmp; + for (int n = 0; b != null && n < b.length; n++) { + stmp = Integer.toHexString(b[n] & 0XFF); + if (stmp.length() == 1) { + hs.append('0'); + } + hs.append(stmp); + } + return hs.toString().toLowerCase(); + } +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/protocol/ProtocolManage.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/protocol/ProtocolManage.java new file mode 100644 index 0000000000..9c10efe874 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/protocol/ProtocolManage.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive.protocol; + +import org.apache.eventmesh.webhook.receive.ManufacturerProtocol; + +import java.util.HashMap; +import java.util.Map; + +public class ProtocolManage { + + /** + * ManufacturerProtocol pool + */ + private final Map protocolMap = new HashMap<>(); + + { + this.register(new GithubProtocol()); + } + + void register(ManufacturerProtocol manufacturerProtocol) { + protocolMap.put(manufacturerProtocol.getManufacturerName(), manufacturerProtocol); + } + + public ManufacturerProtocol getManufacturerProtocol(String manufacturerName) { + return protocolMap.get(manufacturerName); + } +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/AbstractWebHookConfigOperation.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/AbstractWebHookConfigOperation.java new file mode 100644 index 0000000000..cc06685ed2 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/AbstractWebHookConfigOperation.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive.storage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractWebHookConfigOperation { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/HookConfigOperationManage.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/HookConfigOperationManage.java new file mode 100644 index 0000000000..d47c7f89ca --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/HookConfigOperationManage.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive.storage; + +import static org.apache.eventmesh.webhook.api.WebHookOperationConstant.DATA_ID_EXTENSION; +import static org.apache.eventmesh.webhook.api.WebHookOperationConstant.GROUP_PREFIX; +import static org.apache.eventmesh.webhook.api.WebHookOperationConstant.TIMEOUT_MS; + +import org.apache.eventmesh.common.config.ConfigurationWrapper; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookConfigOperation; +import org.apache.eventmesh.webhook.api.WebHookOperationConstant; + +import java.io.FileNotFoundException; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.nacos.api.config.ConfigFactory; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.exception.NacosException; + +public class HookConfigOperationManage implements WebHookConfigOperation { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private String operationMode; + + private ConfigService nacosConfigService; + + /** + * webhook config pool -> key is CallbackPath + */ + private final Map cacheWebHookConfig = new ConcurrentHashMap<>(); + + public HookConfigOperationManage() { + } + + /** + * Initialize according to operationMode + * + * @param configurationWrapper + */ + public HookConfigOperationManage(ConfigurationWrapper configurationWrapper) throws FileNotFoundException, NacosException { + + this.operationMode = configurationWrapper.getProp(WebHookOperationConstant.OPERATION_MODE_CONFIG_NAME); + + if ("file".equals(operationMode)) { + new WebhookFileListener(configurationWrapper.getProp("eventMesh.webHook.fileMode.filePath"), cacheWebHookConfig); + } else if ("nacos".equals(operationMode)) { + nacosModeInit(configurationWrapper.getPropertiesByConfig("eventMesh.webHook.nacosMode", true)); + } + } + + private void nacosModeInit(Properties config) throws NacosException { + nacosConfigService = ConfigFactory.createConfigService(config); + } + + @Override + public WebHookConfig queryWebHookConfigById(WebHookConfig webHookConfig) { + if ("file".equals(operationMode)) { + return cacheWebHookConfig.get(webHookConfig.getCallbackPath()); + } else if ("nacos".equals(operationMode)) { + try { + String content = nacosConfigService.getConfig(webHookConfig.getManufacturerEventName() + DATA_ID_EXTENSION, + GROUP_PREFIX + webHookConfig.getManufacturerName(), TIMEOUT_MS); + return JsonUtils.deserialize(content, WebHookConfig.class); + } catch (NacosException e) { + logger.error("queryWebHookConfigById failed", e); + } + } + return null; + } + + @Override + public List queryWebHookConfigByManufacturer(WebHookConfig webHookConfig, Integer pageNum, + Integer pageSize) { + return null; + } + + @Override + public Integer insertWebHookConfig(WebHookConfig webHookConfig) { + cacheWebHookConfig.put(webHookConfig.getCallbackPath(), webHookConfig); + return 1; + } + + @Override + public Integer updateWebHookConfig(WebHookConfig webHookConfig) { + cacheWebHookConfig.put(webHookConfig.getCallbackPath(), webHookConfig); + return 1; + } + + @Override + public Integer deleteWebHookConfig(WebHookConfig webHookConfig) { + cacheWebHookConfig.remove(webHookConfig.getCallbackPath()); + return 1; + } + +} diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/WebhookFileListener.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/WebhookFileListener.java new file mode 100644 index 0000000000..c4e8410ffa --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/WebhookFileListener.java @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.webhook.receive.storage; + +import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.webhook.api.WebHookConfig; +import org.apache.eventmesh.webhook.api.WebHookOperationConstant; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.FileSystems; +import java.nio.file.Paths; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebhookFileListener { + + public Logger logger = LoggerFactory.getLogger(this.getClass()); + + private String filePath; + + private Map cacheWebHookConfig; + + private final Set pathSet = new LinkedHashSet<>(); // monitored subdirectory + + private final Map watchKeyPathMap = new HashMap<>(); // WatchKey's path + + public WebhookFileListener() { + } + + public WebhookFileListener(String filePath, Map cacheWebHookConfig) throws FileNotFoundException { + this.filePath = WebHookOperationConstant.getFilePath(filePath); + this.cacheWebHookConfig = cacheWebHookConfig; + filePatternInit(); + } + + /** + * Read the directory and register the listener + * + */ + public void filePatternInit() { + File webHookFileDir = new File(filePath); + if (!webHookFileDir.exists()) { + webHookFileDir.mkdirs(); + } else { + readFiles(webHookFileDir); + } + fileWatchRegister(); + } + + /** + * Recursively traverse the folder + * + * @param file file + */ + public void readFiles(File file) { + File[] fs = file.listFiles(); + for (File f : Objects.requireNonNull(fs)) { + if (f.isDirectory()) { + readFiles(f); + } else if (f.isFile()) { + cacheInit(f); + } + } + } + + /** + * Read the file and cache it in map + * + * @param webhookConfigFile webhookConfigFile + */ + public void cacheInit(File webhookConfigFile) { + StringBuilder fileContent = new StringBuilder(); + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(webhookConfigFile)))) { + String line = null; + while ((line = br.readLine()) != null) { + fileContent.append(line); + } + } catch (IOException e) { + logger.error("cacheInit failed", e); + } + WebHookConfig webHookConfig = JsonUtils.deserialize(fileContent.toString(), WebHookConfig.class); + cacheWebHookConfig.put(webHookConfig.getCallbackPath(), webHookConfig); + } + + /** + * Register listeners with folders + */ + public void fileWatchRegister() { + ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1); + cachedThreadPool.execute(() -> { + File root = new File(filePath); + loopDirInsertToSet(root, pathSet); + + WatchService service = null; + try { + service = FileSystems.getDefault().newWatchService(); + } catch (Exception e) { + logger.error("getWatchService failed.", e); + } + + for (String path : pathSet) { + WatchKey key = null; + try { + key = Paths.get(path).register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE); + } catch (IOException e) { + logger.error("registerWatchKey failed", e); + } + watchKeyPathMap.put(key, path); + } + + while (true) { + WatchKey key = null; + try { + assert service != null; + key = service.take(); + } catch (InterruptedException e) { + logger.error("Interrupted", e); + } + + assert key != null; + for (WatchEvent event : key.pollEvents()) { + String flashPath = watchKeyPathMap.get(key); + // manufacturer change + if (flashPath.equals(filePath)) { + if (ENTRY_CREATE == event.kind()) { + try { + key = Paths.get(filePath + event.context()).register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE); + } catch (IOException e) { + logger.error("registerWatchKey failed", e); + } + watchKeyPathMap.put(key, filePath + event.context()); + } + } else { // config change + cacheInit(new File(flashPath + event.context())); + } + } + if (!key.reset()) { + break; + } + } + }); + } + + /** + * Recursive folder, adding folder's path to set + * + * @param parent parent folder + * @param pathSet folder's path set + */ + private void loopDirInsertToSet(File parent, Set pathSet) { + if (!parent.isDirectory()) { + return; + } + pathSet.add(parent.getPath()); + for (File child : Objects.requireNonNull(parent.listFiles())) { + loopDirInsertToSet(child, pathSet); + } + } +} diff --git a/eventmesh-webhook/gradle.properties b/eventmesh-webhook/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-webhook/gradle.properties @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/eventmesh-webhook/webhook.jmx b/eventmesh-webhook/webhook.jmx new file mode 100644 index 0000000000..9bc56e8073 --- /dev/null +++ b/eventmesh-webhook/webhook.jmx @@ -0,0 +1,122 @@ + + + + + + + false + true + false + + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + + + + + + content-type + application/json + + + + + + true + + + + false + { +"callbackPath":"/webhook/test", +"manufacturerName":"1111" +} + = + + + + 127.0.0.1 + 10106 + + + /webhook/insertWebHookConfig + POST + true + false + true + false + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + + + diff --git a/gradle.properties b/gradle.properties index 0f01d9b8a2..0b8550584a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,11 +14,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # -group=cn.webank.eventmesh -version=1.0.0 -rocketmqVersion=4.4.0 + jdk=1.8 snapshot=false -mavenUserName= -mavenPassword= -#org.gradle.java.home=C:\\Program Files\\Java\\jdk1.7.0_67 +group=org.apache.eventmesh +version=1.3.0-release +#last eight bits of public key +signing.keyId= +#passphrase for key pairs +signing.password= +#path of exporting private key +signing.secretKeyRingFile= +#apache id +apacheUserName= +#apache password +apachePassWord= +signEnabled=false + +org.gradle.warning.mode=none diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c05355..7454180f2a 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1581427f9a..fc9e13bc0c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,22 @@ -#Tue Jul 21 17:31:52 CST 2020 -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c51583..b20efadc69 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/usr/bin/env sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,9 +17,49 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME @@ -72,7 +112,7 @@ case "`uname`" in Darwin* ) darwin=true ;; - MINGW* ) + MSYS* | MINGW* ) msys=true ;; NONSTOP* ) @@ -130,7 +170,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 5093609d51..477c896641 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell @@ -101,4 +86,4 @@ exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega +:omega \ No newline at end of file diff --git a/install.sh b/install.sh index 04e66998ef..7acf43d904 100644 --- a/install.sh +++ b/install.sh @@ -1,5 +1,23 @@ #!/usr/bin/env bash # +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + # -Pdev=true : snapshot version # -Pjdk=1.8 : jdk version,default 1.8 # dist : resource collect @@ -8,7 +26,7 @@ # jar : produce jar # package tar.gz/zip -gradle clean -Pdev=true -Pjdk=1.7 dist tar zip +gradle clean -Pdev=true -Pjdk=1.8 dist tar zip # package jar -gradle clean -Pdev=true -Pjdk=1.7 jar \ No newline at end of file +gradle clean -Pdev=true -Pjdk=1.8 jar \ No newline at end of file diff --git a/releasenotes.txt b/releasenotes.txt deleted file mode 100644 index 0d48a10a49..0000000000 --- a/releasenotes.txt +++ /dev/null @@ -1,9 +0,0 @@ --------------------------VERSION 1.0.0----------------------------- -1. implement of sync-request producer. -2. dark launch -3. circuit breaker mechanism -4. invoke service nearby -5. (tong cheng duo huo) -6. dynamic adjust queue -7. isolation mechanism -8. fault tolerant \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index db8d9fa707..0b219b62e5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,12 +15,46 @@ * limitations under the License. */ -rootProject.name = 'EventMesh' +rootProject.name = 'incubator-eventmesh' String jdkVersion = "${jdk}" -include 'eventmesh-emesher' -include 'eventmesh-governance' -include 'eventmesh-registry' -include 'eventmesh-acl' -include 'eventmesh-store' +include 'eventmesh-runtime' include 'eventmesh-sdk-java' +include 'eventmesh-common' +include 'eventmesh-starter' +include 'eventmesh-examples' +include 'eventmesh-spi' +include 'eventmesh-connector-plugin:eventmesh-connector-api' +include 'eventmesh-connector-plugin:eventmesh-connector-rocketmq' +include 'eventmesh-connector-plugin:eventmesh-connector-standalone' +include 'eventmesh-security-plugin:eventmesh-security-api' +include 'eventmesh-security-plugin:eventmesh-security-acl' +include 'eventmesh-registry-plugin:eventmesh-registry-api' +include 'eventmesh-registry-plugin:eventmesh-registry-nacos' +include 'eventmesh-registry-plugin:eventmesh-registry-etcd' +include 'eventmesh-registry-plugin:eventmesh-registry-consul' +include 'eventmesh-admin' +include 'eventmesh-protocol-plugin' +include 'eventmesh-protocol-plugin:eventmesh-protocol-api' +include 'eventmesh-protocol-plugin:eventmesh-protocol-openmessage' +include 'eventmesh-protocol-plugin:eventmesh-protocol-cloudevents' +include 'eventmesh-protocol-plugin:eventmesh-protocol-meshmessage' +include 'eventmesh-protocol-plugin:eventmesh-protocol-http' +include 'eventmesh-admin:eventmesh-admin-rocketmq' +include 'eventmesh-protocol-plugin:eventmesh-protocol-grpc' +include 'eventmesh-protocol-plugin:eventmesh-protocol-grpcmessage' +include 'eventmesh-metrics-plugin' +include 'eventmesh-metrics-plugin:eventmesh-metrics-api' +include 'eventmesh-metrics-plugin:eventmesh-metrics-prometheus' + +include 'eventmesh-security-plugin:eventmesh-security-auth-http-basic' + +include 'eventmesh-trace-plugin' +include 'eventmesh-trace-plugin:eventmesh-trace-api' +include 'eventmesh-trace-plugin:eventmesh-trace-zipkin' + + +include 'eventmesh-webhook' +include 'eventmesh-webhook:eventmesh-webhook-api' +include 'eventmesh-webhook:eventmesh-webhook-admin' +include 'eventmesh-webhook:eventmesh-webhook-receive' diff --git a/style/checkStyle.xml b/style/checkStyle.xml new file mode 100644 index 0000000000..f573dd3f98 --- /dev/null +++ b/style/checkStyle.xml @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/style/codeStyle.xml b/style/codeStyle.xml deleted file mode 100644 index 9b4e561f9c..0000000000 --- a/style/codeStyle.xml +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - diff --git a/style/copyright/Apache.xml b/style/copyright/Apache.xml deleted file mode 100644 index 8b112eea16..0000000000 --- a/style/copyright/Apache.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/tools/dependency-check/check-dependencies.sh b/tools/dependency-check/check-dependencies.sh new file mode 100644 index 0000000000..ddf8701107 --- /dev/null +++ b/tools/dependency-check/check-dependencies.sh @@ -0,0 +1,56 @@ +#!/usr/bin bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# ******************************************************************** +# This script used to check the dependencies are all in our exception. +# This will not check the license legality +# ******************************************************************** + +# Used to store the tmp files. +decompress_conf='build/tmp' +# store all dependencies from our binary jar. +all_dependencies_txt='tools/dependency-check/all-dependencies.txt' +# store all our known dependencies +known_third_party_dependencies_txt='tools/dependency-check/known-dependencies.txt' + +# Below files is generated by this script. +# store all EventMesh self module's name. +self_modules_txt='tools/dependency-check/self-modules.txt' +# store all third part dependencies +third_party_dependencies_txt='tools/dependency-check/third-party-dependencies.txt' + +mkdir $decompress_conf || true +tar -zxf build/incubator-eventmesh*.tar.gz -C $decompress_conf + +./gradlew printProjects | grep '.jar' > "$self_modules_txt" + +find "$decompress_conf" -name "*.jar" -exec basename {} \; | uniq | sort > "$all_dependencies_txt" + +grep -wvf "$self_modules_txt" "$all_dependencies_txt" | uniq | sort > "$third_party_dependencies_txt" + +# If the check is success it will return 0 +sort "$known_third_party_dependencies_txt" | diff - "$third_party_dependencies_txt" + +compareCode=$? +if [ $compareCode -eq 0 ] +then + echo "Dependencies check success" +else + echo "Dependencies check failed, please check if you add unknown dependencies" + exit $compareCode +fi diff --git a/tools/dependency-check/known-dependencies.txt b/tools/dependency-check/known-dependencies.txt new file mode 100644 index 0000000000..6e051f5fb9 --- /dev/null +++ b/tools/dependency-check/known-dependencies.txt @@ -0,0 +1,138 @@ +animal-sniffer-annotations-1.17.jar +assertj-core-2.6.0.jar +bcpkix-jdk15on-1.69.jar +bcprov-jdk15on-1.69.jar +bcutil-jdk15on-1.69.jar +checker-qual-3.12.0.jar +cloudevents-api-2.2.0.jar +cloudevents-core-2.2.0.jar +cloudevents-json-jackson-2.2.0.jar +commons-beanutils-1.9.4.jar +commons-cli-1.2.jar +commons-codec-1.11.jar +commons-collections-3.2.2.jar +commons-collections4-4.1.jar +commons-digester-2.1.jar +commons-lang3-3.6.jar +commons-logging-1.2.jar +commons-text-1.9.jar +commons-validator-1.7.jar +consul-api-1.4.5.jar +disruptor-3.4.2.jar +dledger-0.2.3.jar +error_prone_annotations-2.7.1.jar +failureaccess-1.0.1.jar +fastjson-1.2.76.jar +grpc-context-1.17.1.jar +grpc-core-1.17.1.jar +grpc-netty-1.17.1.jar +grpc-netty-shaded-1.17.1.jar +grpc-protobuf-1.17.1.jar +grpc-protobuf-lite-1.17.1.jar +grpc-stub-1.17.1.jar +grpc-grpclb-1.17.1.jar +gson-2.8.2.jar +guava-31.0.1-jre.jar +hamcrest-core-1.3.jar +httpasyncclient-4.1.3.jar +httpclient-4.5.13.jar +httpcore-4.4.13.jar +httpcore-nio-4.4.6.jar +ipaddress-5.3.3.jar +j2objc-annotations-1.3.jar +jackson-annotations-2.13.0.jar +jackson-core-2.13.0.jar +jackson-databind-2.13.0.jar +javassist-3.24.0-GA.jar +javax.annotation-api-1.3.2.jar +jcommander-1.72.jar +jetcd-core-0.3.0.jar +jetcd-common-0.3.0.jar +jetcd-resolver-0.3.0.jar +jna-4.2.2.jar +jsr305-3.0.2.jar +junit-4.13.2.jar +listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar +log4j-api-2.17.1.jar +log4j-core-2.17.1.jar +log4j-slf4j-impl-2.17.1.jar +metrics-annotation-4.1.0.jar +metrics-core-4.1.0.jar +metrics-healthchecks-4.1.0.jar +metrics-json-4.1.0.jar +nacos-client-2.0.4.jar +netty-all-4.1.73.Final.jar +netty-buffer-4.1.73.Final.jar +netty-codec-4.1.73.Final.jar +netty-codec-dns-4.1.73.Final.jar +netty-codec-haproxy-4.1.73.Final.jar +netty-codec-http-4.1.73.Final.jar +netty-codec-http2-4.1.73.Final.jar +netty-codec-memcache-4.1.73.Final.jar +netty-codec-mqtt-4.1.73.Final.jar +netty-codec-redis-4.1.73.Final.jar +netty-codec-smtp-4.1.73.Final.jar +netty-codec-socks-4.1.73.Final.jar +netty-codec-stomp-4.1.73.Final.jar +netty-codec-xml-4.1.73.Final.jar +netty-common-4.1.73.Final.jar +netty-handler-4.1.73.Final.jar +netty-handler-proxy-4.1.73.Final.jar +netty-resolver-4.1.73.Final.jar +netty-resolver-dns-4.1.73.Final.jar +netty-resolver-dns-classes-macos-4.1.73.Final.jar +netty-resolver-dns-native-macos-4.1.73.Final-osx-aarch_64.jar +netty-resolver-dns-native-macos-4.1.73.Final-osx-x86_64.jar +netty-tcnative-classes-2.0.46.Final.jar +netty-transport-4.1.73.Final.jar +netty-transport-classes-epoll-4.1.73.Final.jar +netty-transport-classes-kqueue-4.1.73.Final.jar +netty-transport-native-epoll-4.1.73.Final-linux-aarch_64.jar +netty-transport-native-epoll-4.1.73.Final-linux-x86_64.jar +netty-transport-native-kqueue-4.1.73.Final-osx-aarch_64.jar +netty-transport-native-kqueue-4.1.73.Final-osx-x86_64.jar +netty-transport-native-unix-common-4.1.73.Final.jar +netty-transport-rxtx-4.1.73.Final.jar +netty-transport-sctp-4.1.73.Final.jar +netty-transport-udt-4.1.73.Final.jar +okhttp-3.14.9.jar +okio-1.17.2.jar +opencensus-api-0.17.0.jar +opencensus-contrib-grpc-metrics-0.17.0.jar +openmessaging-api-2.2.1-pubsub.jar +opentelemetry-api-1.3.0.jar +opentelemetry-api-metrics-1.3.0-alpha.jar +opentelemetry-context-1.3.0.jar +opentelemetry-exporter-prometheus-1.3.0-alpha.jar +opentelemetry-exporter-zipkin-1.3.0.jar +opentelemetry-sdk-1.3.0.jar +opentelemetry-sdk-common-1.3.0.jar +opentelemetry-sdk-metrics-1.3.0-alpha.jar +opentelemetry-sdk-trace-1.3.0.jar +opentelemetry-semconv-1.3.0-alpha.jar +proto-google-common-protos-1.0.0.jar +protobuf-java-3.5.1.jar +protobuf-java-util-3.5.1.jar +reflections-0.9.11.jar +rocketmq-acl-4.9.3.jar +rocketmq-broker-4.9.3.jar +rocketmq-client-4.9.3.jar +rocketmq-common-4.9.3.jar +rocketmq-filter-4.9.3.jar +rocketmq-logging-4.9.3.jar +rocketmq-namesrv-4.9.3.jar +rocketmq-remoting-4.9.3.jar +rocketmq-srvutil-4.9.3.jar +rocketmq-store-4.9.3.jar +rocketmq-test-4.9.3.jar +rocketmq-tools-4.9.3.jar +simpleclient-0.8.1.jar +simpleclient_common-0.8.1.jar +simpleclient_httpserver-0.8.1.jar +slf4j-api-1.7.30.jar +snakeyaml-1.30.jar +system-rules-1.16.1.jar +truth-0.30.jar +zipkin-2.23.2.jar +zipkin-reporter-2.16.3.jar +zipkin-sender-okhttp3-2.16.3.jar \ No newline at end of file diff --git a/tools/third-party-licenses/LICENSE b/tools/third-party-licenses/LICENSE new file mode 100644 index 0000000000..f2874e0a33 --- /dev/null +++ b/tools/third-party-licenses/LICENSE @@ -0,0 +1,477 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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 EventMesh (incubating) Subcomponents: + +The Apache EventMesh (incubating) project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for the these +subcomponents is subject to the terms and conditions of the following +licenses. + +======================================================================== +Apache 2.0 licenses +======================================================================== + +The following components are provided under the Apache License. See project link for details. +The text of each license is also included at licenses/LICENSE-[project].txt. + + assertj-core 2.6.0: https://github.com/assertj/assertj-core, Apache 2.0 + cloudevents-api 2.2.0: https://github.com/cloudevents/sdk-java, Apache 2.0 + cloudevents-core 2.2.0: https://github.com/cloudevents/sdk-java, Apache 2.0 + cloudevents-json-jackson 2.2.0: https://github.com/cloudevents/sdk-java, Apache 2.0 + commons-beanutils 1.9.4: https://github.com/apache/commons-beanutils, Apache 2.0 + commons-cli 1.2: https://github.com/apache/commons-cli, Apache 2.0 + commons-codec 1.11: https://github.com/apache/commons-codec, Apache 2.0 + commons-collections 3.2.2: https://github.com/apache/commons-collections, Apache 2.0 + commons-collections4 4.1: https://github.com/apache/commons-collections, Apache 2.0 + commons-digester 2.1: https://github.com/apache/commons-digester, Apache 2.0 + commons-lang3 3.6: https://github.com/apache/commons-lang, Apache 2.0 + commons-logging 1.2: https://github.com/apache/commons-logging, Apache 2.0 + commons-text 1.9: https://github.com/apache/commons-text, Apache 2.0 + commons-validator 1.7: https://github.com/apache/commons-validator, Apache 2.0 + disruptor 3.4.2: https://github.com/LMAX-Exchange/disruptor, Apache 2.0 + dledger 0.2.3: https://github.com/openmessaging/dledger, Apache 2.0 + error_prone_annotations 2.7.1: https://github.com/google/error-prone, Apache 2.0 + failureaccess 1.0.1: https://github.com/google/guava, Apache 2.0 + listenablefuture 9999.0-empty-to-avoid-conflict-with-guava: https://github.com/google/guava, Apache 2.0 + fastjson 1.2.76: https://github.com/alibaba/fastjson, Apache 2.0 + guava 31.0.1-jre: https://github.com/google/guava, Apache 2.0 + grpc-context 1.17.1: https://github.com/grpc/grpc-java, Apache 2.0 + grpc-core 1.17.1: https://github.com/grpc/grpc-java, Apache 2.0 + grpc-netty 1.17.1: https://github.com/grpc/grpc-java, Apache 2.0 + grpc-netty-shaded 1.17.1: https://github.com/grpc/grpc-java, Apache 2.0 + grpc-protobuf 1.17.1: https://github.com/grpc/grpc-java, Apache 2.0 + grpc-protobuf-lite 1.17.1: https://github.com/grpc/grpc-java, Apache 2.0 + grpc-stub 1.17.1: https://github.com/grpc/grpc-java, Apache 2.0 + gson 2.7: https://github.com/google/gson, Apache 2.0 + httpclient 4.5.13: https://github.com/apache/httpcomponents-client, Apache 2.0 + httpcore 4.4.13: https://github.com/apache/httpcomponents-core, Apache 2.0 + j2objc-annotations 1.3: https://github.com/google/j2objc, Apache 2.0 + jackson-annotations 2.13.0: https://github.com/FasterXML/jackson-annotations, Apache 2.0 + jackson-core 2.13.0: https://github.com/FasterXML/jackson-core, Apache 2.0 + jackson-databind 2.13.0: https://github.com/FasterXML/jackson-databind, Apache 2.0 + javassist 3.20.0-GA/3.24.0-GA: https://github.com/jboss-javassist/javassist, Apache 2.0 + jcommander 1.72: https://github.com/cbeust/jcommander, Apache 2.0 + jna 4.2.2: https://github.com/java-native-access/jna, Apache 2.0 + log4j-api 2.17.1: https://github.com/apache/logging-log4j2, Apache 2.0 + log4j-core 2.17.1: https://github.com/apache/logging-log4j2, Apache 2.0 + log4j-slf4j-impl 2.17.1: https://github.com/apache/logging-log4j2, Apache 2.0 + metrics-annotation 4.1.0: https://github.com/dropwizard/metrics, Apache 2.0 + metrics-core 4.1.0: https://github.com/dropwizard/metrics, Apache 2.0 + metrics-healthchecks 4.1.0: https://github.com/dropwizard/metrics, Apache 2.0 + metrics-json 4.1.0: https://github.com/dropwizard/metrics, Apache 2.0 + netty-all 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-buffer 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-dns 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-haproxy 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-http 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-http2 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-memcache 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-mqtt 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-redis 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-smtp 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-socks 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-stomp 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-codec-xml 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-common 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-handler 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-handler-proxy 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-resolver 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-resolver-dns 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-resolver-dns-classes-macos 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-resolver-dns-native-macos 4.1.73.Final-osx-aarch_64: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-resolver-dns-native-macos 4.1.73.Final-osx-x86_64: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-tcnative-classes 2.0.46.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-classes-epoll 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-classes-kqueue 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-native-epoll 4.1.73.Final-linux-aarch_64: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-native-epoll 4.1.73.Final-linux-x86_64: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-native-kqueue 4.1.73.Final-osx-aarch_64: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-native-kqueue 4.1.73.Final-osx-x86_64: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-native-unix-common 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-rxtx 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-sctp 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + netty-transport-udt 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 + okio 1.17.2: https://github.com/square/okio, Apache 2.0 + okhttp 3.14.9: https://github.com/square/okhttp, Apache 2.0 + opencensus-api 0.12.3: https://github.com/census-instrumentation/opencensus-java, Apache 2.0 + opencensus-contrib-grpc-metrics 0.12.3: https://github.com/census-instrumentation/opencensus-java, Apache 2.0 + openmessaging-api 2.22.1-pubsub: https://github.com/openmessaging/dledger, Apache 2.0 + opentelemetry-api 1.3.0: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-api-metrics 1.3.0-alpha: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-context 1.3.0: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-exporter-prometheus 1.3.0-alpha: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-exporter-zipkin 1.3.0: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-sdk 1.3.0: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-sdk-common 1.3.0: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-sdk-metrics 1.3.0-alpha: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-sdk-trace 1.3.0: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + opentelemetry-semconv 1.3.0-alpha: https://github.com/open-telemetry/opentelemetry-java, Apache 2.0 + proto-google-common-protos 1.0.0: https://github.com/googleapis/common-protos-java, Apache 2.0 + rocketmq-acl 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-broker 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-client 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-common 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-filter 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-logging 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-namesrv 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-remoting 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-srvutil 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-store 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-test 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + rocketmq-tools 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 + simpleclient 0.8.1: https://github.com/prometheus/client_java, Apache 2.0 + simpleclient_common 0.8.1: https://github.com/prometheus/client_java, Apache 2.0 + simpleclient_httpserver 0.8.1: https://github.com/prometheus/client_java, Apache 2.0 + snakeyaml 1.23: https://bitbucket.org/asomov/snakeyaml, Apache 2.0 + snakeyaml 1.30: https://bitbucket.org/asomov/snakeyaml, Apache 2.0 + truth 0.30: https://github.com/google/truth, Apache 2.0 + zipkin 2.23.2: https://github.com/openzipkin/zipkin, Apache 2.0 + zipkin-reporter 2.16.3: https://github.com/openzipkin/zipkin-reporter-java, Apache 2.0 + zipkin-sender-okhttp3 2.16.3: https://github.com/openzipkin/zipkin-reporter-java, Apache 2.0 + bcpkix-jdk15on 1.69: https://github.com/bcgit/bc-java, Apache 2.0 + bcprov-jdk15on 1.69: https://github.com/bcgit/bc-java, Apache 2.0 + bcutil-jdk15on 1.69: https://github.com/bcgit/bc-java, Apache 2.0 + cloud.google.com/go v0.34.0 Apache-2.0 + github.com/OneOfOne/xxhash v1.2.2 Apache-2.0 + github.com/census-instrumentation/opencensus-proto v0.2.1 Apache-2.0 + github.com/cloudevents/sdk-go/v2 v2.6.0 Apache-2.0 + github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 Apache-2.0 + github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 Apache-2.0 + github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 Apache-2.0 + github.com/envoyproxy/protoc-gen-validate v0.1.0 Apache-2.0 + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b Apache-2.0 + github.com/golang/mock v1.1.1 Apache-2.0 + github.com/google/gofuzz v1.0.0 Apache-2.0 + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 Apache-2.0 + github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 Apache-2.0 + github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 Apache-2.0 + go.opentelemetry.io/proto/otlp v0.7.0 Apache-2.0 + google.golang.org/appengine v1.4.0 Apache-2.0 + google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 Apache-2.0 + google.golang.org/grpc v1.45.0 Apache-2.0 + gopkg.in/yaml.v2 v2.3.0 Apache-2.0 + +======================================================================== +BSD licenses +======================================================================== + +The following components are provided under a BSD license. See project link for details. +The text of each license is also included at licenses/LICENSE-[project].txt. + + hamcrest-core 1.3: https://github.com/hamcrest/JavaHamcrest, BSD + jsr305 3.0.2: https://code.google.com/archive/p/jsr-305, BSD + protobuf-java 3.5.1: https://github.com/protocolbuffers/protobuf, BSD + +======================================================================== +CDDL licenses +======================================================================== + +The following components are provided under the CDDL License. See project link for details. +The text of each license is also included at licenses/LICENSE-[project].txt. + + javax.annotation-api 1.3.2: https://github.com/javaee/javax.annotation , CDDL1.1 + +======================================================================== +CPL licenses +======================================================================== + +The following components are provided under the CPL License. See project link for details. +The text of each license is also included at licenses/LICENSE-[project].txt. + + system-rules 1.16.1: https://github.com/stefanbirkner/system-rules + +======================================================================== +EPL licenses +======================================================================== + +The following components are provided under the EPL License. See project link for details. +The text of each license is also included at licenses/LICENSE-[project].txt. + + junit 4.13.2: https://github.com/junit-team/junit5, EPL + +======================================================================== +MIT licenses +======================================================================== + +The following components are provided under the MIT license. See project link for details. +The text of each license is also included at licenses/LICENSE-[project].txt. + + checker-qual 3.12.0: https://github.com/typetools/checker-framework, MIT + slf4j-api 1.7.30: https://github.com/qos-ch/slf4j, MIT + github.com/BurntSushi/toml v0.3.1 MIT + github.com/antihax/optional v1.0.0 MIT + github.com/cespare/xxhash v1.1.0 MIT + github.com/cespare/xxhash/v2 v2.1.1 MIT + github.com/client9/misspell v0.3.4 MIT + github.com/creack/pty v1.1.9 MIT + github.com/deckarep/golang-set v1.7.1 + github.com/ghodss/yaml v1.0.0 MIT + github.com/json-iterator/go v1.1.10 MIT + github.com/kr/pty v1.1.1 MIT + github.com/kr/text v0.2.0 MIT + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e MIT + github.com/panjf2000/ants v1.3.0 MIT + github.com/sony/sonyflake v1.0.0 MIT + github.com/stretchr/objx v0.1.1 MIT + github.com/stretchr/testify v1.7.0 MIT + github.com/valyala/bytebufferpool v1.0.0 MIT + go.uber.org/atomic v1.4.0 MIT + go.uber.org/multierr v1.1.0 MIT + go.uber.org/zap v1.10.0 MIT + honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc MIT + +======================================================================== +BSD-3-Clause licenses +======================================================================== + +The following components are provided under the BSD-3-Clause License. See project link for details. +The text of each license is also included at licenses/license-[project].txt. + + github.com/golang/protobuf v1.5.2 BSD-3-Clause + github.com/google/go-cmp v0.5.5 BSD-3-Clause + github.com/google/uuid v1.3.0 BSD-3-Clause + github.com/grpc-ecosystem/grpc-gateway v1.16.0 BSD-3-Clause + github.com/pmezard/go-difflib v1.0.0 BSD-3-Clause + github.com/rogpeppe/fastuuid v1.2.0 BSD-3-Clause + github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 BSD-3-Clause + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 BSD-3-Clause + golang.org/x/exp v0.0.0-20190121172915-509febef88a4 BSD-3-Clause + golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 BSD-3-Clause + golang.org/x/net v0.0.0-20200822124328-c89045814202 BSD-3-Clause + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d BSD-3-Clause + golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e BSD-3-Clause + golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd BSD-3-Clause + golang.org/x/text v0.3.0 BSD-3-Clause + golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 BSD-3-Clause + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 BSD-3-Clause + +======================================================================== +ISC licenses +======================================================================== + +The following components are provided under the ISC License. See project link for details. +The text of each license is also included at licenses/license-[project].txt. + + github.com/davecgh/go-spew v1.1.1 ISC + +======================================================================== +BSD-2-Clause licenses +======================================================================== + +The following components are provided under the BSD-2-Clause License. See project link for details. +The text of each license is also included at licenses/license-[project].txt. + + github.com/pkg/errors v0.9.1 BSD-2-Clause + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f BSD-2-Clause + +======================================================================== +MIT and Apache licenses +======================================================================== + +The following components are provided under the MIT and Apache License. See project link for details. +The text of each license is also included at licenses/license-[project].txt. + + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c MIT and Apache diff --git a/tools/third-party-licenses/NOTICE b/tools/third-party-licenses/NOTICE new file mode 100644 index 0000000000..3f73a3ba6a --- /dev/null +++ b/tools/third-party-licenses/NOTICE @@ -0,0 +1,543 @@ +Apache EventMesh (incubating) +Copyright 2021-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +======================================================================== + +Apache Commons BeanUtils NOTICE + +========================================================================= +Apache Commons BeanUtils +Copyright 2000-2019 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +========================================================================= + +Apache Commons CLI NOTICE + +========================================================================= +Apache Commons CLI +Copyright 2002-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). + +========================================================================= + +Apache Commons Codec NOTICE +========================================================================= +Apache Commons Codec +Copyright 2002-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). + +src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java +contains test data from http://aspell.net/test/orig/batch0.tab. +Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org) + +=============================================================================== + +The content of package org.apache.commons.codec.language.bm has been translated +from the original php source code available at http://stevemorse.org/phoneticinfo.htm +with permission from the original authors. +Original source copyright: +Copyright (c) 2008 Alexander Beider & Stephen P. Morse. + +=============================================================================== + +Apache Commons Collections NOTICE +=============================================================================== + +Apache Commons Collections +Copyright 2001-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Apache Commons Collections NOTICE + +=============================================================================== +Apache Commons Collections +Copyright 2001-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Apache Commons Digester NOTICE + +=============================================================================== +Apache Commons Digester +Copyright 2001-2016 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Apache Commons Lang NOTICE + +=============================================================================== +Apache Commons Lang +Copyright 2001-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). + +=============================================================================== + +Apache Commons Logging NOTICE + +=============================================================================== +Apache Commons Logging +Copyright 2003-2016 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Apache Commons Text NOTICE + +=============================================================================== +Apache Commons Text +Copyright 2014-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). + +=============================================================================== + +Apache Commons Validator NOTICE + +=============================================================================== +Apache Commons Validator +Copyright 2001-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +grpc-java NOTICE + +=============================================================================== +Copyright 2014 The gRPC Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------------- + + +This product contains a modified portion of 'OkHttp', an open source +HTTP & SPDY client for Android and Java applications, which can be obtained +at: + + * LICENSE: + * okhttp/third_party/okhttp/LICENSE (Apache License 2.0) + * HOMEPAGE: + * https://github.com/square/okhttp + * LOCATION_IN_GRPC: + * okhttp/third_party/okhttp + +This product contains a modified portion of 'Envoy', an open source +cloud-native high-performance edge/middle/service proxy, which can be +obtained at: + + * LICENSE: + * xds/third_party/envoy/LICENSE (Apache License 2.0) + * NOTICE: + * xds/third_party/envoy/NOTICE + * HOMEPAGE: + * https://www.envoyproxy.io + * LOCATION_IN_GRPC: + * xds/third_party/envoy + +This product contains a modified portion of 'protoc-gen-validate (PGV)', +an open source protoc plugin to generate polyglot message validators, +which can be obtained at: + + * LICENSE: + * xds/third_party/protoc-gen-validate/LICENSE (Apache License 2.0) + * NOTICE: + * xds/third_party/protoc-gen-validate/NOTICE + * HOMEPAGE: + * https://github.com/envoyproxy/protoc-gen-validate + * LOCATION_IN_GRPC: + * xds/third_party/protoc-gen-validate + +This product contains a modified portion of 'udpa', +an open source universal data plane API, which can be obtained at: + + * LICENSE: + * xds/third_party/udpa/LICENSE (Apache License 2.0) + * HOMEPAGE: + * https://github.com/cncf/udpa + * LOCATION_IN_GRPC: + * xds/third_party/udpa + +=============================================================================== + +Apache HttpComponents Client NOTICE + +=============================================================================== +Apache HttpComponents Client +Copyright 1999-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Apache HttpComponents Core + +=============================================================================== +Apache HttpComponents Core +Copyright 2005-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Apache Log4j NOTICE + +=============================================================================== +Apache Log4j +Copyright 1999-2021 Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +ResolverUtil.java +Copyright 2005-2006 Tim Fennell + +Dumbster SMTP test server +Copyright 2004 Jason Paul Kitchen + +TypeUtil.java +Copyright 2002-2012 Ramnivas Laddad, Juergen Hoeller, Chris Beams + +picocli (http://picocli.info) +Copyright 2017 Remko Popma + +TimeoutBlockingWaitStrategy.java and parts of Util.java +Copyright 2011 LMAX Ltd. + +=============================================================================== + +The Netty Project NOTICE + +=============================================================================== + The Netty Project + ================= + +Please visit the Netty web site for more information: + + * https://netty.io/ + +Copyright 2014 The Netty Project + +The Netty Project licenses this file to you under the Apache License, +version 2.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. + +Also, please refer to each LICENSE..txt file, which is located in +the 'license' directory of the distribution file, for the license terms of the +components that this product depends on. + +------------------------------------------------------------------------------- +This product contains the extensions to Java Collections Framework which has +been derived from the works by JSR-166 EG, Doug Lea, and Jason T. Greene: + + * LICENSE: + * license/LICENSE.jsr166y.txt (Public Domain) + * HOMEPAGE: + * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/ + * http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/ + +This product contains a modified version of Robert Harder's Public Domain +Base64 Encoder and Decoder, which can be obtained at: + + * LICENSE: + * license/LICENSE.base64.txt (Public Domain) + * HOMEPAGE: + * http://iharder.sourceforge.net/current/java/base64/ + +This product contains a modified portion of 'Webbit', an event based +WebSocket and HTTP server, which can be obtained at: + + * LICENSE: + * license/LICENSE.webbit.txt (BSD License) + * HOMEPAGE: + * https://github.com/joewalnes/webbit + +This product contains a modified portion of 'SLF4J', a simple logging +facade for Java, which can be obtained at: + + * LICENSE: + * license/LICENSE.slf4j.txt (MIT License) + * HOMEPAGE: + * https://www.slf4j.org/ + +This product contains a modified portion of 'Apache Harmony', an open source +Java SE, which can be obtained at: + + * NOTICE: + * license/NOTICE.harmony.txt + * LICENSE: + * license/LICENSE.harmony.txt (Apache License 2.0) + * HOMEPAGE: + * https://archive.apache.org/dist/harmony/ + +This product contains a modified portion of 'jbzip2', a Java bzip2 compression +and decompression library written by Matthew J. Francis. It can be obtained at: + + * LICENSE: + * license/LICENSE.jbzip2.txt (MIT License) + * HOMEPAGE: + * https://code.google.com/p/jbzip2/ + +This product contains a modified portion of 'libdivsufsort', a C API library to construct +the suffix array and the Burrows-Wheeler transformed string for any input string of +a constant-size alphabet written by Yuta Mori. It can be obtained at: + + * LICENSE: + * license/LICENSE.libdivsufsort.txt (MIT License) + * HOMEPAGE: + * https://github.com/y-256/libdivsufsort + +This product contains a modified portion of Nitsan Wakart's 'JCTools', Java Concurrency Tools for the JVM, + which can be obtained at: + + * LICENSE: + * license/LICENSE.jctools.txt (ASL2 License) + * HOMEPAGE: + * https://github.com/JCTools/JCTools + +This product optionally depends on 'JZlib', a re-implementation of zlib in +pure Java, which can be obtained at: + + * LICENSE: + * license/LICENSE.jzlib.txt (BSD style License) + * HOMEPAGE: + * http://www.jcraft.com/jzlib/ + +This product optionally depends on 'Compress-LZF', a Java library for encoding and +decoding data in LZF format, written by Tatu Saloranta. It can be obtained at: + + * LICENSE: + * license/LICENSE.compress-lzf.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/ning/compress + +This product optionally depends on 'lz4', a LZ4 Java compression +and decompression library written by Adrien Grand. It can be obtained at: + + * LICENSE: + * license/LICENSE.lz4.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/jpountz/lz4-java + +This product optionally depends on 'lzma-java', a LZMA Java compression +and decompression library, which can be obtained at: + + * LICENSE: + * license/LICENSE.lzma-java.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/jponge/lzma-java + +This product optionally depends on 'zstd-jni', a zstd-jni Java compression +and decompression library, which can be obtained at: + + * LICENSE: + * license/LICENSE.zstd-jni.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/luben/zstd-jni + +This product contains a modified portion of 'jfastlz', a Java port of FastLZ compression +and decompression library written by William Kinney. It can be obtained at: + + * LICENSE: + * license/LICENSE.jfastlz.txt (MIT License) + * HOMEPAGE: + * https://code.google.com/p/jfastlz/ + +This product contains a modified portion of and optionally depends on 'Protocol Buffers', Google's data +interchange format, which can be obtained at: + + * LICENSE: + * license/LICENSE.protobuf.txt (New BSD License) + * HOMEPAGE: + * https://github.com/google/protobuf + +This product optionally depends on 'Bouncy Castle Crypto APIs' to generate +a temporary self-signed X.509 certificate when the JVM does not provide the +equivalent functionality. It can be obtained at: + + * LICENSE: + * license/LICENSE.bouncycastle.txt (MIT License) + * HOMEPAGE: + * https://www.bouncycastle.org/ + +This product optionally depends on 'Snappy', a compression library produced +by Google Inc, which can be obtained at: + + * LICENSE: + * license/LICENSE.snappy.txt (New BSD License) + * HOMEPAGE: + * https://github.com/google/snappy + +This product optionally depends on 'JBoss Marshalling', an alternative Java +serialization API, which can be obtained at: + + * LICENSE: + * license/LICENSE.jboss-marshalling.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/jboss-remoting/jboss-marshalling + +This product optionally depends on 'Caliper', Google's micro- +benchmarking framework, which can be obtained at: + + * LICENSE: + * license/LICENSE.caliper.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/google/caliper + +This product optionally depends on 'Apache Commons Logging', a logging +framework, which can be obtained at: + + * LICENSE: + * license/LICENSE.commons-logging.txt (Apache License 2.0) + * HOMEPAGE: + * https://commons.apache.org/logging/ + +This product optionally depends on 'Apache Log4J', a logging framework, which +can be obtained at: + + * LICENSE: + * license/LICENSE.log4j.txt (Apache License 2.0) + * HOMEPAGE: + * https://logging.apache.org/log4j/ + +This product optionally depends on 'Aalto XML', an ultra-high performance +non-blocking XML processor, which can be obtained at: + + * LICENSE: + * license/LICENSE.aalto-xml.txt (Apache License 2.0) + * HOMEPAGE: + * https://wiki.fasterxml.com/AaltoHome + +This product contains a modified version of 'HPACK', a Java implementation of +the HTTP/2 HPACK algorithm written by Twitter. It can be obtained at: + + * LICENSE: + * license/LICENSE.hpack.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/twitter/hpack + +This product contains a modified version of 'HPACK', a Java implementation of +the HTTP/2 HPACK algorithm written by Cory Benfield. It can be obtained at: + + * LICENSE: + * license/LICENSE.hyper-hpack.txt (MIT License) + * HOMEPAGE: + * https://github.com/python-hyper/hpack/ + +This product contains a modified version of 'HPACK', a Java implementation of +the HTTP/2 HPACK algorithm written by Tatsuhiro Tsujikawa. It can be obtained at: + + * LICENSE: + * license/LICENSE.nghttp2-hpack.txt (MIT License) + * HOMEPAGE: + * https://github.com/nghttp2/nghttp2/ + +This product contains a modified portion of 'Apache Commons Lang', a Java library +provides utilities for the java.lang API, which can be obtained at: + + * LICENSE: + * license/LICENSE.commons-lang.txt (Apache License 2.0) + * HOMEPAGE: + * https://commons.apache.org/proper/commons-lang/ + + +This product contains the Maven wrapper scripts from 'Maven Wrapper', that provides an easy way to ensure a user has everything necessary to run the Maven build. + + * LICENSE: + * license/LICENSE.mvn-wrapper.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/takari/maven-wrapper + +This product contains the dnsinfo.h header file, that provides a way to retrieve the system DNS configuration on MacOS. +This private header is also used by Apple's open source + mDNSResponder (https://opensource.apple.com/tarballs/mDNSResponder/). + + * LICENSE: + * license/LICENSE.dnsinfo.txt (Apple Public Source License 2.0) + * HOMEPAGE: + * https://www.opensource.apple.com/source/configd/configd-453.19/dnsinfo/dnsinfo.h + +This product optionally depends on 'Brotli4j', Brotli compression and +decompression for Java., which can be obtained at: + + * LICENSE: + * license/LICENSE.brotli4j.txt (Apache License 2.0) + * HOMEPAGE: + * https://github.com/hyperxpro/Brotli4j + +=============================================================================== + +Apache RocketMQ NOTICE + +=============================================================================== +Apache RocketMQ +Copyright 2016-2022 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Prometheus client_java NOTICE + +=============================================================================== +Prometheus instrumentation library for JVM applications +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +Boxever Ltd. (http://www.boxever.com/). + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +This product includes software developed as part of the +Ocelli project by Netflix Inc. (https://github.com/Netflix/ocelli/). + +=============================================================================== + diff --git a/tools/third-party-licenses/licenses/go/LICENSE-cloud.google.com-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-cloud.google.com-go.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-cloud.google.com-go.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-BurntSushi-toml.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-BurntSushi-toml.txt new file mode 100644 index 0000000000..01b5743200 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-BurntSushi-toml.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 TOML authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-OneOfOne-xxhash.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-OneOfOne-xxhash.txt new file mode 100644 index 0000000000..e64dffa0a9 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-OneOfOne-xxhash.txt @@ -0,0 +1,187 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-antihax-optional.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-antihax-optional.txt new file mode 100644 index 0000000000..6a2c64ab1f --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-antihax-optional.txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright (c) 2016 Adam Hintz + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-census-instrumentation-opencensus-proto.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-census-instrumentation-opencensus-proto.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-census-instrumentation-opencensus-proto.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-cespare-xxhash-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cespare-xxhash-v2.txt new file mode 100644 index 0000000000..10222e14e2 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cespare-xxhash-v2.txt @@ -0,0 +1,22 @@ +Copyright (c) 2016 Caleb Spare + +MIT License + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-cespare-xxhash.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cespare-xxhash.txt new file mode 100644 index 0000000000..10222e14e2 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cespare-xxhash.txt @@ -0,0 +1,22 @@ +Copyright (c) 2016 Caleb Spare + +MIT License + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-client9-misspell.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-client9-misspell.txt new file mode 100644 index 0000000000..bfcfcd3013 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-client9-misspell.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2017 Nick Galbreath + +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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-cloudevents-sdk-go-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cloudevents-sdk-go-v2.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cloudevents-sdk-go-v2.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-udpa-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-udpa-go.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-udpa-go.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-xds-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-xds-go.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-xds-go.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-creack-pty.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-creack-pty.txt new file mode 100644 index 0000000000..6b761042bf --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-creack-pty.txt @@ -0,0 +1,23 @@ +Copyright (c) 2011 Keith Rarick + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-davecgh-go-spew.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-davecgh-go-spew.txt new file mode 100644 index 0000000000..7304bdf8cb --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-davecgh-go-spew.txt @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2012-2016 Dave Collins + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-deckarep-golang-set.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-deckarep-golang-set.txt new file mode 100644 index 0000000000..efd4827e21 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-deckarep-golang-set.txt @@ -0,0 +1,22 @@ +Open Source Initiative OSI - The MIT License (MIT):Licensing + +The MIT License (MIT) +Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-go-control-plane.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-go-control-plane.txt new file mode 100644 index 0000000000..9c8f3ea087 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-go-control-plane.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-protoc-gen-validate.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-protoc-gen-validate.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-protoc-gen-validate.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-ghodss-yaml.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-ghodss-yaml.txt new file mode 100644 index 0000000000..e137618b0f --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-ghodss-yaml.txt @@ -0,0 +1,50 @@ +The MIT License (MIT) + +Copyright (c) 2014 Sam Ghods + +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. + + +Copyright (c) 2012 The Go Authors. 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-glog.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-glog.txt new file mode 100644 index 0000000000..8405e89a0b --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-glog.txt @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-mock.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-mock.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-mock.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-protobuf.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-protobuf.txt new file mode 100644 index 0000000000..8e63345bc2 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-protobuf.txt @@ -0,0 +1,27 @@ +Copyright 2010 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-go-cmp.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-go-cmp.txt new file mode 100644 index 0000000000..d9b732cfd3 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-go-cmp.txt @@ -0,0 +1,27 @@ +Copyright (c) 2017 The Go Authors. 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-gofuzz.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-gofuzz.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-gofuzz.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-uuid.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-uuid.txt new file mode 100644 index 0000000000..0c2c410a76 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-uuid.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009,2014 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-grpc-ecosystem-grpc-gateway.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-grpc-ecosystem-grpc-gateway.txt new file mode 100644 index 0000000000..6e59e318a1 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-grpc-ecosystem-grpc-gateway.txt @@ -0,0 +1,27 @@ +Copyright (c) 2015, Gengo, 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 Gengo, 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-json-iterator-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-json-iterator-go.txt new file mode 100644 index 0000000000..c7684dea88 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-json-iterator-go.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 json-iterator + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-pty.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-pty.txt new file mode 100644 index 0000000000..35934dbf5e --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-pty.txt @@ -0,0 +1,23 @@ +Copyright (c) 2019 Keith Rarick + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-text.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-text.txt new file mode 100644 index 0000000000..2e9e336a3f --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-text.txt @@ -0,0 +1,19 @@ +Copyright 2012 Keith Rarick + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-concurrent.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-concurrent.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-concurrent.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-reflect2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-reflect2.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-reflect2.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-niemeyer-pretty.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-niemeyer-pretty.txt new file mode 100644 index 0000000000..2e9e336a3f --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-niemeyer-pretty.txt @@ -0,0 +1,19 @@ +Copyright 2012 Keith Rarick + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-panjf2000-ants.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-panjf2000-ants.txt new file mode 100644 index 0000000000..e257a9ebd6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-panjf2000-ants.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Andy Pan + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-pkg-errors.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-pkg-errors.txt new file mode 100644 index 0000000000..1906e68097 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-pkg-errors.txt @@ -0,0 +1,23 @@ +Copyright (c) 2015, Dave Cheney +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. + +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 HOLDER 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-pmezard-go-difflib.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-pmezard-go-difflib.txt new file mode 100644 index 0000000000..485be13c67 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-pmezard-go-difflib.txt @@ -0,0 +1,27 @@ +Copyright (c) 2013, Patrick Mezard +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. + The names of its contributors may not 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 +HOLDER 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-client_model.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-client_model.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-client_model.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-rogpeppe-fastuuid.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-rogpeppe-fastuuid.txt new file mode 100644 index 0000000000..f84b5232e7 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-rogpeppe-fastuuid.txt @@ -0,0 +1,26 @@ +Copyright © 2014, Roger Peppe +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 this project 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-sony-sonyflake.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-sony-sonyflake.txt new file mode 100644 index 0000000000..049a827f3f --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-sony-sonyflake.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright 2015 Sony Corporation + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-spaolacci-murmur3.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-spaolacci-murmur3.txt new file mode 100644 index 0000000000..8eeb61967a --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-spaolacci-murmur3.txt @@ -0,0 +1,24 @@ +Copyright 2013, Sébastien Paolacci. +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 the library 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 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-objx.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-objx.txt new file mode 100644 index 0000000000..5b30a3704f --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-objx.txt @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2014 Stretchr, Inc. +Copyright (c) 2017-2018 objx contributors + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-testify.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-testify.txt new file mode 100644 index 0000000000..0be77a0bef --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-testify.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors. + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-valyala-bytebufferpool.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-valyala-bytebufferpool.txt new file mode 100644 index 0000000000..8d25e9a147 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-github.com-valyala-bytebufferpool.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Aliaksandr Valialkin, VertaMedia + +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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-go.opentelemetry.io-proto-otlp.txt b/tools/third-party-licenses/licenses/go/LICENSE-go.opentelemetry.io-proto-otlp.txt new file mode 100644 index 0000000000..30f8920b6a --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-go.opentelemetry.io-proto-otlp.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-atomic.txt b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-atomic.txt new file mode 100644 index 0000000000..721b703b60 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-atomic.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 Uber Technologies, Inc. + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-multierr.txt b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-multierr.txt new file mode 100644 index 0000000000..5bfe7bb6d9 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-multierr.txt @@ -0,0 +1,19 @@ +Copyright (c) 2017-2021 Uber Technologies, Inc. + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-zap.txt b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-zap.txt new file mode 100644 index 0000000000..2cf1638263 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-zap.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016-2017 Uber Technologies, Inc. + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-crypto.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-crypto.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-crypto.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-exp.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-exp.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-exp.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-lint.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-lint.txt new file mode 100644 index 0000000000..65d761bc9f --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-lint.txt @@ -0,0 +1,27 @@ +Copyright (c) 2013 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-net.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-net.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-net.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-oauth2.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-oauth2.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-oauth2.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sync.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sync.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sync.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sys.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sys.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sys.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-text.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-text.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-text.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-tools.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-tools.txt new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-tools.txt @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-xerrors.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-xerrors.txt new file mode 100644 index 0000000000..e4a47e17f1 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-xerrors.txt @@ -0,0 +1,27 @@ +Copyright (c) 2019 The Go Authors. 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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-appengine.txt b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-appengine.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-appengine.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-genproto.txt b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-genproto.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-genproto.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-grpc.txt b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-grpc.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-grpc.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-protobuf.txt b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-protobuf.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-protobuf.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-check.v1.txt b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-check.v1.txt new file mode 100644 index 0000000000..eea77e192a --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-check.v1.txt @@ -0,0 +1,25 @@ +Gocheck - A rich testing framework for Go + +Copyright (c) 2010-2013 Gustavo Niemeyer + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. 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. + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v2.txt new file mode 100644 index 0000000000..9c8f3ea087 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v2.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v3.txt b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v3.txt new file mode 100644 index 0000000000..ce5fc85d7b --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v3.txt @@ -0,0 +1,50 @@ + +This project is covered by two different licenses: MIT and Apache. + +#### MIT License #### + +The following files were ported to Go from C files of libyaml, and thus +are still covered by their original MIT license, with the additional +copyright staring in 2011 when the project was ported over: + + apic.go emitterc.go parserc.go readerc.go scannerc.go + writerc.go yamlh.go yamlprivateh.go + +Copyright (c) 2006-2010 Kirill Simonov +Copyright (c) 2006-2011 Kirill Simonov + +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. + +### Apache License ### + +All the remaining project files are covered by the Apache license: + +Copyright (c) 2011-2019 Canonical Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-honnef.co-go-tools.txt b/tools/third-party-licenses/licenses/go/LICENSE-honnef.co-go-tools.txt new file mode 100644 index 0000000000..0dd5c21067 --- /dev/null +++ b/tools/third-party-licenses/licenses/go/LICENSE-honnef.co-go-tools.txt @@ -0,0 +1,20 @@ +Copyright (c) 2016 Dominik Honnef + +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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-assertj-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-assertj-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-assertj-core.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-checker-qual.txt b/tools/third-party-licenses/licenses/java/LICENSE-checker-qual.txt new file mode 100644 index 0000000000..f490f98ba6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-checker-qual.txt @@ -0,0 +1,413 @@ +The Checker Framework +Copyright 2004-present by the Checker Framework developers + + +Most of the Checker Framework is licensed under the GNU General Public +License, version 2 (GPL2), with the classpath exception. The text of this +license appears below. This is the same license used for OpenJDK. + +A few parts of the Checker Framework have more permissive licenses. + + * The annotations are licensed under the MIT License. (The text of this + license appears below.) More specifically, all the parts of the Checker + Framework that you might want to include with your own program use the + MIT License. This is the checker-qual.jar file and all the files that + appear in it: every file in a qual/ directory, plus utility files such + as NullnessUtil.java, RegexUtil.java, SignednessUtil.java, etc. + In addition, the cleanroom implementations of third-party annotations, + which the Checker Framework recognizes as aliases for its own + annotations, are licensed under the MIT License. + +Some external libraries that are included with the Checker Framework have +different licenses. + + * javaparser is dual licensed under the LGPL or the Apache license -- you + may use it under whichever one you want. (The javaparser source code + contains a file with the text of the GPL, but it is not clear why, since + javaparser does not use the GPL.) See file stubparser/LICENSE + and the source code of all its files. + + * JUnit is licensed under the Common Public License v1.0 (see + http://www.junit.org/license), with parts (Hamcrest) licensed under the + BSD License (see http://hamcrest.org/JavaHamcrest/). + + * Libraries in plume-lib (https://github.com/plume-lib/) are licensed + under the MIT License. + +The Checker Framework includes annotations for the JDK in directory +checker/jdk/, and for some other libraries. Each annotated library uses +the same license as the unannotated version of the library. + +=========================================================================== + +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must be licensed for +everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands interactively when run, + you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms +of this License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above + on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code +distributed need not include anything that is normally distributed (in either +source or binary form) with the major components (compiler, kernel, and so on) +of the operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or +any work based on the Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by +third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software Foundation. +If the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER +OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes + with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free + software, and you are welcome to redistribute it under certain conditions; + type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL + +Certain source files distributed by Oracle America and/or its affiliates are +subject to the following clarification and special exception to the GPL, but +only where Oracle has expressly included in the particular source file's header +the words "Oracle designates this particular file as subject to the "Classpath" +exception as provided by Oracle in the LICENSE file that accompanied this code." + + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. + +=========================================================================== + +MIT License: + +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. + +=========================================================================== \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-api.txt new file mode 100644 index 0000000000..1a7891acd6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-api.txt @@ -0,0 +1,203 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2018-Present The CloudEvents Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-core.txt new file mode 100644 index 0000000000..1a7891acd6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-core.txt @@ -0,0 +1,203 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2018-Present The CloudEvents Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-json-jackson.txt b/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-json-jackson.txt new file mode 100644 index 0000000000..1a7891acd6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-cloudevents-json-jackson.txt @@ -0,0 +1,203 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2018-Present The CloudEvents Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-beanutils.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-beanutils.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-beanutils.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-cli.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-cli.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-cli.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-codec.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-codec.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-codec.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-collections.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-collections.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-collections.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-collections4.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-collections4.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-collections4.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-digester.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-digester.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-digester.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-lang3.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-lang3.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-lang3.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-logging.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-logging.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-logging.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-text.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-text.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-text.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-commons-validator.txt b/tools/third-party-licenses/licenses/java/LICENSE-commons-validator.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-commons-validator.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-consul-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-consul-api.txt new file mode 100644 index 0000000000..5a5a8ce54c --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-consul-api.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-disruptor.txt b/tools/third-party-licenses/licenses/java/LICENSE-disruptor.txt new file mode 100644 index 0000000000..50086f8b44 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-disruptor.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-dledger.txt b/tools/third-party-licenses/licenses/java/LICENSE-dledger.txt new file mode 100644 index 0000000000..b90520c005 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-dledger.txt @@ -0,0 +1,203 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (properties) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2017-2020 the original author or authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-error_prone_annotations.txt b/tools/third-party-licenses/licenses/java/LICENSE-error_prone_annotations.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-error_prone_annotations.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-failureaccess.txt b/tools/third-party-licenses/licenses/java/LICENSE-failureaccess.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-failureaccess.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-fastjson.txt b/tools/third-party-licenses/licenses/java/LICENSE-fastjson.txt new file mode 100644 index 0000000000..59f9c59414 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-fastjson.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 1999-2019 Alibaba Group Holding Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-grpc-context.txt b/tools/third-party-licenses/licenses/java/LICENSE-grpc-context.txt new file mode 100644 index 0000000000..cf3c829a19 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-grpc-context.txt @@ -0,0 +1,242 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------- + +BSD 3-Clause License + +Copyright 2016, Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 HOLDER 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. + +----------------------------------------------------------- + +Mozilla Public License, v. 2.0 + +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can +obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-grpc-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-grpc-core.txt new file mode 100644 index 0000000000..cf3c829a19 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-grpc-core.txt @@ -0,0 +1,242 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------- + +BSD 3-Clause License + +Copyright 2016, Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 HOLDER 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. + +----------------------------------------------------------- + +Mozilla Public License, v. 2.0 + +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can +obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-grpc-netty-shaded.txt b/tools/third-party-licenses/licenses/java/LICENSE-grpc-netty-shaded.txt new file mode 100644 index 0000000000..cf3c829a19 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-grpc-netty-shaded.txt @@ -0,0 +1,242 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------- + +BSD 3-Clause License + +Copyright 2016, Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 HOLDER 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. + +----------------------------------------------------------- + +Mozilla Public License, v. 2.0 + +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can +obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-grpc-netty.txt b/tools/third-party-licenses/licenses/java/LICENSE-grpc-netty.txt new file mode 100644 index 0000000000..cf3c829a19 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-grpc-netty.txt @@ -0,0 +1,242 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------- + +BSD 3-Clause License + +Copyright 2016, Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 HOLDER 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. + +----------------------------------------------------------- + +Mozilla Public License, v. 2.0 + +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can +obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-grpc-protobuf-lite.txt b/tools/third-party-licenses/licenses/java/LICENSE-grpc-protobuf-lite.txt new file mode 100644 index 0000000000..cf3c829a19 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-grpc-protobuf-lite.txt @@ -0,0 +1,242 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------- + +BSD 3-Clause License + +Copyright 2016, Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 HOLDER 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. + +----------------------------------------------------------- + +Mozilla Public License, v. 2.0 + +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can +obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-grpc-protobuf.txt b/tools/third-party-licenses/licenses/java/LICENSE-grpc-protobuf.txt new file mode 100644 index 0000000000..cf3c829a19 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-grpc-protobuf.txt @@ -0,0 +1,242 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------- + +BSD 3-Clause License + +Copyright 2016, Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 HOLDER 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. + +----------------------------------------------------------- + +Mozilla Public License, v. 2.0 + +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can +obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-grpc-stub.txt b/tools/third-party-licenses/licenses/java/LICENSE-grpc-stub.txt new file mode 100644 index 0000000000..cf3c829a19 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-grpc-stub.txt @@ -0,0 +1,242 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------------------------------- + +BSD 3-Clause License + +Copyright 2016, Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder 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 HOLDER 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. + +----------------------------------------------------------- + +Mozilla Public License, v. 2.0 + +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can +obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-gson.txt b/tools/third-party-licenses/licenses/java/LICENSE-gson.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-gson.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-guava.txt b/tools/third-party-licenses/licenses/java/LICENSE-guava.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-guava.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-hamcrest-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-hamcrest-core.txt new file mode 100644 index 0000000000..0bf62645cf --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-hamcrest-core.txt @@ -0,0 +1,27 @@ +BSD License + +Copyright (c) 2000-2015 www.hamcrest.org +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 Hamcrest 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-httpasyncclient.txt b/tools/third-party-licenses/licenses/java/LICENSE-httpasyncclient.txt new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-httpasyncclient.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-httpclient.txt b/tools/third-party-licenses/licenses/java/LICENSE-httpclient.txt new file mode 100644 index 0000000000..437923f350 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-httpclient.txt @@ -0,0 +1,558 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + +========================================================================= + +This project includes Public Suffix List copied from + +licensed under the terms of the Mozilla Public License, v. 2.0 + +Full license text: + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-httpcore-nio.txt b/tools/third-party-licenses/licenses/java/LICENSE-httpcore-nio.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-httpcore-nio.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-httpcore.txt b/tools/third-party-licenses/licenses/java/LICENSE-httpcore.txt new file mode 100644 index 0000000000..4947287f7b --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-httpcore.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-ipaddress.txt b/tools/third-party-licenses/licenses/java/LICENSE-ipaddress.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-ipaddress.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-j2objc-annotations.txt b/tools/third-party-licenses/licenses/java/LICENSE-j2objc-annotations.txt new file mode 100644 index 0000000000..2b004c3eee --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-j2objc-annotations.txt @@ -0,0 +1,232 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------- +The next section, BSD-3-Clause, applies to the files in: +jre_emul/android/platform/libcore/ojluni/src/main/java/java/time +-------------------------------------------------------------------------------- +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 JSR-310 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jackson-annotations.txt b/tools/third-party-licenses/licenses/java/LICENSE-jackson-annotations.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jackson-annotations.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jackson-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-jackson-core.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jackson-core.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jackson-databind.txt b/tools/third-party-licenses/licenses/java/LICENSE-jackson-databind.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jackson-databind.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-javassist.txt b/tools/third-party-licenses/licenses/java/LICENSE-javassist.txt new file mode 100644 index 0000000000..a8d8dfd737 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-javassist.txt @@ -0,0 +1,141 @@ +MOZILLA PUBLIC LICENSE +Version 1.1 +1. Definitions. + +1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. +1.1. ''Contributor'' means each entity that creates or contributes to the creation of Modifications. + +1.2. ''Contributor Version'' means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. + +1.3. ''Covered Code'' means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. + +1.4. ''Electronic Distribution Mechanism'' means a mechanism generally accepted in the software development community for the electronic transfer of data. + +1.5. ''Executable'' means Covered Code in any form other than Source Code. + +1.6. ''Initial Developer'' means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. + +1.7. ''Larger Work'' means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. + +1.8. ''License'' means this document. + +1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + +1.9. ''Modifications'' means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: + +A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. +B. Any new file that contains any part of the Original Code or previous Modifications. + + +1.10. ''Original Code'' means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. +1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + +1.11. ''Source Code'' means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. + +1.12. "You'' (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You'' includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control'' means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. Source Code License. +2.1. The Initial Developer Grant. +The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: +(a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and +(b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). + +(c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. +(d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. + + +2.2. Contributor Grant. +Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license + +(a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and +(b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + +(c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. + +(d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. + + +3. Distribution Obligations. + +3.1. Application of License. +The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. +3.2. Availability of Source Code. +Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. + +3.3. Description of Modifications. +You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. + +3.4. Intellectual Property Matters + +(a) Third Party Claims. +If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL'' which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. +(b) Contributor APIs. +If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. + + + (c) Representations. +Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. + +3.5. Required Notices. +You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + +3.6. Distribution of Executable Versions. +You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + +3.7. Larger Works. +You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. +If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. +5. Application of this License. +This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. +6. Versions of the License. +6.1. New Versions. +Netscape Communications Corporation (''Netscape'') may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. +6.2. Effect of New Versions. +Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. + +6.3. Derivative Works. +If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases ''Mozilla'', ''MOZILLAPL'', ''MOZPL'', ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) + +7. DISCLAIMER OF WARRANTY. +COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +8. TERMINATION. +8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. +8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: + +(a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. + +(b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. + +8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. + +8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +10. U.S. GOVERNMENT END USERS. +The Covered Code is a ''commercial item,'' as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of ''commercial computer software'' and ''commercial computer software documentation,'' as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. +11. MISCELLANEOUS. +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. +12. RESPONSIBILITY FOR CLAIMS. +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. +13. MULTIPLE-LICENSED CODE. +Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the MPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + +The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ +Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF +ANY KIND, either express or implied. See the License for the specific language governing rights and +limitations under the License. + +The Original Code is Javassist. + +The Initial Developer of the Original Code is Shigeru Chiba. Portions created by the Initial Developer are + Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. + +Contributor(s): __Bill Burke, Jason T. Greene______________. + +Alternatively, the contents of this software may be used under the terms of the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), or the Apache License Version 2.0 (the "AL"), in which case the provisions of the LGPL or the AL are applicable instead of those above. If you wish to allow use of your version of this software only under the terms of either the LGPL or the AL, and not to allow others to use your version of this software under the terms of the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the LGPL or the AL. If you do not delete the provisions above, a recipient may use your version of this software under the terms of any one of the MPL, the LGPL or the AL. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-javax.annotation-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-javax.annotation-api.txt new file mode 100644 index 0000000000..68076ad96b --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-javax.annotation-api.txt @@ -0,0 +1,759 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1 + +1. Definitions. + + 1.1. "Contributor" means each individual or entity that creates or + contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Software, prior Modifications used by a Contributor (if any), and + the Modifications made by that particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or (b) + Modifications, or (c) the combination of files containing Original + Software with files containing Modifications, in each case including + portions thereof. + + 1.4. "Executable" means the Covered Software in any form other than + Source Code. + + 1.5. "Initial Developer" means the individual or entity that first + makes Original Software available under this License. + + 1.6. "Larger Work" means a work which combines Covered Software or + portions thereof with code not governed by the terms of this License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means the Source Code and Executable form of + any of the following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original Software + or previous Modifications; + + B. Any new file that contains any part of the Original Software or + previous Modification; or + + C. Any new file that is contributed or otherwise made available + under the terms of this License. + + 1.10. "Original Software" means the Source Code and Executable form + of computer software code that is originally released under this + License. + + 1.11. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.12. "Source Code" means (a) the common form of computer software + code in which modifications are made and (b) associated + documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, + this License. For legal entities, "You" includes any entity which + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, the Initial Developer + hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer, to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Software (or portions thereof), with or without Modifications, + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of + Original Software, to make, have made, use, practice, sell, and + offer for sale, and/or otherwise dispose of the Original Software + (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on + the date Initial Developer first distributes or otherwise makes the + Original Software available to a third party under the terms of this + License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: (1) for code that You delete from the Original Software, or + (2) for infringements caused by: (i) the modification of the + Original Software, or (ii) the combination of the Original Software + with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject + to third party intellectual property claims, each Contributor hereby + grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof), either on an + unmodified basis, with other Modifications, as Covered Software + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling + of Modifications made by that Contributor either alone and/or in + combination with its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, have made, and/or + otherwise dispose of: (1) Modifications made by that Contributor (or + portions thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions of such + combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective + on the date Contributor first distributes or otherwise makes the + Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: (1) for any code that Contributor has deleted from the + Contributor Version; (2) for infringements caused by: (i) third + party modifications of Contributor Version, or (ii) the combination + of Modifications made by that Contributor with other software + (except as part of the Contributor Version) or other devices; or (3) + under Patent Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available + in Executable form must also be made available in Source Code form + and that Source Code form must be distributed only under the terms + of this License. You must include a copy of this License with every + copy of the Source Code form of the Covered Software You distribute + or otherwise make available. You must inform recipients of any such + Covered Software in Executable form as to how they can obtain such + Covered Software in Source Code form in a reasonable manner on or + through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are + governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or You + have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that + identifies You as the Contributor of the Modification. You may not + remove or alter any copyright, patent or trademark notices contained + within the Covered Software, or any notices of licensing or any + descriptive text giving attribution to any Contributor or the + Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in + Source Code form that alters or restricts the applicable version of + this License or the recipients' rights hereunder. You may choose to + offer, and to charge a fee for, warranty, support, indemnity or + liability obligations to one or more recipients of Covered Software. + However, you may do so only on Your own behalf, and not on behalf of + the Initial Developer or any Contributor. You must make it + absolutely clear that any such warranty, support, indemnity or + liability obligation is offered by You alone, and You hereby agree + to indemnify the Initial Developer and every Contributor for any + liability incurred by the Initial Developer or such Contributor as a + result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under + the terms of this License or under the terms of a license of Your + choice, which may contain terms different from this License, + provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to + limit or alter the recipient's rights in the Source Code form from + the rights set forth in this License. If You distribute the Covered + Software in Executable form under a different license, You must make + it absolutely clear that any terms which differ from this License + are offered by You alone, not by the Initial Developer or + Contributor. You hereby agree to indemnify the Initial Developer and + every Contributor for any liability incurred by the Initial + Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with + other code not governed by the terms of this License and distribute + the Larger Work as a single product. In such a case, You must make + sure the requirements of this License are fulfilled for the Covered + Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or + new versions of this License from time to time. Each version will be + given a distinguishing version number. Except as provided in Section + 4.3, no one other than the license steward has the right to modify + this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the + Covered Software available under the terms of the version of the + License under which You originally received the Covered Software. If + the Initial Developer includes a notice in the Original Software + prohibiting it from being distributed or otherwise made available + under any subsequent version of the License, You must distribute and + make the Covered Software available under the terms of the version + of the License under which You originally received the Covered + Software. Otherwise, You may also choose to use, distribute or + otherwise make the Covered Software available under the terms of any + subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new + license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license and + remove any references to the name of the license steward (except to + note that the license differs from this License); and (b) otherwise + make it clear that the license contains terms which differ from this + License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE + IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR + NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF + THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE + DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, + REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS + AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond the + termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or a + Contributor (the Initial Developer or Contributor against whom You + assert such claim is referred to as "Participant") alleging that the + Participant Software (meaning the Contributor Version where the + Participant is a Contributor or the Original Software where the + Participant is the Initial Developer) directly or indirectly + infringes any patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial Developer (if the + Initial Developer is not the Participant) and all Contributors under + Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice + from Participant terminate prospectively and automatically at the + expiration of such 60 day notice period, unless if within such 60 + day period You withdraw Your claim with respect to the Participant + Software against such Participant either unilaterally or pursuant to + a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant + alleging that the Participant Software directly or indirectly + infringes any patent where such claim is resolved (such as by + license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, + all end user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE + TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER + FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR + LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE + POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT + APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH + PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH + LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR + LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION + AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is defined + in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" (as that term is defined at 48 C.F.R. § + 252.227-7014(a)(1)) and "commercial computer software documentation" + as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent + with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 + (June 1995), all U.S. Government End Users acquire Covered Software + with only those rights set forth herein. This U.S. Government Rights + clause is in lieu of, and supersedes, any other FAR, DFAR, or other + clause or provision that addresses Government rights in computer + software under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + the law of the jurisdiction specified in a notice contained within + the Original Software (except to the extent applicable law, if any, + provides otherwise), excluding such jurisdiction's conflict-of-law + provisions. Any litigation relating to this License shall be subject + to the jurisdiction of the courts located in the jurisdiction and + venue specified in a notice contained within the Original Software, + with the losing party responsible for costs, including, without + limitation, court costs and reasonable attorneys' fees and expenses. + The application of the United Nations Convention on Contracts for + the International Sale of Goods is expressly excluded. Any law or + regulation which provides that the language of a contract shall be + construed against the drafter shall not apply to this License. You + agree that You alone are responsible for compliance with the United + States export administration regulations (and the export control + laws and regulation of any other countries) when You use, distribute + or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +------------------------------------------------------------------------ + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION +LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the +State of California (excluding conflict-of-law provisions). Any +litigation relating to this License shall be subject to the jurisdiction +of the Federal Courts of the Northern District of California and the +state courts of the State of California, with venue lying in Santa Clara +County, California. + + + + The GNU General Public License (GPL) Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor +Boston, MA 02110-1335 +USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to +share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free software--to +make sure the software is free for all its users. This General Public +License applies to most of the Free Software Foundation's software and +to any other program whose authors commit to using it. (Some other Free +Software Foundation software is covered by the GNU Library General +Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. +Our General Public Licenses are designed to make sure that you have the +freedom to distribute copies of free software (and charge for this +service if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone +to deny you these rights or to ask you to surrender the rights. These +restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis +or for a fee, you must give the recipients all the rights that you have. +You must make sure that they, too, receive or can get the source code. +And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software patents. +We wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program +proprietary. To prevent this, we have made it clear that any patent must +be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed under +the terms of this General Public License. The "Program", below, refers +to any such program or work, and a "work based on the Program" means +either the Program or any derivative work under copyright law: that is +to say, a work containing the Program or a portion of it, either +verbatim or with modifications and/or translated into another language. +(Hereinafter, translation is included without limitation in the term +"modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of running +the Program is not restricted, and the output from the Program is +covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, provided +that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any part + thereof, to be licensed as a whole at no charge to all third parties + under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this License. + (Exception: if the Program itself is interactive but does not + normally print such an announcement, your work based on the Program + is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, and +can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based on +the Program, the distribution of the whole must be on the terms of this +License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of a +storage or distribution medium does not bring the other work under the +scope of this License. + +3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your cost + of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed + only for noncommercial distribution and only if you received the + program in object code or executable form with such an offer, in + accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source code +means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies the +executable. + +If distribution of executable or object code is made by offering access +to copy from a designated place, then offering equivalent access to copy +the source code from the same place counts as distribution of the source +code, even though third parties are not compelled to copy the source +along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will +not have their licenses terminated so long as such parties remain in +full compliance. + +5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and all +its terms and conditions for copying, distributing or modifying the +Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further restrictions +on the recipients' exercise of the rights granted herein. You are not +responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot distribute +so as to satisfy simultaneously your obligations under this License and +any other pertinent obligations, then as a consequence you may not +distribute the Program at all. For example, if a patent license would +not permit royalty-free redistribution of the Program by all those who +receive copies directly or indirectly through you, then the only way you +could satisfy both it and this License would be to refrain entirely from +distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up to +the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be +a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the +limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a version +number of this License, you may choose any version ever published by the +Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH +YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR +DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM +(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR +OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type + `show w'. This is free software, and you are welcome to redistribute + it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the commands +you use may be called something other than `show w' and `show c'; they +could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (which makes passes at compilers) written by + James Hacker. + + signature of Ty Coon, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications +with the library. If this is what you want to do, use the GNU Library +General Public License instead of this License. + +# + +Certain source files distributed by Oracle America, Inc. and/or its +affiliates are subject to the following clarification and special +exception to the GPLv2, based on the GNU Project exception for its +Classpath libraries, known as the GNU Classpath Exception, but only +where Oracle has expressly included in the particular source file's +header the words "Oracle designates this particular file as subject to +the "Classpath" exception as provided by Oracle in the LICENSE file +that accompanied this code." + +You should also note that Oracle includes multiple, independent +programs in this software package. Some of those programs are provided +under licenses deemed incompatible with the GPLv2 by the Free Software +Foundation and others. For example, the package includes programs +licensed under the Apache License, Version 2.0. Such programs are +licensed to you under their original licenses. + +Oracle facilitates your further distribution of this package by adding +the Classpath Exception to the necessary parts of its GPLv2 code, which +permits you to use that code in combination with other independent +modules not licensed under the GPLv2. However, note that this would +not permit you to commingle code under an incompatible license with +Oracle's GPLv2 licensed code by, for example, cutting and pasting such +code into a file also containing Oracle's GPLv2 licensed code and then +distributing the result. Additionally, if you were to remove the +Classpath Exception from any of the files to which it applies and +distribute the result, you would likely be required to license some or +all of the other code in that distribution under the GPLv2 as well, and +since the GPLv2 is incompatible with the license terms of some items +included in the distribution by Oracle, removing the Classpath +Exception could therefore effectively compromise your ability to +further distribute the package. + +Proceed with caution and we recommend that you obtain the advice of a +lawyer skilled in open source matters before removing the Classpath +Exception or making modifications to this package which may +subsequently be redistributed and/or involve the use of third party +software. + +CLASSPATH EXCEPTION +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License version 2 cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from or +based on this library. If you modify this library, you may extend this +exception to your version of the library, but you are not obligated to +do so. If you do not wish to do so, delete this exception statement +from your version. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jcommander.txt b/tools/third-party-licenses/licenses/java/LICENSE-jcommander.txt new file mode 100644 index 0000000000..477eb7b7ba --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jcommander.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2012, Cedric Beust + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jna.txt b/tools/third-party-licenses/licenses/java/LICENSE-jna.txt new file mode 100644 index 0000000000..b456098518 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jna.txt @@ -0,0 +1,26 @@ +SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1 + +Java Native Access (JNA) is licensed under the LGPL, version 2.1 +or later, or (from version 4.0 onward) the Apache License, +version 2.0. + +You can freely decide which license you want to apply to the project. + +You may obtain a copy of the LGPL License at: + +http://www.gnu.org/licenses/licenses.html + +A copy is also included in the downloadable source code package +containing JNA, in file "LGPL2.1", under the same directory +as this file. + +You may obtain a copy of the Apache License at: + +http://www.apache.org/licenses/ + +A copy is also included in the downloadable source code package +containing JNA, in file "AL2.0", under the same directory +as this file. + +Commercial support may be available, please e-mail +twall[at]users[dot]sf[dot]net. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jsr305.txt b/tools/third-party-licenses/licenses/java/LICENSE-jsr305.txt new file mode 100644 index 0000000000..7fb51fb895 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jsr305.txt @@ -0,0 +1,28 @@ +Copyright (c) 2007-2009, JSR305 expert group +All rights reserved. + +https://opensource.org/licenses/BSD-3-Clause + +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 the JSR305 expert group 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-junit.txt b/tools/third-party-licenses/licenses/java/LICENSE-junit.txt new file mode 100644 index 0000000000..7b5e981e7c --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-junit.txt @@ -0,0 +1,213 @@ +JUnit + +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' from a +Contributor if it was added to the Program by such Contributor itself or anyone +acting on such Contributor's behalf. Contributions do not include additions to +the Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) are +not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free copyright license to +reproduce, prepare derivative works of, publicly display, publicly perform, +distribute and sublicense the Contribution of such Contributor, if any, and +such derivative works, in source code and object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free patent license under +Licensed Patents to make, use, sell, offer to sell, import and otherwise +transfer the Contribution of such Contributor, if any, in source code and +object code form. This patent license shall apply to the combination of the +Contribution and the Program if, at the time the Contribution is added by the +Contributor, such addition of the Contribution causes such combination to be +covered by the Licensed Patents. The patent license shall not apply to any +other combinations which include the Contribution. No hardware per se is +licensed hereunder. + + c) Recipient understands that although each Contributor grants the +licenses to its Contributions set forth herein, no assurances are provided by +any Contributor that the Program does not infringe the patent or other +intellectual property rights of any other entity. Each Contributor disclaims +any liability to Recipient for claims brought by any other entity based on +infringement of intellectual property rights or otherwise. As a condition to +exercising the rights and licenses granted hereunder, each Recipient hereby +assumes sole responsibility to secure any other intellectual property rights +needed, if any. For example, if a third party patent license is required to +allow Recipient to distribute the Program, it is Recipient's responsibility to +acquire that license before distributing the Program. + + d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright license +set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under +its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title +and non-infringement, and implied warranties or conditions of merchantability +and fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are +offered by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such +Contributor, and informs licensees how to obtain it in a reasonable manner on +or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the +Program. + +Contributors may not remove or alter any copyright notices contained within the +Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor +to control, and cooperate with the Commercial Contributor in, the defense and +any related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using +and distributing the Program and assumes all risks associated with its exercise +of rights under this Agreement, including but not limited to the risks and +costs of program errors, compliance with applicable laws, damage to or loss of +data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software or +hardware) infringes such Recipient's patent(s), then such Recipient's rights +granted under Section 2(b) shall terminate as of the date such litigation is +filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue +and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each new version +of the Agreement will be given a distinguishing version number. The Program +(including Contributions) may always be distributed subject to the version of +the Agreement under which it was received. In addition, after a new version of +the Agreement is published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to +the intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial +in any resulting litigation. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-listenablefuture.txt b/tools/third-party-licenses/licenses/java/LICENSE-listenablefuture.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-listenablefuture.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-log4j-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-log4j-api.txt new file mode 100644 index 0000000000..98a324cf06 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-log4j-api.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 1999-2005 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-log4j-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-log4j-core.txt new file mode 100644 index 0000000000..98a324cf06 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-log4j-core.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 1999-2005 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-log4j-slf4j-impl.txt b/tools/third-party-licenses/licenses/java/LICENSE-log4j-slf4j-impl.txt new file mode 100644 index 0000000000..98a324cf06 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-log4j-slf4j-impl.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 1999-2005 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-logback-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-logback-core.txt new file mode 100644 index 0000000000..8953762a3c --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-logback-core.txt @@ -0,0 +1,14 @@ +Logback LICENSE +--------------- + +Logback: the reliable, generic, fast and flexible logging framework. +Copyright (C) 1999-2015, QOS.ch. All rights reserved. + +This program and the accompanying materials are dual-licensed under +either the terms of the Eclipse Public License v1.0 as published by +the Eclipse Foundation + + or (per the licensee's choosing) + +under the terms of the GNU Lesser General Public License version 2.1 +as published by the Free Software Foundation. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-metrics-annotation.txt b/tools/third-party-licenses/licenses/java/LICENSE-metrics-annotation.txt new file mode 100644 index 0000000000..52823540de --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-metrics-annotation.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2010-2013 Coda Hale and Yammer, Inc., 2014-2020 Dropwizard Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-metrics-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-metrics-core.txt new file mode 100644 index 0000000000..52823540de --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-metrics-core.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2010-2013 Coda Hale and Yammer, Inc., 2014-2020 Dropwizard Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-metrics-healthchecks.txt b/tools/third-party-licenses/licenses/java/LICENSE-metrics-healthchecks.txt new file mode 100644 index 0000000000..52823540de --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-metrics-healthchecks.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2010-2013 Coda Hale and Yammer, Inc., 2014-2020 Dropwizard Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-metrics-json.txt b/tools/third-party-licenses/licenses/java/LICENSE-metrics-json.txt new file mode 100644 index 0000000000..52823540de --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-metrics-json.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2010-2013 Coda Hale and Yammer, Inc., 2014-2020 Dropwizard Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-nacos-client.txt b/tools/third-party-licenses/licenses/java/LICENSE-nacos-client.txt new file mode 100644 index 0000000000..f490f98ba6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-nacos-client.txt @@ -0,0 +1,413 @@ +The Checker Framework +Copyright 2004-present by the Checker Framework developers + + +Most of the Checker Framework is licensed under the GNU General Public +License, version 2 (GPL2), with the classpath exception. The text of this +license appears below. This is the same license used for OpenJDK. + +A few parts of the Checker Framework have more permissive licenses. + + * The annotations are licensed under the MIT License. (The text of this + license appears below.) More specifically, all the parts of the Checker + Framework that you might want to include with your own program use the + MIT License. This is the checker-qual.jar file and all the files that + appear in it: every file in a qual/ directory, plus utility files such + as NullnessUtil.java, RegexUtil.java, SignednessUtil.java, etc. + In addition, the cleanroom implementations of third-party annotations, + which the Checker Framework recognizes as aliases for its own + annotations, are licensed under the MIT License. + +Some external libraries that are included with the Checker Framework have +different licenses. + + * javaparser is dual licensed under the LGPL or the Apache license -- you + may use it under whichever one you want. (The javaparser source code + contains a file with the text of the GPL, but it is not clear why, since + javaparser does not use the GPL.) See file stubparser/LICENSE + and the source code of all its files. + + * JUnit is licensed under the Common Public License v1.0 (see + http://www.junit.org/license), with parts (Hamcrest) licensed under the + BSD License (see http://hamcrest.org/JavaHamcrest/). + + * Libraries in plume-lib (https://github.com/plume-lib/) are licensed + under the MIT License. + +The Checker Framework includes annotations for the JDK in directory +checker/jdk/, and for some other libraries. Each annotated library uses +the same license as the unannotated version of the library. + +=========================================================================== + +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must be licensed for +everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands interactively when run, + you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms +of this License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above + on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code +distributed need not include anything that is normally distributed (in either +source or binary form) with the major components (compiler, kernel, and so on) +of the operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or +any work based on the Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by +third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software Foundation. +If the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER +OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes + with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free + software, and you are welcome to redistribute it under certain conditions; + type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL + +Certain source files distributed by Oracle America and/or its affiliates are +subject to the following clarification and special exception to the GPL, but +only where Oracle has expressly included in the particular source file's header +the words "Oracle designates this particular file as subject to the "Classpath" +exception as provided by Oracle in the LICENSE file that accompanied this code." + + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. + +=========================================================================== + +MIT License: + +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. + +=========================================================================== \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-all.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-all.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-all.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-buffer.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-buffer.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-buffer.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-dns.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-dns.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-dns.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-haproxy.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-haproxy.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-haproxy.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-http.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-http.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-http.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-http2.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-http2.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-http2.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-memcache.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-memcache.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-memcache.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-mqtt.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-mqtt.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-mqtt.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-redis.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-redis.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-redis.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-smtp.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-smtp.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-smtp.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-socks.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-socks.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-socks.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-stomp.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-stomp.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-stomp.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-xml.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-xml.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec-xml.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-codec.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-codec.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-common.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-common.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-common.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-handler-proxy.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-handler-proxy.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-handler-proxy.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-handler.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-handler.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-handler.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns-classes-macos.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns-classes-macos.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns-classes-macos.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns-native-macos.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns-native-macos.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns-native-macos.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver-dns.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-resolver.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-tcnative-boringssl-static.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-tcnative-boringssl-static.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-tcnative-boringssl-static.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-tcnative-classes.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-tcnative-classes.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-tcnative-classes.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-classes-epoll.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-classes-epoll.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-classes-epoll.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-classes-kqueue.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-classes-kqueue.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-classes-kqueue.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-epoll.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-epoll.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-epoll.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-kqueue.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-kqueue.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-kqueue.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-unix-common.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-unix-common.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-native-unix-common.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-rxtx.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-rxtx.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-rxtx.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-sctp.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-sctp.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-sctp.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-udt.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-udt.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport-udt.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-transport.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-transport.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-okhttp.txt b/tools/third-party-licenses/licenses/java/LICENSE-okhttp.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-okhttp.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-okio.txt b/tools/third-party-licenses/licenses/java/LICENSE-okio.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-okio.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opencensus-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-opencensus-api.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opencensus-api.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opencensus-contrib-grpc-metrics.txt b/tools/third-party-licenses/licenses/java/LICENSE-opencensus-contrib-grpc-metrics.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opencensus-contrib-grpc-metrics.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-openmessaging-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-openmessaging-api.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-openmessaging-api.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-api-metrics.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-api-metrics.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-api-metrics.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-api.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-api.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-context.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-context.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-context.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-exporter-prometheus.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-exporter-prometheus.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-exporter-prometheus.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-exporter-zipkin.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-exporter-zipkin.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-exporter-zipkin.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-common.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-common.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-common.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-metrics.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-metrics.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-metrics.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-trace.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-trace.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk-trace.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-sdk.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-semconv.txt b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-semconv.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-opentelemetry-semconv.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-proto-google-common-protos.txt b/tools/third-party-licenses/licenses/java/LICENSE-proto-google-common-protos.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-proto-google-common-protos.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-protobuf-java.txt b/tools/third-party-licenses/licenses/java/LICENSE-protobuf-java.txt new file mode 100644 index 0000000000..c80f6413d1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-protobuf-java.txt @@ -0,0 +1,48 @@ +The 3-Clause BSD License +SPDX short identifier: BSD-3-Clause + +Further resources on the 3-clause BSD license +Note: This license has also been called the "New BSD License" or "Modified BSD License". See also the 2-clause BSD License. + +This license applies to all parts of Protocol Buffers except the following: + + - Atomicops support for generic gcc, located in + src/google/protobuf/stubs/atomicops_internals_generic_gcc.h. + This file is copyrighted by Red Hat Inc. + + - Atomicops support for AIX/POWER, located in + src/google/protobuf/stubs/atomicops_internals_power.h. + This file is copyrighted by Bloomberg Finance LP. + +Copyright 2014, 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. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-reflections.txt b/tools/third-party-licenses/licenses/java/LICENSE-reflections.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-reflections.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-acl.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-acl.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-acl.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-broker.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-broker.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-broker.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-client.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-client.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-client.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-common.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-common.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-common.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-filter.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-filter.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-filter.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-logging.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-logging.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-logging.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-namesrv.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-namesrv.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-namesrv.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-remoting.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-remoting.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-remoting.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-srvutil.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-srvutil.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-srvutil.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-store.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-store.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-store.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-test.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-test.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-test.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-tools.txt b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-tools.txt new file mode 100644 index 0000000000..f49a4e16e6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-rocketmq-tools.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-simpleclient.txt b/tools/third-party-licenses/licenses/java/LICENSE-simpleclient.txt new file mode 100644 index 0000000000..835428fbaa --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-simpleclient.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-simpleclient_common.txt b/tools/third-party-licenses/licenses/java/LICENSE-simpleclient_common.txt new file mode 100644 index 0000000000..835428fbaa --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-simpleclient_common.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-simpleclient_httpserver.txt b/tools/third-party-licenses/licenses/java/LICENSE-simpleclient_httpserver.txt new file mode 100644 index 0000000000..835428fbaa --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-simpleclient_httpserver.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-slf4j-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-slf4j-api.txt new file mode 100644 index 0000000000..744377c437 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-slf4j-api.txt @@ -0,0 +1,21 @@ +Copyright (c) 2004-2017 QOS.ch +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-snakeyam.txt b/tools/third-party-licenses/licenses/java/LICENSE-snakeyam.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-snakeyam.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-snakeyaml.txt b/tools/third-party-licenses/licenses/java/LICENSE-snakeyaml.txt new file mode 100644 index 0000000000..1a7891acd6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-snakeyaml.txt @@ -0,0 +1,203 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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 2018-Present The CloudEvents Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-system-rules.txt b/tools/third-party-licenses/licenses/java/LICENSE-system-rules.txt new file mode 100644 index 0000000000..3a4c72849d --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-system-rules.txt @@ -0,0 +1,213 @@ +Common Public License Version 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and +documentation distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' from a +Contributor if it was added to the Program by such Contributor itself or anyone +acting on such Contributor's behalf. Contributions do not include additions to +the Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) are not +derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free copyright license to +reproduce, prepare derivative works of, publicly display, publicly perform, +distribute and sublicense the Contribution of such Contributor, if any, and such +derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed +Patents to make, use, sell, offer to sell, import and otherwise transfer the +Contribution of such Contributor, if any, in source code and object code form. +This patent license shall apply to the combination of the Contribution and the +Program if, at the time the Contribution is added by the Contributor, such +addition of the Contribution causes such combination to be covered by the +Licensed Patents. The patent license shall not apply to any other combinations +which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses +to its Contributions set forth herein, no assurances are provided by any +Contributor that the Program does not infringe the patent or other intellectual +property rights of any other entity. Each Contributor disclaims any liability to +Recipient for claims brought by any other entity based on infringement of +intellectual property rights or otherwise. As a condition to exercising the +rights and licenses granted hereunder, each Recipient hereby assumes sole +responsibility to secure any other intellectual property rights needed, if any. +For example, if a third party patent license is required to allow Recipient to +distribute the Program, it is Recipient's responsibility to acquire that license +before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright license set +forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its +own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title and +non-infringement, and implied warranties or conditions of merchantability and +fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered +by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such +Contributor, and informs licensees how to obtain it in a reasonable manner on or +through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the +Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor to +control, and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may participate in +any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its exercise of +rights under this Agreement, including but not limited to the risks and costs of +program errors, compliance with applicable laws, damage to or loss of data, +programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with respect to +a patent applicable to software (including a cross-claim or counterclaim in a +lawsuit), then any patent licenses granted by that Contributor to such Recipient +under this Agreement shall terminate as of the date such litigation is filed. In +addition, if Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the Program +itself (excluding combinations of the Program with other software or hardware) +infringes such Recipient's patent(s), then such Recipient's rights granted under +Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue and +survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +IBM is the initial Agreement Steward. IBM may assign the responsibility to serve +as the Agreement Steward to a suitable separate entity. Each new version of the +Agreement will be given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the Agreement +under which it was received. In addition, after a new version of the Agreement +is published, Contributor may elect to distribute the Program (including its +Contributions) under the new version. Except as expressly stated in Sections +2(a) and 2(b) above, Recipient receives no rights or licenses to the +intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-truth.txt b/tools/third-party-licenses/licenses/java/LICENSE-truth.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-truth.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-zipkin-reporter.txt b/tools/third-party-licenses/licenses/java/LICENSE-zipkin-reporter.txt new file mode 100644 index 0000000000..9c8f3ea087 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-zipkin-reporter.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-zipkin-sender-okhttp3.txt b/tools/third-party-licenses/licenses/java/LICENSE-zipkin-sender-okhttp3.txt new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-zipkin-sender-okhttp3.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-zipkin.txt b/tools/third-party-licenses/licenses/java/LICENSE-zipkin.txt new file mode 100644 index 0000000000..0c1111bc79 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-zipkin.txt @@ -0,0 +1,216 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + 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"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +This product contains a modified part of Gson, distributed by Google: + + * License: Apache License v2.0 + * Homepage: https://github.com/google/gson + +This product contains a modified part of Guava, distributed by Google: + + * License: Apache License v2.0 + * Homepage: https://github.com/google/guava + +This product contains a modified part of Okio, distributed by Square: + + * License: Apache License v2.0 + * Homepage: https://github.com/square/okio